List of usage examples for org.apache.pdfbox.cos COSName ACRO_FORM
COSName ACRO_FORM
To view the source code for org.apache.pdfbox.cos COSName ACRO_FORM.
Click Source Link
From source file:ShowSignature.java
License:Apache License
private void showSignature(String[] args) throws IOException, CertificateException { if (args.length != 2) { usage();//from ww w . j av a 2 s. c om } else { String password = args[0]; String infile = args[1]; PDDocument document = null; try { document = PDDocument.load(new File(infile), password); if (!document.isEncrypted()) { System.err.println("Warning: Document is not encrypted."); } COSDictionary trailer = document.getDocument().getTrailer(); COSDictionary root = (COSDictionary) trailer.getDictionaryObject(COSName.ROOT); COSDictionary acroForm = (COSDictionary) root.getDictionaryObject(COSName.ACRO_FORM); COSArray fields = (COSArray) acroForm.getDictionaryObject(COSName.FIELDS); for (int i = 0; i < fields.size(); i++) { COSDictionary field = (COSDictionary) fields.getObject(i); COSName type = field.getCOSName(COSName.FT); if (COSName.SIG.equals(type)) { COSDictionary cert = (COSDictionary) field.getDictionaryObject(COSName.V); if (cert != null) { System.out.println("Certificate found"); System.out.println("Name=" + cert.getDictionaryObject(COSName.NAME)); System.out.println("Modified=" + cert.getDictionaryObject(COSName.M)); COSName subFilter = (COSName) cert.getDictionaryObject(COSName.SUB_FILTER); if (subFilter != null) { if (subFilter.getName().equals("adbe.x509.rsa_sha1")) { COSString certString = (COSString) cert .getDictionaryObject(COSName.getPDFName("Cert")); byte[] certData = certString.getBytes(); CertificateFactory factory = CertificateFactory.getInstance("X.509"); ByteArrayInputStream certStream = new ByteArrayInputStream(certData); Collection<? extends Certificate> certs = factory .generateCertificates(certStream); System.out.println("certs=" + certs); } else if (subFilter.getName().equals("adbe.pkcs7.sha1")) { COSString certString = (COSString) cert.getDictionaryObject(COSName.CONTENTS); byte[] certData = certString.getBytes(); CertificateFactory factory = CertificateFactory.getInstance("X.509"); ByteArrayInputStream certStream = new ByteArrayInputStream(certData); Collection<? extends Certificate> certs = factory .generateCertificates(certStream); System.out.println("certs=" + certs); } else { System.err.println("Unknown certificate type:" + subFilter); } } else { throw new IOException("Missing subfilter for cert dictionary"); } } else { System.out.println("Signature found, but no certificate"); } } } } finally { if (document != null) { document.close(); } } } }
From source file:at.gv.egiz.pdfas.lib.impl.signing.pdfbox.PADESPDFBOXSigner.java
License:EUPL
public void signPDF(PDFObject genericPdfObject, RequestedSignature requestedSignature, PDFASSignatureInterface genericSigner) throws PdfAsException { String fisTmpFile = null;// ww w. java 2 s .c o m PDFAsVisualSignatureProperties properties = null; if (!(genericPdfObject instanceof PDFBOXObject)) { // tODO: throw new PdfAsException(); } PDFBOXObject pdfObject = (PDFBOXObject) genericPdfObject; if (!(genericSigner instanceof PDFASPDFBOXSignatureInterface)) { // tODO: throw new PdfAsException(); } PDFASPDFBOXSignatureInterface signer = (PDFASPDFBOXSignatureInterface) genericSigner; TempFileHelper helper = pdfObject.getStatus().getTempFileHelper(); PDDocument doc = pdfObject.getDocument(); SignatureOptions options = new SignatureOptions(); COSDocument visualSignatureDocumentGuard = null; try { fisTmpFile = helper.getStaticFilename(); FileOutputStream tmpOutputStream = null; try { // write to temporary file tmpOutputStream = new FileOutputStream(new File(fisTmpFile)); InputStream tmpis = null; try { tmpis = pdfObject.getOriginalDocument().getInputStream(); IOUtils.copy(tmpis, tmpOutputStream); tmpis.close(); } finally { IOUtils.closeQuietly(tmpis); } SignaturePlaceholderData signaturePlaceholderData = PlaceholderFilter .checkPlaceholderSignature(pdfObject.getStatus(), pdfObject.getStatus().getSettings()); TablePos tablePos = null; if (signaturePlaceholderData != null) { // Placeholder found! logger.info("Placeholder data found."); if (signaturePlaceholderData.getProfile() != null) { logger.debug("Placeholder Profile set to: " + signaturePlaceholderData.getProfile()); requestedSignature.setSignatureProfileID(signaturePlaceholderData.getProfile()); } tablePos = signaturePlaceholderData.getTablePos(); if (tablePos != null) { SignatureProfileConfiguration signatureProfileConfiguration = pdfObject.getStatus() .getSignatureProfileConfiguration(requestedSignature.getSignatureProfileID()); float minWidth = signatureProfileConfiguration.getMinWidth(); if (minWidth > 0) { if (tablePos.getWidth() < minWidth) { tablePos.width = minWidth; logger.debug("Correcting placeholder with to minimum width {}", minWidth); } } logger.debug("Placeholder Position set to: " + tablePos.toString()); } } 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(requestedSignature, pdfObject.getStatus()); String signerName = resolver.resolve("SIG_SUBJECT", signatureProfileSettings.getValue("SIG_SUBJECT"), signatureProfileSettings); signature.setName(signerName); // take signing time from provided signer... signature.setSignDate(signer.getSigningDate()); // ...and update operation status in order to use exactly this date for the complete signing process requestedSignature.getStatus().setSigningDate(signer.getSigningDate()); 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); int signatureSize = 0x1000; try { String reservedSignatureSizeString = signatureProfileSettings.getValue(SIG_RESERVED_SIZE); if (reservedSignatureSizeString != null) { signatureSize = Integer.parseInt(reservedSignatureSizeString); } logger.debug("Reserving {} bytes for signature", signatureSize); } catch (NumberFormatException e) { logger.warn("Invalid configuration value: {} should be a number using 0x1000", SIG_RESERVED_SIZE); } options.setPreferedSignatureSize(signatureSize); // Is visible Signature if (requestedSignature.isVisual()) { logger.debug("Creating visual signature block"); SignatureProfileConfiguration signatureProfileConfiguration = pdfObject.getStatus() .getSignatureProfileConfiguration(requestedSignature.getSignatureProfileID()); if (tablePos == null) { // ================================================================ // PositioningStage (visual) -> find position or use // fixed // position String posString = pdfObject.getStatus().getSignParamter().getSignaturePosition(); TablePos signaturePos = null; String signaturePosString = signatureProfileConfiguration.getDefaultPositioning(); if (signaturePosString != null) { logger.debug("using signature Positioning: " + signaturePos); signaturePos = new TablePos(signaturePosString); } logger.debug("using Positioning: " + posString); if (posString != null) { // Merge Signature Position tablePos = new TablePos(posString, signaturePos); } else { // Fallback to signature Position! tablePos = signaturePos; } if (tablePos == null) { // Last Fallback default position tablePos = new TablePos(); } } boolean legacy32Position = signatureProfileConfiguration.getLegacy32Positioning(); boolean legacy40Position = signatureProfileConfiguration.getLegacy40Positioning(); // create Table describtion Table main = TableFactory.createSigTable(signatureProfileSettings, MAIN, pdfObject.getStatus(), 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, "", doc, visualObject, legacy32Position, legacy40Position); logger.debug("Positioning: {}", positioningInstruction.toString()); 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()); p.setResources(new PDResources()); p.setRotation(lastPage.findRotation()); doc.addPage(p); } // handle rotated page PDDocumentCatalog documentCatalog = doc.getDocumentCatalog(); PDPageNode documentPages = documentCatalog.getPages(); List<PDPage> documentPagesKids = new ArrayList<PDPage>(); documentPages.getAllKids(documentPagesKids); int targetPageNumber = positioningInstruction.getPage(); logger.debug("Target Page: " + targetPageNumber); // rootPages.getAllKids(kids); PDPage targetPage = documentPagesKids.get(targetPageNumber - 1); int rot = targetPage.findRotation(); logger.debug("Page rotation: " + rot); // positioningInstruction.setRotation(positioningInstruction.getRotation() // + rot); logger.debug("resulting Sign rotation: " + positioningInstruction.getRotation()); 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); properties = new PDFAsVisualSignatureProperties(pdfObject.getStatus().getSettings(), pdfObject, (PdfBoxVisualObject) visualObject, positioningInstruction, signatureProfileSettings); properties.buildSignature(); /* * ByteArrayOutputStream sigbos = new * ByteArrayOutputStream(); * sigbos.write(StreamUtils.inputStreamToByteArray * (properties .getVisibleSignature())); sigbos.close(); */ if (signaturePlaceholderData != null) { // Placeholder found! // replace placeholder InputStream is = null; try { 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 - 1); 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()); } finally { IOUtils.closeQuietly(is); } } if (signatureProfileSettings.isPDFA()) { PDDocumentCatalog root = doc.getDocumentCatalog(); COSBase base = root.getCOSDictionary().getItem(COSName.OUTPUT_INTENTS); if (base == null) { InputStream colorProfile = null; try { 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) { throw new PdfAsException("Failed to add Output Intent", e); } } finally { IOUtils.closeQuietly(colorProfile); } } } options.setPage(positioningInstruction.getPage()); options.setVisualSignature(properties.getVisibleSignature()); } visualSignatureDocumentGuard = options.getVisualSignature(); doc.addSignature(signature, signer, options); // set need to update indirect fields array in acro form COSDictionary trailer = doc.getDocument().getTrailer(); if (trailer != null) { COSDictionary troot = (COSDictionary) trailer.getDictionaryObject(COSName.ROOT); if (troot != null) { COSDictionary acroForm = (COSDictionary) troot.getDictionaryObject(COSName.ACRO_FORM); if (acroForm != null) { COSArray tfields = (COSArray) acroForm.getDictionaryObject(COSName.FIELDS); if (tfields != null && !tfields.isDirect()) { tfields.setNeedToBeUpdate(true); } } } } String sigFieldName = signatureProfileSettings.getSignFieldValue(); if (sigFieldName == null) { sigFieldName = "PDF-AS Signatur"; } int count = PdfBoxUtils.countSignatures(doc, sigFieldName); sigFieldName = sigFieldName + count; PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm(); PDSignatureField signatureField = null; if (acroFormm != null) { @SuppressWarnings("unchecked") List<PDField> fields = acroFormm.getFields(); 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) { if (tmpSigField.getSignature().getDictionary() .equals(signature.getDictionary())) { signatureField = (PDSignatureField) pdField; } } } } } } else { logger.warn("Failed to name Signature Field! [Cannot find Field list in acroForm!]"); } if (signatureField != null) { 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 structureTreeRoot = root.getStructureTreeRoot(); if (structureTreeRoot != null) { logger.info("Tree Root: {}", structureTreeRoot.toString()); List<Object> kids = structureTreeRoot.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; } } 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.setPage(signatureField.getWidget().getPage()); 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 = structureTreeRoot.getParentTree(); int parentTreeNextKey = structureTreeRoot.getParentTreeNextKey(); if (ntn == null) { ntn = new PDNumberTreeNode(objectDic, null); logger.info("No number-tree-node found!"); } COSArray ntnKids = (COSArray) ntn.getCOSDictionary().getDictionaryObject(COSName.KIDS); COSArray ntnNumbers = (COSArray) ntn.getCOSDictionary().getDictionaryObject(COSName.NUMS); if (ntnNumbers == null && ntnKids != null) {//no number array, so continue with the kids array //create dictionary with limits and nums array COSDictionary pTreeEntry = new COSDictionary(); COSArray limitsArray = new COSArray(); //limits for exact one entry limitsArray.add(COSInteger.get(parentTreeNextKey)); limitsArray.add(COSInteger.get(parentTreeNextKey)); COSArray numsArray = new COSArray(); numsArray.add(COSInteger.get(parentTreeNextKey)); numsArray.add(sigBlock); pTreeEntry.setItem(COSName.NUMS, numsArray); pTreeEntry.setItem(COSName.LIMITS, limitsArray); PDNumberTreeNode newKidsElement = new PDNumberTreeNode(pTreeEntry, PDNumberTreeNode.class); ntnKids.add(newKidsElement); ntnKids.setNeedToBeUpdate(true); //working // List<PDNumberTreeNode> treeRootKids = structureTreeRoot.getParentTree().getKids(); // PDNumberTreeNode last = (PDNumberTreeNode)treeRootKids.get(treeRootKids.size()-1); // COSArray lim1 = (COSArray) last.getCOSDictionary().getDictionaryObject(COSName.LIMITS); // lim1.remove(1); // lim1.add(1, COSInteger.get(parentTreeNextKey)); // PDNumberTreeNode verylast = (PDNumberTreeNode)last.getKids().get(last.getKids().size()-1); // COSArray numa = (COSArray) verylast.getCOSDictionary().getDictionaryObject(COSName.NUMS); // COSArray lim = (COSArray) verylast.getCOSDictionary().getDictionaryObject(COSName.LIMITS); // lim.remove(1); // lim.add(1, COSInteger.get(parentTreeNextKey)); // // int size = numa.size(); // numa.add(size, COSInteger.get(parentTreeNextKey)); // numa.add(sigBlock); //working end } else if (ntnNumbers != null && ntnKids == null) { int arrindex = ntnNumbers.size(); ntnNumbers.add(arrindex, COSInteger.get(parentTreeNextKey)); ntnNumbers.add(arrindex + 1, sigBlock.getCOSObject()); ntnNumbers.getCOSObject().setNeedToBeUpdate(true); structureTreeRoot.setParentTree(ntn); } else if (ntnNumbers == null && ntnKids == null) { //document is not pdfua conform before signature creation throw new PdfAsException("error.pdf.sig.pdfua.1"); } else { //this is not allowed throw new PdfAsException("error.pdf.sig.pdfua.1"); } // set StructureParent for signature field annotation signatureField.getWidget().setStructParent(parentTreeNextKey); //Increase the next Key value in the structure tree root structureTreeRoot.setParentTreeNextKey(parentTreeNextKey + 1); // add the Tabs /S Element for Tabbing through annots PDPage p = signatureField.getWidget().getPage(); p.getCOSDictionary().setName("Tabs", "S"); p.getCOSObject().setNeedToBeUpdate(true); //check alternative signature field name if (signatureField != null) { if (signatureField.getAlternateFieldName().equals("")) signatureField.setAlternateFieldName(sigFieldName); } ntn.getCOSDictionary().setNeedToBeUpdate(true); sigBlock.getCOSObject().setNeedToBeUpdate(true); structureTreeRoot.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"); } } try { applyFilter(doc, requestedSignature); } catch (PDFASError e) { throw new PdfAsErrorCarrier(e); } FileInputStream tmpFileIs = null; try { tmpFileIs = new FileInputStream(new File(fisTmpFile)); synchronized (doc) { doc.saveIncremental(tmpFileIs, tmpOutputStream); } tmpFileIs.close(); } finally { IOUtils.closeQuietly(tmpFileIs); if (options != null) { if (options.getVisualSignature() != null) { options.getVisualSignature().close(); } } } tmpOutputStream.flush(); tmpOutputStream.close(); } finally { IOUtils.closeQuietly(tmpOutputStream); COSDocument visualSignature = options.getVisualSignature(); if (visualSignature != null) { visualSignature.close(); } } FileInputStream readReadyFile = null; try { readReadyFile = new FileInputStream(new File(fisTmpFile)); // write to resulting output stream // ByteArrayOutputStream bos = new ByteArrayOutputStream(); // bos.write(); // bos.close(); pdfObject.setSignedDocument(StreamUtils.inputStreamToByteArray(readReadyFile)); readReadyFile.close(); } finally { IOUtils.closeQuietly(readReadyFile); } } catch (IOException e) { logger.info(MessageResolver.resolveMessage("error.pdf.sig.01") + ": {}", e.toString()); throw new PdfAsException("error.pdf.sig.01", e); } catch (SignatureException e) { logger.info(MessageResolver.resolveMessage("error.pdf.sig.01") + ": {}", e.toString()); throw new PdfAsException("error.pdf.sig.01", e); } catch (COSVisitorException e) { logger.info(MessageResolver.resolveMessage("error.pdf.sig.01") + ": {}", e.toString()); throw new PdfAsException("error.pdf.sig.01", e); } finally { if (doc != null) { try { doc.close(); } catch (IOException e) { logger.debug("Failed to close COS Doc!", e); // Ignore } } if (fisTmpFile != null) { helper.deleteFile(fisTmpFile); } logger.debug("Signature done!"); } }
From source file:com.itdhq.poc.ocrsign.ShowSignature.java
License:Apache License
private void showSignature(String[] args) throws IOException, CertificateException { if (args.length != 2) { usage();/*from w ww . j a va 2 s .c om*/ } else { String password = args[0]; String infile = args[1]; PDDocument document = null; try { document = PDDocument.load(new File(infile)); if (!document.isEncrypted()) { System.err.println("Warning: Document is not encrypted."); } COSDictionary trailer = document.getDocument().getTrailer(); COSDictionary root = (COSDictionary) trailer.getDictionaryObject(COSName.ROOT); COSDictionary acroForm = (COSDictionary) root.getDictionaryObject(COSName.ACRO_FORM); COSArray fields = (COSArray) acroForm.getDictionaryObject(COSName.FIELDS); for (int i = 0; i < fields.size(); i++) { COSDictionary field = (COSDictionary) fields.getObject(i); // FIXME /* COSName type = field.getCOSName( COSName.FT ); if( COSName.SIG.equals( type ) ) { COSDictionary cert = (COSDictionary)field.getDictionaryObject( COSName.V ); if( cert != null ) { System.out.println( "Certificate found" ); System.out.println( "Name=" + cert.getDictionaryObject( COSName.NAME ) ); System.out.println( "Modified=" + cert.getDictionaryObject( COSName.M ) ); COSName subFilter = (COSName)cert.getDictionaryObject( COSName.SUB_FILTER ); if( subFilter != null ) { if( subFilter.getName().equals( "adbe.x509.rsa_sha1" ) ) { COSString certString = (COSString)cert.getDictionaryObject( COSName.getPDFName( "Cert" ) ); byte[] certData = certString.getBytes(); CertificateFactory factory = CertificateFactory.getInstance( "X.509" ); ByteArrayInputStream certStream = new ByteArrayInputStream( certData ); Collection<? extends Certificate> certs = factory.generateCertificates( certStream ); System.out.println( "certs=" + certs ); } else if( subFilter.getName().equals( "adbe.pkcs7.sha1" ) ) { COSString certString = (COSString)cert.getDictionaryObject( COSName.CONTENTS ); byte[] certData = certString.getBytes(); CertificateFactory factory = CertificateFactory.getInstance( "X.509" ); ByteArrayInputStream certStream = new ByteArrayInputStream( certData ); Collection<? extends Certificate> certs = factory.generateCertificates( certStream ); System.out.println( "certs=" + certs ); } else { System.err.println( "Unknown certificate type:" + subFilter ); } } else { throw new IOException( "Missing subfilter for cert dictionary" ); } } else { System.out.println( "Signature found, but no certificate" ); } } */ } } finally { if (document != null) { document.close(); } } } }
From source file:org.apache.fop.render.pdf.pdfbox.PDFBoxAdapter.java
License:Apache License
private void handleAnnotations(PDDocument sourceDoc, PDPage page, AffineTransform at) throws IOException { PDDocumentCatalog srcCatalog = sourceDoc.getDocumentCatalog(); PDAcroForm srcAcroForm = srcCatalog.getAcroForm(); List pageAnnotations = page.getAnnotations(); if (srcAcroForm == null && pageAnnotations.isEmpty()) { return;/*ww w . ja v a2 s . c o m*/ } moveAnnotations(page, pageAnnotations, at); //Pseudo-cache the target page in place of the original source page. //This essentially replaces the original page reference with the target page. COSObject cosPage = null; COSDictionary parentDic = (COSDictionary) page.getCOSObject().getDictionaryObject(COSName.PARENT, COSName.P); COSArray kids = (COSArray) parentDic.getDictionaryObject(COSName.KIDS); for (int i = 0; i < kids.size(); i++) { //Hopefully safe to cast, as kids need to be indirect objects COSObject kid = (COSObject) kids.get(i); if (!pageNumbers.containsKey(i)) { PDFArray a = new PDFArray(); a.add(null); pdfDoc.assignObjectNumber(a); pdfDoc.addTrailerObject(a); pageNumbers.put(i, a); } cacheClonedObject(kid, pageNumbers.get(i)); if (kid.getObject() == page.getCOSObject()) { cosPage = kid; } } if (cosPage == null) { throw new IOException("Illegal PDF. Page not part of parent page node."); } Set<COSObject> fields = copyAnnotations(page); boolean formAlreadyCopied = getCachedClone(srcAcroForm) != null; PDFRoot catalog = this.pdfDoc.getRoot(); PDFDictionary destAcroForm = (PDFDictionary) catalog.get(COSName.ACRO_FORM.getName()); if (formAlreadyCopied) { //skip, already copied } else if (destAcroForm == null) { if (srcAcroForm != null) { //With this, only the first PDF's AcroForm is copied over. If later AcroForms have //different properties besides the actual fields, these get lost. Only fields //get merged. Collection exclude = Collections.singletonList(COSName.FIELDS); destAcroForm = (PDFDictionary) cloneForNewDocument(srcAcroForm, srcAcroForm, exclude); } else { //Work-around for incorrectly split PDFs which lack an AcroForm but have widgets //on pages. This doesn't handle the case where field dicts have "C" entries //(for the "CO" entry), so this may produce problems, but we have almost no chance //to guess the calculation order. destAcroForm = new PDFDictionary(pdfDoc.getRoot()); } pdfDoc.registerObject(destAcroForm); catalog.put(COSName.ACRO_FORM.getName(), destAcroForm); } PDFArray clonedFields = (PDFArray) destAcroForm.get(COSName.FIELDS.getName()); if (clonedFields == null) { clonedFields = new PDFArray(); destAcroForm.put(COSName.FIELDS.getName(), clonedFields); } for (COSObject field : fields) { PDFDictionary clone = (PDFDictionary) cloneForNewDocument(field, field, Arrays.asList(COSName.KIDS)); clonedFields.add(clone); } }
From source file:test.be.fedict.eid.applet.PdfSpikeTest.java
License:Open Source License
@Test public void testSignPDF() throws Exception { // create a sample PDF file Document document = new Document(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfWriter.getInstance(document, baos); document.open();/* w w w . j av a 2 s . c om*/ Paragraph titleParagraph = new Paragraph("This is a test."); titleParagraph.setAlignment(Paragraph.ALIGN_CENTER); document.add(titleParagraph); document.newPage(); Paragraph textParagraph = new Paragraph("Hello world."); document.add(textParagraph); document.close(); File tmpFile = File.createTempFile("test-", ".pdf"); LOG.debug("tmp file: " + tmpFile.getAbsolutePath()); FileUtils.writeByteArrayToFile(tmpFile, baos.toByteArray()); // eID PcscEid pcscEid = new PcscEid(new TestView(), new Messages(Locale.getDefault())); if (false == pcscEid.isEidPresent()) { LOG.debug("insert eID card"); pcscEid.waitForEidPresent(); } List<X509Certificate> signCertificateChain = pcscEid.getSignCertificateChain(); Certificate[] certs = new Certificate[signCertificateChain.size()]; for (int idx = 0; idx < certs.length; idx++) { certs[idx] = signCertificateChain.get(idx); } // open the pdf FileInputStream pdfInputStream = new FileInputStream(tmpFile); File signedTmpFile = File.createTempFile("test-signed-", ".pdf"); PdfReader reader = new PdfReader(pdfInputStream); FileOutputStream pdfOutputStream = new FileOutputStream(signedTmpFile); PdfStamper stamper = PdfStamper.createSignature(reader, pdfOutputStream, '\0', null, true); // add extra page Rectangle pageSize = reader.getPageSize(1); int pageCount = reader.getNumberOfPages(); int extraPageIndex = pageCount + 1; stamper.insertPage(extraPageIndex, pageSize); // calculate unique signature field name int signatureNameIndex = 1; String signatureName; AcroFields existingAcroFields = reader.getAcroFields(); List<String> existingSignatureNames = existingAcroFields.getSignatureNames(); do { signatureName = "Signature" + signatureNameIndex; signatureNameIndex++; } while (existingSignatureNames.contains(signatureName)); LOG.debug("new unique signature name: " + signatureName); PdfSignatureAppearance signatureAppearance = stamper.getSignatureAppearance(); signatureAppearance.setCrypto(null, certs, null, PdfSignatureAppearance.SELF_SIGNED); signatureAppearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED); signatureAppearance.setReason("PDF Signature Test"); signatureAppearance.setLocation("Belgium"); signatureAppearance.setVisibleSignature(new Rectangle(54, 440, 234, 566), extraPageIndex, signatureName); signatureAppearance.setExternalDigest(new byte[128], new byte[20], "RSA"); signatureAppearance.preClose(); byte[] content = IOUtils.toByteArray(signatureAppearance.getRangeStream()); byte[] hash = MessageDigest.getInstance("SHA-1").digest(content); byte[] signatureBytes = pcscEid.sign(hash, "SHA-1"); pcscEid.close(); PdfSigGenericPKCS sigStandard = signatureAppearance.getSigStandard(); PdfPKCS7 signature = sigStandard.getSigner(); signature.setExternalDigest(signatureBytes, hash, "RSA"); PdfDictionary dictionary = new PdfDictionary(); dictionary.put(PdfName.CONTENTS, new PdfString(signature.getEncodedPKCS1()).setHexWriting(true)); signatureAppearance.close(dictionary); LOG.debug("signed tmp file: " + signedTmpFile.getAbsolutePath()); // verify the signature reader = new PdfReader(new FileInputStream(signedTmpFile)); AcroFields acroFields = reader.getAcroFields(); ArrayList<String> signatureNames = acroFields.getSignatureNames(); for (String signName : signatureNames) { LOG.debug("signature name: " + signName); LOG.debug("signature covers whole document: " + acroFields.signatureCoversWholeDocument(signName)); LOG.debug("document revision " + acroFields.getRevision(signName) + " of " + acroFields.getTotalRevisions()); PdfPKCS7 pkcs7 = acroFields.verifySignature(signName); Calendar signDate = pkcs7.getSignDate(); LOG.debug("signing date: " + signDate.getTime()); LOG.debug("Subject: " + PdfPKCS7.getSubjectFields(pkcs7.getSigningCertificate())); LOG.debug("Document modified: " + !pkcs7.verify()); Certificate[] verifyCerts = pkcs7.getCertificates(); for (Certificate certificate : verifyCerts) { X509Certificate x509Certificate = (X509Certificate) certificate; LOG.debug("cert subject: " + x509Certificate.getSubjectX500Principal()); } } /* * Reading the signature using Apache PDFBox. */ PDDocument pdDocument = PDDocument.load(signedTmpFile); COSDictionary trailer = pdDocument.getDocument().getTrailer(); /* * PDF Reference - third edition - Adobe Portable Document Format - * Version 1.4 - 3.6.1 Document Catalog */ COSDictionary documentCatalog = (COSDictionary) trailer.getDictionaryObject(COSName.ROOT); /* * 8.6.1 Interactive Form Dictionary */ COSDictionary acroForm = (COSDictionary) documentCatalog.getDictionaryObject(COSName.ACRO_FORM); COSArray fields = (COSArray) acroForm.getDictionaryObject(COSName.FIELDS); for (int fieldIdx = 0; fieldIdx < fields.size(); fieldIdx++) { COSDictionary field = (COSDictionary) fields.getObject(fieldIdx); String fieldType = field.getNameAsString("FT"); if ("Sig".equals(fieldType)) { COSDictionary signatureDictionary = (COSDictionary) field.getDictionaryObject(COSName.V); /* * TABLE 8.60 Entries in a signature dictionary */ COSString signatoryName = (COSString) signatureDictionary.getDictionaryObject(COSName.NAME); if (null != signatoryName) { LOG.debug("signatory name: " + signatoryName.getString()); } COSString reason = (COSString) signatureDictionary.getDictionaryObject(COSName.REASON); if (null != reason) { LOG.debug("reason: " + reason.getString()); } COSString location = (COSString) signatureDictionary.getDictionaryObject(COSName.LOCATION); if (null != location) { LOG.debug("location: " + location.getString()); } Calendar signingTime = signatureDictionary.getDate(COSName.M); if (null != signingTime) { LOG.debug("signing time: " + signingTime.getTime()); } String signatureHandler = signatureDictionary.getNameAsString(COSName.FILTER); LOG.debug("signature handler: " + signatureHandler); } } }