1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.pdfbox.pdmodel.encryption; 19 20 import java.security.Key; 21 import java.security.KeyStore; 22 import java.security.KeyStoreException; 23 import java.security.NoSuchAlgorithmException; 24 import java.security.UnrecoverableKeyException; 25 import java.security.cert.X509Certificate; 26 import java.util.Enumeration; 27 28 /** 29 * This class holds necessary information to decrypt a PDF document 30 * protected by the public key security handler. 31 * 32 * To decrypt such a document, we need: 33 * <ul> 34 * <li>a valid X509 certificate which correspond to one of the recipient of the document</li> 35 * <li>the private key corresponding to this certificate 36 * <li>the password to decrypt the private key if necessary</li> 37 * </ul> 38 * 39 * Objects of this class can be used with the <code>openProtection</code> method of <code>PDDocument</code>. 40 * 41 * The following example shows how to decrypt a document using a PKCS#12 certificate 42 * (typically files with a pfx extension). 43 * 44 * <pre> 45 * PDDocument doc = PDDocument.load(document_path); 46 * KeyStore ks = KeyStore.getInstance("PKCS12"); 47 * ks.load(new FileInputStream(certificate_path), password.toCharArray()); 48 * PublicKeyDecryptionMaterial dm = new PublicKeyDecryptionMaterial(ks, null, password); 49 * doc.openProtection(dm); 50 * </pre> 51 * 52 * In this code sample certificate_path contains the path to the PKCS#12 certificate. 53 * 54 * @see org.apache.pdfbox.pdmodel.PDDocument#openProtection(DecryptionMaterial) 55 * 56 * @author Benoit Guillon (benoit.guillon@snv.jussieu.fr) 57 * @version $Revision: 1.2 $ 58 */ 59 60 public class PublicKeyDecryptionMaterial extends DecryptionMaterial 61 { 62 private String password = null; 63 private KeyStore keyStore = null; 64 private String alias = null; 65 66 /** 67 * Create a new public key decryption material. 68 * 69 * @param keystore The keystore were the private key and the certificate are 70 * @param a The alias of the private key and the certificate. 71 * If the keystore contains only 1 entry, this parameter can be left null. 72 * @param pwd The password to extract the private key from the keystore. 73 */ 74 75 public PublicKeyDecryptionMaterial(KeyStore keystore, String a, String pwd) 76 { 77 keyStore = keystore; 78 alias = a; 79 password = pwd; 80 } 81 82 83 /** 84 * Returns the certificate contained in the keystore. 85 * 86 * @return The certificate that will be used to try to open the document. 87 * 88 * @throws KeyStoreException If there is an error accessing the certificate. 89 */ 90 91 public X509Certificate getCertificate() throws KeyStoreException 92 { 93 if(keyStore.size() == 1) 94 { 95 Enumeration aliases = keyStore.aliases(); 96 String keyStoreAlias = (String)aliases.nextElement(); 97 return (X509Certificate)keyStore.getCertificate(keyStoreAlias); 98 } 99 else 100 { 101 if(keyStore.containsAlias(alias)) 102 { 103 return (X509Certificate)keyStore.getCertificate(alias); 104 } 105 throw new KeyStoreException("the keystore does not contain the given alias"); 106 } 107 } 108 109 /** 110 * Returns the password given by the user and that will be used 111 * to open the private key. 112 * 113 * @return The password. 114 */ 115 public String getPassword() 116 { 117 return password; 118 } 119 120 /** 121 * returns The private key that will be used to open the document protection. 122 * @return The private key. 123 * @throws KeyStoreException If there is an error accessing the key. 124 */ 125 public Key getPrivateKey() throws KeyStoreException 126 { 127 try 128 { 129 if(keyStore.size() == 1) 130 { 131 Enumeration aliases = keyStore.aliases(); 132 String keyStoreAlias = (String)aliases.nextElement(); 133 return keyStore.getKey(keyStoreAlias, password.toCharArray()); 134 } 135 else 136 { 137 if(keyStore.containsAlias(alias)) 138 { 139 return keyStore.getKey(alias, password.toCharArray()); 140 } 141 throw new KeyStoreException("the keystore does not contain the given alias"); 142 } 143 } 144 catch(UnrecoverableKeyException ex) 145 { 146 throw new KeyStoreException("the private key is not recoverable"); 147 } 148 catch(NoSuchAlgorithmException ex) 149 { 150 throw new KeyStoreException("the algorithm necessary to recover the key is not available"); 151 } 152 } 153 }