Author: tilman Date: Tue Mar 6 19:09:09 2018 New Revision: 1826024 URL: http://svn.apache.org/viewvc?rev=1826024&view=rev Log: PDFBOX-1848: add timestamping, by Alexis Suter
Added: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java - copied, changed from r1826022, pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimestampBase.java (with props) Copied: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java (from r1826022, pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java) URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java?p2=pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java&p1=pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java&r1=1826022&r2=1826024&rev=1826024&view=diff ============================================================================== --- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java (original) +++ pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimeStamp.java Tue Mar 6 19:09:09 2018 @@ -20,42 +20,30 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; +import java.net.URL; import java.security.GeneralSecurityException; -import java.security.NoSuchAlgorithmException; +import java.security.MessageDigest; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface; /** - * An example for timestamp-singing a PDF for PADeS-Specification. The document will be extended by - * a signed TimeStamp (another kind of signature) (Signed TimeStamp and Hash-Value of the document - * are signed by a Time Stamp Authority (TSA)). + * An example for timestamp-singing a PDF for PADeS-Specification. The document will only be + * extended by a signed Timestamp (Signed Timestamp and Hash-Value of the document are signed by a + * Time Stamp Authority (TSA)). * - * @author Thomas Chojecki - * @author Vakhtang Koroghlishvili - * @author John Hewson * @author Alexis Suter */ -public class CreateSignedTimeStamp implements SignatureInterface +public class CreateSignedTimeStamp extends CreateSignedTimestampBase { - private static final Log LOG = LogFactory.getLog(CreateSignedTimeStamp.class); - - private final String tsaUrl; /** * Initialize the signed timestamp creator - * - * @param tsaUrl The url where TS-Request will be done. */ - public CreateSignedTimeStamp(String tsaUrl) + public CreateSignedTimeStamp() { - this.tsaUrl = tsaUrl; } /** @@ -66,7 +54,7 @@ public class CreateSignedTimeStamp imple */ public void signDetached(File file) throws IOException { - signDetached(file, file); + signDetached(file, file, null); } /** @@ -78,28 +66,37 @@ public class CreateSignedTimeStamp imple */ public void signDetached(File inFile, File outFile) throws IOException { + signDetached(inFile, outFile, null); + } + + /** + * Signs the given PDF file. + * + * @param inFile input PDF file + * @param outFile output PDF file + * @param tsaClient optional TSA client + * @throws IOException if the input file could not be read + */ + public void signDetached(File inFile, File outFile, TSAClient tsaClient) throws IOException + { if (inFile == null || !inFile.exists()) { throw new FileNotFoundException("Document for signing does not exist"); } + FileOutputStream fos = new FileOutputStream(outFile); + // sign - try (PDDocument doc = PDDocument.load(inFile); - FileOutputStream fos = new FileOutputStream(outFile)) - { - signDetached(doc, fos); - } + PDDocument doc = PDDocument.load(inFile); + signDetached(doc, fos, tsaClient); + doc.close(); } - /** - * Prepares the TimeStamp-Signature and starts the saving-process. - * - * @param document given Pdf - * @param output Where the file will be written - * @throws IOException - */ - public void signDetached(PDDocument document, OutputStream output) throws IOException + public void signDetached(PDDocument document, OutputStream output, TSAClient tsaClient) + throws IOException { + setTsaClient(tsaClient); + int accessPermissions = SigUtils.getMDPPermission(document); if (accessPermissions == 1) { @@ -113,10 +110,11 @@ public class CreateSignedTimeStamp imple signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); signature.setSubFilter(COSName.getPDFName("ETSI.RFC3161")); - // No certification allowed because /Reference not allowed in signature directory - // see ETSI EN 319 142-1 Part 1 and ETSI TS 102 778-4 - // http://www.etsi.org/deliver/etsi_en%5C319100_319199%5C31914201%5C01.01.00_30%5Cen_31914201v010100v.pdf - // http://www.etsi.org/deliver/etsi_ts/102700_102799/10277804/01.01.01_60/ts_10277804v010101p.pdf + // Optional: certify + if (accessPermissions == 0) + { + SigUtils.setMDPPermission(document, signature, 2); + } // register signature dictionary and sign interface document.addSignature(signature, this); @@ -125,22 +123,6 @@ public class CreateSignedTimeStamp imple document.saveIncremental(output); } - @Override - public byte[] sign(InputStream content) throws IOException - { - ValidationTimeStamp validation; - try - { - validation = new ValidationTimeStamp(tsaUrl); - return validation.getTimeStampToken(content); - } - catch (NoSuchAlgorithmException e) - { - LOG.error("Hashing-Algorithm not found for TimeStamping", e); - } - return new byte[] {}; - } - public static void main(String[] args) throws IOException, GeneralSecurityException { if (args.length != 3) @@ -160,21 +142,29 @@ public class CreateSignedTimeStamp imple System.exit(1); } + // TSA client + TSAClient tsaClient = null; + if (tsaUrl != null) + { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + tsaClient = new TSAClient(new URL(tsaUrl), null, null, digest); + } + // sign PDF - CreateSignedTimeStamp signing = new CreateSignedTimeStamp(tsaUrl); + CreateSignedTimeStamp signing = new CreateSignedTimeStamp(); File inFile = new File(args[0]); String name = inFile.getName(); String substring = name.substring(0, name.lastIndexOf('.')); File outFile = new File(inFile.getParent(), substring + "_timestamped.pdf"); - signing.signDetached(inFile, outFile); + signing.signDetached(inFile, outFile, tsaClient); } private static void usage() { System.err.println("usage: java " + CreateSignedTimeStamp.class.getName() + " " - + "<pdf_to_sign>\n" + "mandatory options:\n" + + "<pdf_to_sign>\n" + "options:\n" + " -tsa <url> sign timestamp using the given TSA server\n"); } } Added: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimestampBase.java URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimestampBase.java?rev=1826024&view=auto ============================================================================== --- pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimestampBase.java (added) +++ pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimestampBase.java Tue Mar 6 19:09:09 2018 @@ -0,0 +1,56 @@ +/* + * Copyright 2015 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.pdfbox.examples.signature; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.pdfbox.io.IOUtils; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface; + +public abstract class CreateSignedTimestampBase implements SignatureInterface +{ + private TSAClient tsaClient; + + public void setTsaClient(TSAClient tsaClient) + { + this.tsaClient = tsaClient; + } + + public TSAClient getTsaClient() + { + return tsaClient; + } + + /** + * SignatureInterface implementation. + * + * This method will be called from inside of the pdfbox and create the PKCS #7 signature. The given InputStream + * contains the bytes that are given by the byte range. + * + * This method is for internal use only. + * + * Use your favorite cryptographic library to implement PKCS #7 signature creation. + * + * @throws IOException + */ + @Override + public byte[] sign(InputStream content) throws IOException + { + return getTsaClient().getTimeStampToken(IOUtils.toByteArray(content)); + } +} Propchange: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignedTimestampBase.java ------------------------------------------------------------------------------ svn:eol-style = native