001: /**
002: * Copyright (c) 2003, www.pdfbox.org
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * 1. Redistributions of source code must retain the above copyright notice,
009: * this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: * 3. Neither the name of pdfbox; nor the names of its
014: * contributors may be used to endorse or promote products derived from this
015: * software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
021: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: *
028: * http://www.pdfbox.org
029: *
030: */package org.pdfbox.examples.signature;
031:
032: import java.io.ByteArrayInputStream;
033: import java.io.IOException;
034:
035: import java.security.cert.CertificateFactory;
036:
037: import java.util.Collection;
038:
039: import org.pdfbox.cos.COSArray;
040: import org.pdfbox.cos.COSDictionary;
041: import org.pdfbox.cos.COSName;
042: import org.pdfbox.cos.COSString;
043:
044: import org.pdfbox.pdmodel.PDDocument;
045:
046: /**
047: * This will read a document from the filesystem, decrypt it and do something with the signature.
048: *
049: * usage: java org.pdfbox.examples.signature.ShowSignature <password> <inputfile>
050: *
051: *
052: * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
053: * @version $Revision: 1.9 $
054: */
055: public class ShowSignature {
056:
057: /**
058: * This is the entry point for the application.
059: *
060: * @param args The command-line arguments.
061: *
062: * @throws Exception If there is an error reading the file.
063: */
064: public static void main(String[] args) throws Exception {
065: ShowSignature show = new ShowSignature();
066: show.showSignature(args);
067: }
068:
069: private void showSignature(String[] args) throws Exception {
070: if (args.length != 2) {
071: usage();
072: } else {
073: String password = args[0];
074: String infile = args[1];
075: PDDocument document = null;
076: try {
077: document = PDDocument.load(infile);
078:
079: if (document.isEncrypted()) {
080: document.decrypt(password);
081: } else {
082: System.err
083: .println("Warning: Document is not encrypted.");
084: }
085:
086: COSDictionary trailer = document.getDocument()
087: .getTrailer();
088: COSDictionary root = (COSDictionary) trailer
089: .getDictionaryObject(COSName.ROOT);
090: COSDictionary acroForm = (COSDictionary) root
091: .getDictionaryObject(COSName
092: .getPDFName("AcroForm"));
093: COSArray fields = (COSArray) acroForm
094: .getDictionaryObject(COSName
095: .getPDFName("Fields"));
096: for (int i = 0; i < fields.size(); i++) {
097: COSDictionary field = (COSDictionary) fields
098: .getObject(i);
099: String type = field.getNameAsString("FT");
100: if ("Sig".equals(type)) {
101: COSDictionary cert = (COSDictionary) field
102: .getDictionaryObject(COSName
103: .getPDFName("V"));
104: if (cert != null) {
105: System.out.println("Certificate found");
106: System.out.println("Name="
107: + cert.getDictionaryObject(COSName
108: .getPDFName("Name")));
109: System.out.println("Modified="
110: + cert.getDictionaryObject(COSName
111: .getPDFName("M")));
112: COSName subFilter = (COSName) cert
113: .getDictionaryObject(COSName
114: .getPDFName("SubFilter"));
115: if (subFilter != null) {
116: if (subFilter.getName().equals(
117: "adbe.x509.rsa_sha1")) {
118: COSString certString = (COSString) cert
119: .getDictionaryObject(COSName
120: .getPDFName("Cert"));
121: byte[] certData = certString
122: .getBytes();
123: CertificateFactory factory = CertificateFactory
124: .getInstance("X.509");
125: ByteArrayInputStream certStream = new ByteArrayInputStream(
126: certData);
127: Collection certs = factory
128: .generateCertificates(certStream);
129: System.out
130: .println("certs=" + certs);
131: } else if (subFilter.getName().equals(
132: "adbe.pkcs7.sha1")) {
133: COSString certString = (COSString) cert
134: .getDictionaryObject(COSName
135: .getPDFName("Contents"));
136: byte[] certData = certString
137: .getBytes();
138: CertificateFactory factory = CertificateFactory
139: .getInstance("X.509");
140: ByteArrayInputStream certStream = new ByteArrayInputStream(
141: certData);
142: Collection certs = factory
143: .generateCertificates(certStream);
144: System.out
145: .println("certs=" + certs);
146: } else {
147: System.err
148: .println("Unknown certificate type:"
149: + subFilter);
150: }
151: } else {
152: throw new IOException(
153: "Missing subfilter for cert dictionary");
154: }
155: } else {
156: System.out
157: .println("Signature found, but no certificate");
158: }
159: }
160: }
161: } finally {
162: if (document != null) {
163: document.close();
164: }
165: }
166: }
167: }
168:
169: /**
170: * This will print a usage message.
171: */
172: private static void usage() {
173: System.err
174: .println("usage: java org.pdfbox.examples.signature.ShowSignature "
175: + "<password> <inputfile>");
176: }
177:
178: }
|