aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-04-01 16:50:03 +0200
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2014-04-01 16:51:50 +0200
commit4f1e143c6eac9e1b57b2400bf5b0761a8b072419 (patch)
treef06266246e8264bf56515a279853bd7197573fe2 /pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing
parentdce9a1535236da947d9f866421c4f0b8ae47e527 (diff)
downloadpdf-as-4-4f1e143c6eac9e1b57b2400bf5b0761a8b072419.tar.gz
pdf-as-4-4f1e143c6eac9e1b57b2400bf5b0761a8b072419.tar.bz2
pdf-as-4-4f1e143c6eac9e1b57b2400bf5b0761a8b072419.zip
PDFBOX Table generation incl. QR Code detection and Positioning is done
Diffstat (limited to 'pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing')
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java353
1 files changed, 263 insertions, 90 deletions
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
index 651c2e49..767887b3 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
@@ -29,12 +29,21 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Calendar;
+import java.util.List;
+import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.exceptions.SignatureException;
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageNode;
+import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;
import org.slf4j.Logger;
@@ -45,111 +54,275 @@ import at.gv.egiz.pdfas.common.messages.MessageResolver;
import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
import at.gv.egiz.pdfas.common.utils.StreamUtils;
import at.gv.egiz.pdfas.common.utils.TempFileHelper;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
+import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl;
+import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration;
+import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderFilter;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import at.gv.egiz.pdfas.lib.impl.positioning.Positioning;
import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner;
import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.gv.egiz.pdfas.lib.impl.stamping.StamperFactory;
import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory;
import at.gv.egiz.pdfas.lib.impl.stamping.ValueResolver;
import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PDFAsVisualSignatureProperties;
+import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PdfBoxVisualObject;
import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.table.Table;
-public class PADESPDFBOXSigner implements IPdfSigner {
+public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
- private static final Logger logger = LoggerFactory.getLogger(PADESPDFBOXSigner.class);
+ private static final Logger logger = LoggerFactory
+ .getLogger(PADESPDFBOXSigner.class);
- public void signPDF(PDFObject pdfObject, RequestedSignature requestedSignature,
- PDFASSignatureInterface signer)
- throws PdfAsException {
- String fisTmpFile = null;
-
- TempFileHelper helper = pdfObject.getStatus().getTempFileHelper();
-
- try {
- fisTmpFile = helper.getStaticFilename();
+ public void signPDF(PDFObject pdfObject,
+ RequestedSignature requestedSignature,
+ PDFASSignatureInterface signer) throws PdfAsException {
+ String fisTmpFile = null;
- // write to temporary file
- FileOutputStream fos = new FileOutputStream(new File(fisTmpFile));
- fos.write(pdfObject.getStampedDocument());
+ TempFileHelper helper = pdfObject.getStatus().getTempFileHelper();
+ try {
+ fisTmpFile = helper.getStaticFilename();
- FileInputStream fis = new FileInputStream(new File(fisTmpFile));
+ // write to temporary file
+ FileOutputStream fos = new FileOutputStream(new File(fisTmpFile));
+ fos.write(pdfObject.getOriginalDocument());
- PDDocument doc = PDDocument.load(
- new ByteArrayInputStream(pdfObject.getStampedDocument()));
+ FileInputStream fis = new FileInputStream(new File(fisTmpFile));
- PDSignature signature = new PDSignature();
- signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default filter
- signature.setSubFilter(COSName.getPDFName(signer.getPDFSubFilter()));
+ PDDocument doc = PDDocument.load(new ByteArrayInputStream(pdfObject
+ .getOriginalDocument()));
- SignatureProfileSettings signatureProfileSettings = TableFactory
- .createProfile(requestedSignature.getSignatureProfileID(),
+ PDSignature signature = new PDSignature();
+ signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default
+ // filter
+ signature
+ .setSubFilter(COSName.getPDFName(signer.getPDFSubFilter()));
+
+ SignatureProfileSettings signatureProfileSettings = TableFactory
+ .createProfile(requestedSignature.getSignatureProfileID(),
pdfObject.getStatus().getSettings());
-
- ValueResolver resolver = new ValueResolver();
- String signerName = resolver.resolve("SIG_SUBJECT", signatureProfileSettings.getValue("SIG_SUBJECT"),
- signatureProfileSettings, requestedSignature);
-
- signature.setName(signerName);
- signature.setSignDate(Calendar.getInstance());
- String signerReason = signatureProfileSettings.getSigningReason();
-
- if(signerReason == null) {
- signerReason = "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());
-
- signer.setPDSignature(signature);
- SignatureOptions options = new SignatureOptions();
-
- // FOR DEVELOPING: Call custom visual signature creation
- PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties(
- pdfObject.getStatus().getSettings(), pdfObject);
- properties.buildSignature();
-
- ByteArrayOutputStream sigbos = new ByteArrayOutputStream();
- sigbos.write(StreamUtils.inputStreamToByteArray(properties.getVisibleSignature()));
- sigbos.close();
-
- FileOutputStream fos2 = new FileOutputStream("/tmp/apsig.pdf");
- fos2.write(sigbos.toByteArray());
- fos2.close();
-
- options.setVisualSignature(new ByteArrayInputStream(sigbos.toByteArray()));
-
- doc.addSignature(signature, signer, options);
-
- // pdfbox patched (FIS -> IS)
- doc.saveIncremental(fis, fos);
- fis.close();
- fos.close();
-
- fis = new FileInputStream(new File(fisTmpFile));
-
- // write to resulting output stream
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- bos.write(StreamUtils.inputStreamToByteArray(fis));
- fis.close();
- bos.close();
-
- pdfObject.setSignedDocument(bos.toByteArray());
-
- helper.deleteFile(fisTmpFile);
-
- } catch (IOException e) {
- logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
- throw new PdfAsException("error.pdf.sig.01", e);
- } catch(SignatureException e) {
- logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
- throw new PdfAsException("error.pdf.sig.01", e);
- } catch (COSVisitorException e) {
- logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
- throw new PdfAsException("error.pdf.sig.01", e);
- }
- }
+
+ ValueResolver resolver = new ValueResolver();
+ String signerName = resolver.resolve("SIG_SUBJECT",
+ signatureProfileSettings.getValue("SIG_SUBJECT"),
+ signatureProfileSettings, requestedSignature);
+
+ signature.setName(signerName);
+ signature.setSignDate(Calendar.getInstance());
+ String signerReason = signatureProfileSettings.getSigningReason();
+
+ if (signerReason == null) {
+ signerReason = "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());
+
+ signer.setPDSignature(signature);
+ SignatureOptions options = new SignatureOptions();
+
+ // Is visible Signature
+ if (requestedSignature.isVisual()) {
+ logger.info("Creating visual siganture block");
+
+ SignatureProfileConfiguration signatureProfileConfiguration = pdfObject
+ .getStatus().getSignatureProfileConfiguration(
+ requestedSignature.getSignatureProfileID());
+
+ SignaturePlaceholderData signaturePlaceholderData = PlaceholderFilter
+ .checkPlaceholderSignature(pdfObject.getStatus(),
+ pdfObject.getStatus().getSettings());
+
+ TablePos tablePos = null;
+
+ if (signaturePlaceholderData != null) {
+ // Placeholder found!
+
+ if (signaturePlaceholderData.getProfile() != null) {
+ requestedSignature
+ .setSignatureProfileID(signaturePlaceholderData
+ .getProfile());
+ }
+
+ tablePos = signaturePlaceholderData.getTablePos();
+ }
+
+ if (tablePos == null) {
+ // ================================================================
+ // PositioningStage (visual) -> find position or use fixed
+ // position
+
+ String posString = pdfObject.getStatus().getSignParamter()
+ .getSignaturePosition();
+
+ if (posString == null) {
+ posString = signatureProfileConfiguration
+ .getDefaultPositioning();
+ }
+
+ logger.debug("using Positioning: " + posString);
+
+ if (posString == null) {
+ tablePos = new TablePos();
+ } else {
+ tablePos = new TablePos(posString);
+ }
+ }
+ boolean legacy32Position = signatureProfileConfiguration
+ .getLegacy32Positioning();
+
+ // create Table describtion
+ Table main = TableFactory.createSigTable(
+ signatureProfileSettings, MAIN, pdfObject.getStatus()
+ .getSettings(), requestedSignature);
+
+ IPDFStamper stamper = StamperFactory
+ .createDefaultStamper(pdfObject.getStatus()
+ .getSettings());
+
+ IPDFVisualObject visualObject = stamper.createVisualPDFObject(
+ pdfObject, main);
+
+ PDDocument originalDocument = PDDocument
+ .load(new ByteArrayInputStream(pdfObject.getStatus()
+ .getPdfObject().getOriginalDocument()));
+
+ PositioningInstruction positioningInstruction = Positioning
+ .determineTablePositioning(tablePos, "",
+ originalDocument, visualObject,
+ legacy32Position);
+
+ SignaturePositionImpl position = new SignaturePositionImpl();
+ position.setX(positioningInstruction.getX());
+ position.setY(positioningInstruction.getY());
+ position.setPage(positioningInstruction.getPage());
+ position.setHeight(visualObject.getHeight());
+ position.setWidth(visualObject.getWidth());
+
+ requestedSignature.setSignaturePosition(position);
+
+ PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties(
+ pdfObject.getStatus().getSettings(), pdfObject,
+ (PdfBoxVisualObject) visualObject,
+ positioningInstruction);
+
+ properties.buildSignature();
+
+ ByteArrayOutputStream sigbos = new ByteArrayOutputStream();
+ sigbos.write(StreamUtils.inputStreamToByteArray(properties
+ .getVisibleSignature()));
+ sigbos.close();
+
+ FileOutputStream fos2 = new FileOutputStream("/tmp/apsig.pdf");
+ fos2.write(sigbos.toByteArray());
+ fos2.close();
+
+ if (signaturePlaceholderData != null) {
+ // Placeholder found!
+ // replace placeholder
+ InputStream is = PADESPDFBOXSigner.class
+ .getResourceAsStream("/placeholder/empty.jpg");
+ PDJpeg img = new PDJpeg(doc, is);
+ img.getCOSObject().setNeedToBeUpdate(true);
+
+ PDDocumentCatalog root = doc.getDocumentCatalog();
+ PDPageNode rootPages = root.getPages();
+ List<PDPage> kids = new ArrayList<PDPage>();
+ rootPages.getAllKids(kids);
+ int pageNumber = positioningInstruction.getPage();
+ rootPages.getAllKids(kids);
+ PDPage page = kids.get(pageNumber);
+
+ logger.info("Placeholder name: " + signaturePlaceholderData.getPlaceholderName());
+ COSDictionary xobjectsDictionary = (COSDictionary) page.findResources().getCOSDictionary()
+ .getDictionaryObject(COSName.XOBJECT);
+ xobjectsDictionary.setItem(signaturePlaceholderData.getPlaceholderName(), img);
+ xobjectsDictionary.setNeedToBeUpdate(true);
+ page.findResources().getCOSObject().setNeedToBeUpdate(true);
+ logger.info("Placeholder name: " + signaturePlaceholderData.getPlaceholderName());
+ }
+
+ if (positioningInstruction.isMakeNewPage()) {
+ int last = doc.getNumberOfPages() - 1;
+ PDDocumentCatalog root = doc.getDocumentCatalog();
+ PDPageNode rootPages = root.getPages();
+ List<PDPage> kids = new ArrayList<PDPage>();
+ rootPages.getAllKids(kids);
+ PDPage lastPage = kids.get(last);
+ rootPages.getCOSObject().setNeedToBeUpdate(true);
+ PDPage p = new PDPage(lastPage.findMediaBox());
+
+ doc.addPage(p);
+ }
+
+ if (signatureProfileSettings.isPDFA()) {
+ PDDocumentCatalog root = doc.getDocumentCatalog();
+ InputStream colorProfile = PDDocumentCatalog.class
+ .getResourceAsStream("/icm/sRGB Color Space Profile.icm");
+ try {
+ PDOutputIntent oi = new PDOutputIntent(doc,
+ colorProfile);
+ oi.setInfo("sRGB IEC61966-2.1");
+ oi.setOutputCondition("sRGB IEC61966-2.1");
+ oi.setOutputConditionIdentifier("sRGB IEC61966-2.1");
+ oi.setRegistryName("http://www.color.org");
+
+ root.addOutputIntent(oi);
+ root.getCOSObject().setNeedToBeUpdate(true);
+ logger.info("added Output Intent");
+ } catch (Throwable e) {
+ e.printStackTrace();
+ throw new PdfAsException("Failed to add Output Intent",
+ e);
+ }
+ }
+
+ options.setPreferedSignatureSize(0x1000);
+ options.setPage(positioningInstruction.getPage());
+ options.setVisualSignature(new ByteArrayInputStream(sigbos
+ .toByteArray()));
+ }
+
+ doc.addSignature(signature, signer, options);
+
+ // pdfbox patched (FIS -> IS)
+ doc.saveIncremental(fis, fos);
+ fis.close();
+ fos.close();
+
+ fis = new FileInputStream(new File(fisTmpFile));
+
+ // write to resulting output stream
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ bos.write(StreamUtils.inputStreamToByteArray(fis));
+ fis.close();
+ bos.close();
+
+ pdfObject.setSignedDocument(bos.toByteArray());
+
+ helper.deleteFile(fisTmpFile);
+
+ } catch (IOException e) {
+ logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+ throw new PdfAsException("error.pdf.sig.01", e);
+ } catch (SignatureException e) {
+ logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+ throw new PdfAsException("error.pdf.sig.01", e);
+ } catch (COSVisitorException e) {
+ logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+ throw new PdfAsException("error.pdf.sig.01", e);
+ }
+ }
}