public byte[] buildSignedPDF(String digestOID, byte[] signature, byte[] hash) throws Exception { byte[] hashTmp = null; if (dateTime != null) hashTmp = hash; byte[] pkcs7enc = PKCS7Manager.buildPDFPKCS7(digestOID, x509Certificate, signature, hashTmp, dateTime); PdfDictionary dic = new PdfDictionary(); PdfString contents = new PdfString(pkcs7enc).setHexWriting(true); contentsSize = contents.length(); dic.put(PdfName.CONTENTS, contents); sap.close(dic); return bout.toByteArray(); }
private void unpack(Set<PdfDictionary> dictionaries) throws TaskIOException { for (PdfDictionary dictionary : dictionaries) { PdfName type = dictionary.getAsName(PdfName.TYPE); if (PdfName.F.equals(type) || PdfName.FILESPEC.equals(type)) { PdfDictionary ef = dictionary.getAsDict(PdfName.EF); PdfString fn = dictionary.getAsString(PdfName.F); if (fn != null && ef != null) { PRStream prs = (PRStream) PdfReader.getPdfObject(ef.get(PdfName.F)); if (prs != null) { File tmpFile = copyToTemporaryFile(prs); outputWriter.addOutput(file(tmpFile).name(fn.toUnicodeString())); } } } } }
public Text(PdfString text, Vector startLocation, Vector endLocation, boolean visible, int numOfStrTextBelongsTo) { super(visible); this.text = text; this.startX = startLocation.get(0); this.endX = endLocation.get(0); this.numOfStrTextBelongsTo = numOfStrTextBelongsTo; }
/** * <p> * A primitive attempt at copying links from page <code>sourcePage</code> * of <code>PdfReader reader</code> to page <code>targetPage</code> of * <code>PdfStamper stamper</code>. * </p> * <p> * This method is meant only for the use case at hand, i.e. copying a link * to an external URI without expecting any advanced features. * </p> */ void copyLinks(PdfStamper stamper, int targetPage, PdfReader reader, int sourcePage) { PdfDictionary sourcePageDict = reader.getPageNRelease(sourcePage); PdfArray annotations = sourcePageDict.getAsArray(PdfName.ANNOTS); if (annotations != null && annotations.size() > 0) { for (PdfObject annotationObject : annotations) { annotationObject = PdfReader.getPdfObject(annotationObject); if (!annotationObject.isDictionary()) continue; PdfDictionary annotation = (PdfDictionary) annotationObject; if (!PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) continue; PdfArray rectArray = annotation.getAsArray(PdfName.RECT); if (rectArray == null || rectArray.size() < 4) continue; Rectangle rectangle = PdfReader.getNormalizedRectangle(rectArray); PdfName hightLight = annotation.getAsName(PdfName.H); if (hightLight == null) hightLight = PdfAnnotation.HIGHLIGHT_INVERT; PdfDictionary actionDict = annotation.getAsDict(PdfName.A); if (actionDict == null || !PdfName.URI.equals(actionDict.getAsName(PdfName.S))) continue; PdfString urlPdfString = actionDict.getAsString(PdfName.URI); if (urlPdfString == null) continue; PdfAction action = new PdfAction(urlPdfString.toString()); PdfAnnotation link = PdfAnnotation.createLink(stamper.getWriter(), rectangle, hightLight, action); stamper.addAnnotation(link, targetPage); } } }
/** * <a href="http://stackoverflow.com/questions/31402602/how-to-rename-only-the-first-found-duplicate-acrofield-in-pdf"> * How to rename only the first found duplicate acrofield in pdf? * </a> * <br> * <a href="http://s000.tinyupload.com/index.php?file_id=34970992934525199618"> * test_duplicate_field2.pdf * </a> * <p> * Demonstration of how to transform generate a new field for a widget. * </p> */ @Test public void testWidgetToField() throws IOException, DocumentException { try ( InputStream resource = getClass().getResourceAsStream("test_duplicate_field2.pdf"); OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "test_duplicate_field2-widgetToField.pdf")) ) { PdfReader reader = new PdfReader(resource); PdfDictionary form = reader.getCatalog().getAsDict(PdfName.ACROFORM); PdfArray fields = form.getAsArray(PdfName.FIELDS); for (PdfObject object: fields) { PdfDictionary field = (PdfDictionary) PdfReader.getPdfObject(object); if ("Text1".equals(field.getAsString(PdfName.T).toString())) { PdfDictionary newField = new PdfDictionary(); PRIndirectReference newFieldRef = reader.addPdfObject(newField); fields.add(newFieldRef); newField.putAll(field); newField.put(PdfName.T, new PdfString("foobar")); PdfArray newKids = new PdfArray(); newField.put(PdfName.KIDS, newKids); PdfArray kids = field.getAsArray(PdfName.KIDS); PdfObject widget = kids.remove(0); newKids.add(widget); PdfDictionary widgetDict = (PdfDictionary) PdfReader.getPdfObject(widget); widgetDict.put(PdfName.PARENT, newFieldRef); break; } } PdfStamper stamper = new PdfStamper(reader, result); stamper.close(); } }
static void collectFolders(Map<Integer, File> collection, PdfDictionary folder, File baseDir) { PdfString name = folder.getAsString(PdfName.NAME); File folderDir = new File(baseDir, name.toString()); folderDir.mkdirs(); PdfNumber id = folder.getAsNumber(PdfName.ID); collection.put(id.intValue(), folderDir); PdfDictionary next = folder.getAsDict(PdfName.NEXT); if (next != null) collectFolders(collection, next, baseDir); PdfDictionary child = folder.getAsDict(CHILD); if (child != null) collectFolders(collection, child, folderDir); }
private void updateOneEntryPerDoc(PdfMergeInput input, int offset) { String name = input.getSource().getName(); if (StringUtils.isNotBlank(name)) { LOG.debug("Adding outline entry for {}", name); HashMap<String, Object> current = new HashMap<String, Object>(); current.put(ITextOutlineUtils.TITLE_KEY, new PdfString(removeExtension(name)).toUnicodeString()); current.put(ITextOutlineUtils.PAGE_KEY, Integer.toString(offset + 1)); current.put(ITextOutlineUtils.ACTION_KEY, ITextOutlineUtils.GOTO_VALUE); outline.add(current); } else { LOG.warn("Outline entry not created, unable to find its name."); } }
@Override public PdfStructureElement toPdfStructureElement(PdfStructureTreeRoot treeRoot) { PdfStructureElement pdfStructureElement = new PdfStructureElement(treeRoot, getLevelPdfName()); for (TEIElement element : this.getChildElements()) { element.toPdfStructureElement(pdfStructureElement); } pdfStructureElement.setAttribute(PdfName.ACTUALTEXT, new PdfString(getContent())); return pdfStructureElement; }
@Override public PdfStructureElement toPdfStructureElement(PdfStructureElement parent) { PdfStructureElement pdfStructureElement = new PdfStructureElement(parent, getLevelPdfName()); for (TEIElement element : this.getChildElements()) { element.toPdfStructureElement(pdfStructureElement); } pdfStructureElement.setAttribute(PdfName.ACTUALTEXT, new PdfString(getContent())); return pdfStructureElement; }
@Override public PdfStructureElement toPdfStructureElement(PdfStructureTreeRoot treeRoot) { PdfStructureElement pdfStructureElement = new PdfStructureElement(treeRoot, PdfName.FIGURE); pdfStructureElement.setAttribute(PdfName.ACTUALTEXT, new PdfString(getContent())); if (heading != null) { pdfStructureElement.setAttribute(PdfName.H, new PdfString(heading)); } return pdfStructureElement; }
@Override public PdfStructureElement toPdfStructureElement(PdfStructureElement parent) { PdfStructureElement pdfStructureElement = new PdfStructureElement(parent, PdfName.FIGURE); pdfStructureElement.setAttribute(PdfName.ACTUALTEXT, new PdfString(getContent())); if (heading != null) { pdfStructureElement.setAttribute(PdfName.H, new PdfString(heading)); } return pdfStructureElement; }
/** * This method extracts integrated signature information from the PDF * this class is instantiated with. * @return */ //@SuppressWarnings("unchecked") public Map<String, SignatureData> extractSignatures() { final Map<String, SignatureData> result = new HashMap<String, SignatureData>(); final AcroFields fields = reader.getAcroFields(); for (String name: fields.getSignatureNames()) { PdfDictionary sigDict = fields.getSignatureDictionary(name); PdfString contents = sigDict.getAsString(PdfName.CONTENTS); PdfName subFilter = sigDict.getAsName(PdfName.SUBFILTER); if (contents != null) { byte[] contentBytes = contents.getOriginalBytes(); byte[] containerBytes = null; /* ContentInfo contentInfo = null; try { contentInfo = new ContentInfoImpl(contentBytes); byte[] bytes = contentInfo.getEncoded(); if (bytes.length <= contentBytes.length) { boolean equal = true; for (int i = 0; i < bytes.length; i++) { if (bytes[i] != contentBytes[i]) { System.err.println("Re-encoded differs at " + i); equal = false; break; } } if (equal) containerBytes = bytes; } else { System.err.println("Re-encoded data too long"); } } catch (GeneralSecurityException e) { System.err.println("Failure decoding content as container."); e.printStackTrace(); } */ Date signingTime = null; Object pdfDateEntry = sigDict.get(PdfName.M); if (pdfDateEntry != null) { Calendar cal = PdfDate.decode(pdfDateEntry.toString()); if (cal != null) { signingTime = cal.getTime(); } } result.put(name, new SignatureData(/*contentInfo,*/ containerBytes, contentBytes, subFilter, signingTime)); } } return result; }
public PdfString getText() { return text; }
/** * <a href="http://stackoverflow.com/questions/28911509/how-to-retain-page-labels-when-concatenating-an-existing-pdf-with-a-pdf-created"> * How to retain page labels when concatenating an existing pdf with a pdf created from scratch? * </a> * <p> * A proposal how to implement the task using a {@link PdfStamper}. */ @Test public void testInsertTitlePage() throws IOException, DocumentException { try ( InputStream documentStream = getClass().getResourceAsStream("Labels.pdf"); InputStream titleStream = getClass().getResourceAsStream("Cover.pdf"); OutputStream outputStream = new FileOutputStream(new File(RESULT_FOLDER, "labels-with-cover-page.pdf")) ) { PdfReader titleReader = new PdfReader(titleStream); PdfReader reader = new PdfReader(documentStream); PdfStamper stamper = new PdfStamper(reader, outputStream); PdfImportedPage page = stamper.getImportedPage(titleReader, 1); stamper.insertPage(1, titleReader.getPageSize(1)); PdfContentByte content = stamper.getUnderContent(1); content.addTemplate(page, 0, 0); copyLinks(stamper, 1, titleReader, 1); PdfDictionary root = reader.getCatalog(); PdfDictionary labels = root.getAsDict(PdfName.PAGELABELS); if (labels != null) { PdfArray newNums = new PdfArray(); newNums.add(new PdfNumber(0)); PdfDictionary coverDict = new PdfDictionary(); coverDict.put(PdfName.P, new PdfString("Cover Page")); newNums.add(coverDict); PdfArray nums = labels.getAsArray(PdfName.NUMS); if (nums != null) { for (int i = 0; i < nums.size() - 1; ) { int n = nums.getAsNumber(i++).intValue(); newNums.add(new PdfNumber(n+1)); newNums.add(nums.getPdfObject(i++)); } } labels.put(PdfName.NUMS, newNums); stamper.markUsed(labels); } stamper.close(); } }
@Override protected void configurePDFWriter(PdfWriter writer) throws IOException { double leftMap = pageFormat.getPageLeft(); double bottomMap = pageFormat.getPageBottom(); PdfDictionary lgiDict = new PdfDictionary(new PdfName("LGIDict")); lgiDict.put(new PdfName("Version"), new PdfNumber("2.1")); /* // Registration (optional): not interpreted by GDAL double rightMap = pageFormat.getPageRight(); double topMap = pageFormat.getPageTop(); float leftPage = xToPagePx((float) leftMap); float bottomPage = yToPagePx((float) bottomMap); float rightPage = xToPagePx((float) rightMap); float topPage = yToPagePx((float) topMap); PdfArray lowerLeftPoint = new PdfArray(); lowerLeftPoint.add(new PdfString(Double.toString(leftPage))); lowerLeftPoint.add(new PdfString(Double.toString(bottomPage))); lowerLeftPoint.add(new PdfString(Double.toString(leftMap))); lowerLeftPoint.add(new PdfString(Double.toString(bottomMap))); PdfArray upperRightPoint = new PdfArray(); upperRightPoint.add(new PdfString(Double.toString(rightPage))); upperRightPoint.add(new PdfString(Double.toString(topPage))); upperRightPoint.add(new PdfString(Double.toString(rightMap))); upperRightPoint.add(new PdfString(Double.toString(topMap))); PdfArray registration = new PdfArray(); registration.add(lowerLeftPoint); registration.add(upperRightPoint); lgiDict.put(new PdfName("Registration"), registration); */ // FIXME usage of PageFormat.MM2PX double scale = pageFormat.getPageWidthWorldCoordinates() / pageFormat.getPageWidth() / PageFormat.MM2PX; PdfArray ctmArray = new PdfArray(); ctmArray.add(new PdfString(Double.toString(scale))); ctmArray.add(new PdfString("0")); ctmArray.add(new PdfString("0")); ctmArray.add(new PdfString(Double.toString(scale))); ctmArray.add(new PdfString(Double.toString(leftMap))); ctmArray.add(new PdfString(Double.toString(bottomMap))); lgiDict.put(new PdfName("CTM"), ctmArray); // Projection PdfDictionary projectionDict = new PdfDictionary(new PdfName("Projection")); projectionDict.put(new PdfName("ProjectionType"), new PdfString("NONE")); lgiDict.put(new PdfName("Projection"), projectionDict); /* // Neatline (optional) PdfArray neatlinePoints = new PdfArray(); neatlinePoints.add(new PdfString(Double.toString(leftPage))); neatlinePoints.add(new PdfString(Double.toString(bottomPage))); neatlinePoints.add(new PdfString(Double.toString(rightPage))); neatlinePoints.add(new PdfString(Double.toString(topPage))); lgiDict.put(new PdfName("Neatline"), neatlinePoints); */ writer.addPageDictEntry(new PdfName("LGIDict"), lgiDict); }
@Override protected void configurePDFWriter(PdfWriter writer) throws IOException { final boolean initialPrecisionFlat = ByteBuffer.HIGH_PRECISION; try { ByteBuffer.HIGH_PRECISION = true; PdfDictionary dicMeasure = new PdfDictionary(new PdfName("Measure")); dicMeasure.put(PdfName.SUBTYPE, new PdfName("GEO")); PdfArray bounds = new PdfArray(); // lower left, upper left, upper right, lower right bounds.add(new float[]{0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f}); // geographic coordinates of corner points as lat/lon pairs PdfArray gpts = new PdfArray(lonLatCornerPoints); // lower left, upper left, upper right, lower right PdfArray lpts = new PdfArray(new float[]{0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f}); dicMeasure.put(new PdfName("Bounds"), bounds); dicMeasure.put(new PdfName("LPTS"), lpts); dicMeasure.put(new PdfName("GPTS"), gpts); PdfDictionary dicGCS = new PdfDictionary(new PdfName("PROJCS")); dicGCS.put(new PdfName("WKT"), new PdfString(wkt)); PdfIndirectObject indObjGCS = writer.addToBody(dicGCS); PdfIndirectReference indRefGCS = indObjGCS.getIndirectReference(); dicMeasure.put(new PdfName("GCS"), indRefGCS); PdfDictionary viewport = new PdfDictionary(new PdfName("Viewport")); viewport.put(new PdfName("Name"), new PdfString("Scree")); float left = (float) xToPagePx(pageFormat.getPageLeft()); float lower = (float) yToPagePx(pageFormat.getPageBottom()); float right = (float) xToPagePx(pageFormat.getPageRight()); float upper = (float) yToPagePx(pageFormat.getPageTop()); viewport.put(new PdfName("BBox"), new PdfRectangle(left, lower, right, upper)); PdfIndirectObject indObjMeasure = writer.addToBody(dicMeasure); PdfIndirectReference indRefMeasure = indObjMeasure.getIndirectReference(); viewport.put(new PdfName("Measure"), indRefMeasure); writer.setPageViewport(new PdfArray(viewport)); } finally { ByteBuffer.HIGH_PRECISION = initialPrecisionFlat; } }
@Override public PdfStructureElement toPdfStructureElement(PdfStructureTreeRoot treeRoot) { PdfStructureElement pdfStructureElement = new PdfStructureElement(treeRoot, PdfName.P); pdfStructureElement.setAttribute(PdfName.ACTUALTEXT, new PdfString(getContent())); return pdfStructureElement; }
@Override public PdfStructureElement toPdfStructureElement(PdfStructureElement parent) { PdfStructureElement pdfStructureElement = new PdfStructureElement(parent, PdfName.P); pdfStructureElement.setAttribute(PdfName.ACTUALTEXT, new PdfString(getContent())); return pdfStructureElement; }
public ByteArrayOutputStream doSign(byte[] pdf, Rectangle stampPos, int pageNmbrForStamp) throws IOException, DocumentException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Certificate[] chain = signCert.toArray(new Certificate[0]); PdfReader reader = new PdfReader(pdf); ByteArrayOutputStream byteOS = new ByteArrayOutputStream(); PdfStamper stp = PdfStamper.createSignature(reader, byteOS, '\0', null, true); PdfSignatureAppearance sap = stp.getSignatureAppearance(); if (stampPos != null) { sap.setVisibleSignature(new com.itextpdf.text.Rectangle(stampPos.x, stampPos.y, stampPos.width, stampPos.height), pageNmbrForStamp, null); sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION); sap.setAcro6Layers(true); } // Siganture Appearance PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); log.info("Creating signature with reason: " + ParamValidator.getInstance().getSignatureReason()); sap.setReason(ParamValidator.getInstance().getSignatureReason()); sap.setLocation("Ruhr-Universität Bochum"); Image i = Image.getInstance(getClass().getResource("/de/rub/dez6a3/jpdfsigner/resources/images/sign.png")); sap.setImage(i); sap.setCrypto((PrivateKey) signPrivKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED); dic.setReason(ParamValidator.getInstance().getSignatureReason()); dic.setLocation("Ruhr-Universität Bochum"); sap.setCryptoDictionary(dic); // preserve some space for the contents int contentEstimated = 15000; HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>(); exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2)); sap.preClose(exc); // make the digest InputStream data = sap.getRangeStream(); MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); byte buf[] = new byte[8192]; int n; while ((n = data.read(buf)) > 0) { messageDigest.update(buf, 0, n); } byte hash[] = messageDigest.digest(); Calendar cal = Calendar.getInstance(); // If we add a time stamp: TSAClient tsc = new TSAClientBouncyCastle("http://zeitstempel.dfn.de/"); // Create the signature PdfPKCS7 sgn; try { sgn = new PdfPKCS7((PrivateKey) signPrivKey, chain, null, "SHA1", null, false); byte sh[] = sgn.getAuthenticatedAttributeBytes(hash, cal, null); sgn.update(sh, 0, sh.length); byte[] encodedSig = sgn.getEncodedPKCS7(hash, cal, tsc, null); if (contentEstimated + 2 < encodedSig.length) { throw new DocumentException("Not enough space"); } byte[] paddedSig = new byte[contentEstimated]; System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length); // Replace the contents PdfDictionary dic2 = new PdfDictionary(); dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true)); sap.close(dic2); } catch (NoSuchProviderException ex) { ex.printStackTrace(); } return byteOS; }
@Override public void exportElement(JRPdfExporterContext exporterContext, JRGenericPrintElement element) { try { PdfWriter writer = exporterContext.getPdfWriter(); PdfIndirectObject swfRef; boolean newContext = !existingContexts.containsKey(exporterContext); if (newContext) { PdfDictionary extensions = new PdfDictionary(); PdfDictionary adobeExtension = new PdfDictionary(); adobeExtension.put(new PdfName("BaseVersion"), PdfWriter.PDF_VERSION_1_7); adobeExtension.put(new PdfName("ExtensionLevel"), new PdfNumber(3)); extensions.put(new PdfName("ADBE"), adobeExtension); writer.getExtraCatalog().put(new PdfName("Extensions"), extensions); byte[] swfData = getChartSwf(); PdfFileSpecification swfFile = PdfFileSpecification.fileEmbedded(writer, null, "Open Flash Chart", swfData); swfRef = writer.addToBody(swfFile); existingContexts.put(exporterContext, swfRef); } else { swfRef = (PdfIndirectObject) existingContexts.get(exporterContext); } Rectangle rect = new Rectangle(element.getX() + exporterContext.getOffsetX(), exporterContext.getExportedReport().getPageHeight() - element.getY() - exporterContext.getOffsetY(), element.getX() + exporterContext.getOffsetX() + element.getWidth(), exporterContext.getExportedReport().getPageHeight() - element.getY() - exporterContext.getOffsetY() - element.getHeight()); PdfAnnotation ann = new PdfAnnotation(writer, rect); ann.put(PdfName.SUBTYPE, new PdfName("RichMedia")); PdfDictionary settings = new PdfDictionary(); PdfDictionary activation = new PdfDictionary(); activation.put(new PdfName("Condition"), new PdfName("PV")); settings.put(new PdfName("Activation"), activation); ann.put(new PdfName("RichMediaSettings"), settings); PdfDictionary content = new PdfDictionary(); HashMap<String, PdfIndirectReference> assets = new HashMap<String, PdfIndirectReference>(); assets.put("map.swf", swfRef.getIndirectReference()); PdfDictionary assetsDictionary = PdfNameTree.writeTree(assets, writer); content.put(new PdfName("Assets"), assetsDictionary); PdfArray configurations = new PdfArray(); PdfDictionary configuration = new PdfDictionary(); PdfArray instances = new PdfArray(); PdfDictionary instance = new PdfDictionary(); instance.put(new PdfName("Subtype"), new PdfName("Flash")); PdfDictionary params = new PdfDictionary(); String chartData = ((ChartGenerator) element.getParameterValue(ChartGenerator.PARAMETER_CHART_GENERATOR)).generateChart(); String vars = "inline_data=" + chartData; params.put(new PdfName("FlashVars"), new PdfString(vars)); instance.put(new PdfName("Params"), params); instance.put(new PdfName("Asset"), swfRef.getIndirectReference()); PdfIndirectObject instanceRef = writer.addToBody(instance); instances.add(instanceRef.getIndirectReference()); configuration.put(new PdfName("Instances"), instances); PdfIndirectObject configurationRef = writer.addToBody(configuration); configurations.add(configurationRef.getIndirectReference()); content.put(new PdfName("Configurations"), configurations); ann.put(new PdfName("RichMediaContent"), content); writer.addAnnotation(ann); } catch (Exception e) { throw new RuntimeException(e); } }