package org.icepdf.os.examples.signatures; /* * Copyright 2006-2017 ICEsoft Technologies Canada Corp. * * 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. */ import org.icepdf.core.exceptions.PDFException; import org.icepdf.core.exceptions.PDFSecurityException; import org.icepdf.core.pobjects.Document; import org.icepdf.core.pobjects.PDate; import org.icepdf.core.pobjects.acroform.InteractiveForm; import org.icepdf.core.pobjects.acroform.SignatureDictionary; import org.icepdf.core.pobjects.acroform.signature.SignatureValidator; import org.icepdf.core.pobjects.acroform.signature.exceptions.SignatureIntegrityException; import org.icepdf.core.pobjects.annotations.SignatureWidgetAnnotation; import org.icepdf.ri.util.FontPropertiesManager; import org.icepdf.ri.util.PropertiesManager; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.ResourceBundle; /** * The <code>SignatureVerification</code> class is an example of how to validate the signatures * associated with a document A file specified at the command line is opened and the signatures are * accessed and validated against the current state of the document. * * @since 6.1 */ public class SignatureVerification { static { // read/store the font cache. ResourceBundle messageBundle = ResourceBundle.getBundle( PropertiesManager.DEFAULT_MESSAGE_BUNDLE); PropertiesManager properties = new PropertiesManager(System.getProperties(), ResourceBundle.getBundle(PropertiesManager.DEFAULT_MESSAGE_BUNDLE)); new FontPropertiesManager(properties, System.getProperties(), messageBundle); } public static void main(String[] args) { // Get a file from the command line to open String filePath = args[0]; // start the capture new SignatureVerification().validateDocument(filePath); } public void validateDocument(String filePath) { // open the url Document document = new Document(); try { // open the file. document.setFile(filePath); // signatures can be found off the Catalog as InteractiveForms. InteractiveForm interactiveForm = document.getCatalog().getInteractiveForm(); if (interactiveForm != null) { ArrayList<SignatureWidgetAnnotation> signatureFields = interactiveForm.getSignatureFields(); // found some signatures! if (signatureFields != null) { // must be called in order to verify signatures cover full length of document. // signatures cover length of document, there could still be an issue with the signature // but we know the signature(s) cover all the bytes in the file. interactiveForm.isSignaturesCoverDocumentLength(); // validate each signature. for (SignatureWidgetAnnotation signatureWidgetAnnotation : signatureFields) { SignatureValidator signatureValidator = signatureWidgetAnnotation.getSignatureValidator(); try { // annotation summary SignatureVerification.printSignatureSummary(signatureWidgetAnnotation); // validate the signature and certificate. signatureValidator.validate(); // print out some important properties of the validator state. SignatureVerification.printValidationSummary(signatureValidator); } catch (SignatureIntegrityException e) { System.out.println("Signature failed to validate: " + signatureValidator.toString()); e.printStackTrace(); } } } } } catch (PDFException ex) { System.out.println("Error parsing PDF document " + ex); } catch (PDFSecurityException ex) { System.out.println("Error encryption not supported " + ex); } catch (FileNotFoundException ex) { System.out.println("Error file not found " + ex); } catch (IOException ex) { System.out.println("Error handling PDF document " + ex); } System.out.println(); } private static void printSignatureSummary(SignatureWidgetAnnotation signatureWidgetAnnotation) { SignatureDictionary signatureDictionary = signatureWidgetAnnotation.getSignatureDictionary(); String signingTime = new PDate(signatureWidgetAnnotation.getLibrary().getSecurityManager(), signatureDictionary.getDate()).toString(); System.out.println("General Info:"); System.out.println(" Signing time: " + signingTime); System.out.println(" Reason: " + signatureDictionary.getReason()); System.out.println(" Location: " + signatureDictionary.getLocation()); } /** * Print out some summary data of the validator results. * * @param signatureValidator validator to show properties data. */ private static void printValidationSummary(SignatureValidator signatureValidator) { System.out.println("Singer Info:"); if (signatureValidator.isCertificateChainTrusted()) { System.out.println(" Path validation checks were successful"); } else { System.out.println(" Path validation checks were unsuccessful"); } if (!signatureValidator.isCertificateChainTrusted() || signatureValidator.isRevocation()) { System.out.println(" Revocation checking was not performed"); } else { System.out.println(" Signer's certificate is valid and has not been revoked"); } System.out.println("Validity Summary:"); if (!signatureValidator.isSignedDataModified() && !signatureValidator.isDocumentDataModified()) { System.out.println(" Document has not been modified since it was signed"); } else if (!signatureValidator.isSignedDataModified() && signatureValidator.isDocumentDataModified() && signatureValidator.isSignaturesCoverDocumentLength()) { System.out.println(" This version of the document is unaltered but subsequent changes have been made"); } else if (!signatureValidator.isSignaturesCoverDocumentLength()) { System.out.println(" Document has been altered or corrupted sing it was singed"); } if (!signatureValidator.isCertificateDateValid()) { System.out.println(" Signers certificate has expired"); } if (signatureValidator.isEmbeddedTimeStamp()) { System.out.println(" Signature included an embedded timestamp but it could not be validated"); } else { System.out.println(" Signing time is from the clock on this signer's computer"); } if (signatureValidator.isSelfSigned()) { System.out.println(" Document is self signed"); } System.out.println(); } }