001: /**
002: * Copyright (c) 2003-2005, 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.pdmodel.encryption;
031:
032: import java.security.Key;
033: import java.security.KeyStore;
034: import java.security.KeyStoreException;
035: import java.security.NoSuchAlgorithmException;
036: import java.security.UnrecoverableKeyException;
037: import java.security.cert.X509Certificate;
038: import java.util.Enumeration;
039:
040: /**
041: * This class holds necessary information to decrypt a PDF document
042: * protected by the public key security handler.
043: *
044: * To decrypt such a document, we need:
045: * <ul>
046: * <li>a valid X509 certificate which correspond to one of the recipient of the document</li>
047: * <li>the private key corresponding to this certificate
048: * <li>the password to decrypt the private key if necessary</li>
049: * </ul>
050: *
051: * Objects of this class can be used with the <code>openProtection</code> method of <code>PDDocument</code>.
052: *
053: * The following example shows how to decrypt a document using a PKCS#12 certificate
054: * (typically files with a pfx extension).
055: *
056: * <pre>
057: * PDDocument doc = PDDocument.load(document_path);
058: * KeyStore ks = KeyStore.getInstance("PKCS12");
059: * ks.load(new FileInputStream(certificate_path), password.toCharArray());
060: * PublicKeyDecryptionMaterial dm = new PublicKeyDecryptionMaterial(ks, null, password);
061: * doc.openProtection(dm);
062: * </pre>
063: *
064: * In this code sample certificate_path contains the path to the PKCS#12 certificate.
065: *
066: * @see org.pdfbox.pdmodel.PDDocument#openProtection(DecryptionMaterial)
067: *
068: * @author Benoit Guillon (benoit.guillon@snv.jussieu.fr)
069: * @version $Revision: 1.2 $
070: */
071:
072: public class PublicKeyDecryptionMaterial extends DecryptionMaterial {
073: private String password = null;
074: private KeyStore keyStore = null;
075: private String alias = null;
076:
077: /**
078: * Create a new public key decryption material.
079: *
080: * @param keystore The keystore were the private key and the certificate are
081: * @param a The alias of the private key and the certificate.
082: * If the keystore contains only 1 entry, this parameter can be left null.
083: * @param pwd The password to extract the private key from the keystore.
084: */
085:
086: public PublicKeyDecryptionMaterial(KeyStore keystore, String a,
087: String pwd) {
088: keyStore = keystore;
089: alias = a;
090: password = pwd;
091: }
092:
093: /**
094: * Returns the certificate contained in the keystore.
095: *
096: * @return The certificate that will be used to try to open the document.
097: *
098: * @throws KeyStoreException If there is an error accessing the certificate.
099: */
100:
101: public X509Certificate getCertificate() throws KeyStoreException {
102: if (keyStore.size() == 1) {
103: Enumeration aliases = keyStore.aliases();
104: String keyStoreAlias = (String) aliases.nextElement();
105: return (X509Certificate) keyStore
106: .getCertificate(keyStoreAlias);
107: } else {
108: if (keyStore.containsAlias(alias)) {
109: return (X509Certificate) keyStore.getCertificate(alias);
110: }
111: throw new KeyStoreException(
112: "the keystore does not contain the given alias");
113: }
114: }
115:
116: /**
117: * Returns the password given by the user and that will be used
118: * to open the private key.
119: *
120: * @return The password.
121: */
122: public String getPassword() {
123: return password;
124: }
125:
126: /**
127: * returns The private key that will be used to open the document protection.
128: * @return The private key.
129: * @throws KeyStoreException If there is an error accessing the key.
130: */
131: public Key getPrivateKey() throws KeyStoreException {
132: try {
133: if (keyStore.size() == 1) {
134: Enumeration aliases = keyStore.aliases();
135: String keyStoreAlias = (String) aliases.nextElement();
136: return keyStore.getKey(keyStoreAlias, password
137: .toCharArray());
138: } else {
139: if (keyStore.containsAlias(alias)) {
140: return keyStore.getKey(alias, password
141: .toCharArray());
142: }
143: throw new KeyStoreException(
144: "the keystore does not contain the given alias");
145: }
146: } catch (UnrecoverableKeyException ex) {
147: throw new KeyStoreException(
148: "the private key is not recoverable");
149: } catch (NoSuchAlgorithmException ex) {
150: throw new KeyStoreException(
151: "the algorithm necessary to recover the key is not available");
152: }
153: }
154: }
|