Author: jahewson Date: Wed Mar 12 02:57:28 2014 New Revision: 1576570 URL: http://svn.apache.org/r1576570 Log: PDFBOX-1973: Replaced BadSecurityHandlerException with IOException
Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlerFactory.java - copied, changed from r1576483, pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlersManager.java Removed: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/BadSecurityHandlerException.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlersManager.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/NonSequentialPDFParser.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeyProtectionPolicy.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardProtectionPolicy.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/NonSequentialPDFParser.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/NonSequentialPDFParser.java?rev=1576570&r1=1576569&r2=1576570&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/NonSequentialPDFParser.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/NonSequentialPDFParser.java Wed Mar 12 02:57:28 2014 @@ -64,7 +64,7 @@ import org.apache.pdfbox.pdmodel.encrypt import org.apache.pdfbox.pdmodel.encryption.PDEncryptionDictionary; import org.apache.pdfbox.pdmodel.encryption.PublicKeyDecryptionMaterial; import org.apache.pdfbox.pdmodel.encryption.SecurityHandler; -import org.apache.pdfbox.pdmodel.encryption.SecurityHandlersManager; +import org.apache.pdfbox.pdmodel.encryption.SecurityHandlerFactory; import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial; import org.apache.pdfbox.persistence.util.COSObjectKey; @@ -416,7 +416,7 @@ public class NonSequentialPDFParser exte { PDEncryptionDictionary encParameters = new PDEncryptionDictionary(document.getEncryptionDictionary()); - DecryptionMaterial decryptionMaterial = null; + DecryptionMaterial decryptionMaterial; if (keyStoreFilename != null) { KeyStore ks = KeyStore.getInstance("PKCS12"); @@ -429,7 +429,11 @@ public class NonSequentialPDFParser exte decryptionMaterial = new StandardDecryptionMaterial(password); } - securityHandler = SecurityHandlersManager.getInstance().getSecurityHandler(encParameters.getFilter()); + securityHandler = SecurityHandlerFactory.INSTANCE.newSecurityHandler(encParameters.getFilter()); + if (securityHandler == null) + { + throw new IOException("No security handler for filter " + encParameters.getFilter()); + } securityHandler.prepareForDecryption(encParameters, document.getDocumentID(), decryptionMaterial); AccessPermission permission = securityHandler.getCurrentAccessPermission(); Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java?rev=1576570&r1=1576569&r2=1576570&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java Wed Mar 12 02:57:28 2014 @@ -51,14 +51,14 @@ import org.apache.pdfbox.pdmodel.common. import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.pdmodel.encryption.AccessPermission; -import org.apache.pdfbox.pdmodel.encryption.BadSecurityHandlerException; import org.apache.pdfbox.pdmodel.encryption.DecryptionMaterial; import org.apache.pdfbox.pdmodel.encryption.PDEncryptionDictionary; import org.apache.pdfbox.pdmodel.encryption.ProtectionPolicy; import org.apache.pdfbox.pdmodel.encryption.SecurityHandler; -import org.apache.pdfbox.pdmodel.encryption.SecurityHandlersManager; +import org.apache.pdfbox.pdmodel.encryption.SecurityHandlerFactory; import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial; import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy; +import org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; @@ -857,7 +857,9 @@ public class PDDocument implements Close } /** - * This will decrypt a document. This method is provided for compatibility reasons only. User should use the new + * This will decrypt a document. + * + * @deprecated This method is provided for compatibility reasons only. User should use the new * security layer instead and the openProtection method especially. * * @param password Either the user or owner password. @@ -865,46 +867,32 @@ public class PDDocument implements Close * @throws CryptographyException If there is an error decrypting the document. * @throws IOException If there is an error getting the stream data. * @throws InvalidPasswordException If the password is not a user or owner password. - * */ + @Deprecated public void decrypt(String password) throws CryptographyException, IOException, InvalidPasswordException { - try - { - StandardDecryptionMaterial m = new StandardDecryptionMaterial(password); - this.openProtection(m); - document.dereferenceObjectStreams(); - } - catch (BadSecurityHandlerException e) - { - throw new CryptographyException(e); - } + StandardDecryptionMaterial m = new StandardDecryptionMaterial(password); + openProtection(m); + document.dereferenceObjectStreams(); } /** * This will <b>mark</b> a document to be encrypted. The actual encryption will occur when the document is saved. - * This method is provided for compatibility reasons only. User should use the new security layer instead and the + * + * @deprecated This method is provided for compatibility reasons only. User should use the new security layer instead and the * openProtection method especially. * * @param ownerPassword The owner password to encrypt the document. * @param userPassword The user password to encrypt the document. - * - * @throws CryptographyException If an error occurs during encryption. + * @throws IOException If there is an error accessing the data. - * */ - public void encrypt(String ownerPassword, String userPassword) throws CryptographyException, IOException + @Deprecated + public void encrypt(String ownerPassword, String userPassword) + throws IOException { - try - { - StandardProtectionPolicy policy = new StandardProtectionPolicy(ownerPassword, userPassword, - new AccessPermission()); - this.protect(policy); - } - catch (BadSecurityHandlerException e) - { - throw new CryptographyException(e); - } + securityHandler = new StandardSecurityHandler( + new StandardProtectionPolicy(ownerPassword, userPassword, new AccessPermission())); } /** @@ -1348,18 +1336,19 @@ public class PDDocument implements Close /** * Protects the document with the protection policy pp. The document content will be really encrypted when it will * be saved. This method only marks the document for encryption. - * + * * @see org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy * @see org.apache.pdfbox.pdmodel.encryption.PublicKeyProtectionPolicy * - * @param pp The protection policy. - * - * @throws BadSecurityHandlerException If there is an error during protection. + * @param policy The protection policy. */ - public void protect(ProtectionPolicy pp) throws BadSecurityHandlerException + public void protect(ProtectionPolicy policy) throws IOException { - SecurityHandler handler = SecurityHandlersManager.getInstance().getSecurityHandler(pp); - securityHandler = handler; + securityHandler = SecurityHandlerFactory.INSTANCE.newSecurityHandlerForPolicy(policy); + if (securityHandler == null) + { + throw new IOException("No security handler for policy " + policy); + } } /** @@ -1368,26 +1357,30 @@ public class PDDocument implements Close * @see org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial * @see org.apache.pdfbox.pdmodel.encryption.PublicKeyDecryptionMaterial * - * @param pm The decryption material (password or certificate). - * - * @throws BadSecurityHandlerException If there is an error during decryption. + * @param decryptionMaterial The decryption material (password or certificate). + * * @throws IOException If there is an error reading cryptographic information. * @throws CryptographyException If there is an error during decryption. */ - public void openProtection(DecryptionMaterial pm) throws BadSecurityHandlerException, IOException, - CryptographyException + public void openProtection(DecryptionMaterial decryptionMaterial) + throws IOException, CryptographyException { - PDEncryptionDictionary dict = this.getEncryptionDictionary(); - if (dict.getFilter() != null) + PDEncryptionDictionary encryption = getEncryptionDictionary(); + if (encryption.getFilter() != null) { - securityHandler = SecurityHandlersManager.getInstance().getSecurityHandler(dict.getFilter()); - securityHandler.decryptDocument(this, pm); + securityHandler = SecurityHandlerFactory.INSTANCE.newSecurityHandler(encryption.getFilter()); + if (securityHandler == null) + { + throw new IOException("No security handler for filter " + encryption.getFilter()); + } + + securityHandler.decryptDocument(this, decryptionMaterial); document.dereferenceObjectStreams(); document.setEncryptionDictionary(null); } else { - throw new RuntimeException("This document does not need to be decrypted"); + throw new IOException("The document is not encrypted"); } } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeyProtectionPolicy.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeyProtectionPolicy.java?rev=1576570&r1=1576569&r2=1576570&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeyProtectionPolicy.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeyProtectionPolicy.java Wed Mar 12 02:57:28 2014 @@ -20,11 +20,10 @@ package org.apache.pdfbox.pdmodel.encryp import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; /** - * This class represents the protection policy to use to protect - * a document with the public key security handler as described - * in the PDF specification 1.6 p104. + * The protection policy to use to protect a document with the public key security handler. * * PDF documents are encrypted so that they can be decrypted by * one or more recipients. Each recipient have its own access permission. @@ -53,73 +52,55 @@ import java.util.Iterator; * doc.save(out); * </pre> * - * * @see org.apache.pdfbox.pdmodel.PDDocument#protect(ProtectionPolicy) * @see AccessPermission * @see PublicKeyRecipient - * * @author Benoit Guillon (benoit.guil...@snv.jussieu.fr) - * - * @version $Revision: 1.2 $ */ -public class PublicKeyProtectionPolicy extends ProtectionPolicy +public final class PublicKeyProtectionPolicy extends ProtectionPolicy { - - /** - * The list of recipients. - */ - private ArrayList recipients = null; - - /** - * The X509 certificate used to decrypt the current document. - */ + public final List<PublicKeyRecipient> recipients = new ArrayList<PublicKeyRecipient>(); private X509Certificate decryptionCertificate; /** - * Constructor for encryption. Just creates an empty recipients list. + * Creates a new PublicKeyProtectionPolicy with an empty recipients list. */ public PublicKeyProtectionPolicy() { - recipients = new ArrayList(); } /** * Adds a new recipient to the recipients list. - * - * @param r A new recipient. + * @param recipient A new recipient. */ - public void addRecipient(PublicKeyRecipient r) + public void addRecipient(PublicKeyRecipient recipient) { - recipients.add(r); + recipients.add(recipient); } /** * Removes a recipient from the recipients list. - * - * @param r The recipient to remove. - * + * @param recipient The recipient to remove. * @return true If a recipient was found and removed. */ - public boolean removeRecipient(PublicKeyRecipient r) + public boolean removeRecipient(PublicKeyRecipient recipient) { - return recipients.remove(r); + return recipients.remove(recipient); } /** - * Returns an iterator to browse the list of recipients. Object - * found in this iterator are <code>PublicKeyRecipient</code>. - * + * Returns an iterator to browse the list of recipients. + * Object found in this iterator are <code>PublicKeyRecipient</code>. * @return The recipients list iterator. */ - public Iterator getRecipientsIterator() + public Iterator<PublicKeyRecipient> getRecipientsIterator() { return recipients.iterator(); } /** - * Getter of the property <tt>decryptionCertificate</tt>. - * - * @return Returns the decryptionCertificate. + * Returns the decryption certificate. + * @return the decryption certificate */ public X509Certificate getDecryptionCertificate() { @@ -127,21 +108,19 @@ public class PublicKeyProtectionPolicy e } /** - * Setter of the property <tt>decryptionCertificate</tt>. - * - * @param aDecryptionCertificate The decryption certificate to set. + * Sets the the decryption certificate + * @param decryptionCertificate the new decryption certificate. */ - public void setDecryptionCertificate(X509Certificate aDecryptionCertificate) + public void setDecryptionCertificate(X509Certificate decryptionCertificate) { - this.decryptionCertificate = aDecryptionCertificate; + this.decryptionCertificate = decryptionCertificate; } /** - * Returns the number of recipients. - * - * @return The number of recipients. + * Returns the number of recipients + * @return the number of recipients */ - public int getRecipientsNumber() + public int getNumberOfRecipients() { return recipients.size(); } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java?rev=1576570&r1=1576569&r2=1576570&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java Wed Mar 12 02:57:28 2014 @@ -67,22 +67,14 @@ import org.apache.pdfbox.exceptions.Cryp import org.apache.pdfbox.pdmodel.PDDocument; /** - * This class implements the public key security handler - * described in the PDF specification. - * - * [PDF 1.6: p 104] + * This class implements the public key security handler described in the PDF specification. * * @see PublicKeyProtectionPolicy to see how to protect document with this security handler. - * - * @author Benoit Guillon (benoit.guil...@snv.jussieu.fr) - * @version $Revision: 1.3 $ + * @author Benoit Guillon */ public class PublicKeySecurityHandler extends SecurityHandler { - - /** - * The filter name. - */ + /** The filter name. */ public static final String FILTER = "Adobe.PubSec"; private static final String SUBFILTER = "adbe.pkcs7.s4"; @@ -274,7 +266,7 @@ public class PublicKeySecurityHandler ex dictionary.setVersion(2); dictionary.setSubFilter(SUBFILTER); - byte[][] recipientsField = new byte[policy.getRecipientsNumber()][]; + byte[][] recipientsField = new byte[policy.getNumberOfRecipients()][]; // create the 20 bytes seed @@ -288,7 +280,7 @@ public class PublicKeySecurityHandler ex catch (NoSuchAlgorithmException e) { // should never happen - throw new RuntimeException("Could not find a suitable javax.crypto provider", e); + throw new RuntimeException(e); } key.init(192, new SecureRandom()); @@ -394,12 +386,12 @@ public class PublicKeySecurityHandler ex } catch (NoSuchAlgorithmException e) { - // should never happen + // should never happen, if this happens throw IOException instead throw new RuntimeException("Could not find a suitable javax.crypto provider", e); } catch (NoSuchPaddingException e) { - // should never happen + // should never happen, if this happens throw IOException instead throw new RuntimeException("Could not find a suitable javax.crypto provider", e); } @@ -445,12 +437,12 @@ public class PublicKeySecurityHandler ex } catch (NoSuchAlgorithmException e) { - // should never happen + // should never happen, if this happens throw IOException instead throw new RuntimeException("Could not find a suitable javax.crypto provider", e); } catch (NoSuchPaddingException e) { - // should never happen + // should never happen, if this happens throw IOException instead throw new RuntimeException("Could not find a suitable javax.crypto provider", e); } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java?rev=1576570&r1=1576569&r2=1576570&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java Wed Mar 12 02:57:28 2014 @@ -52,68 +52,43 @@ import org.apache.pdfbox.exceptions.Cryp import org.apache.pdfbox.pdmodel.PDDocument; /** - * This class represents a security handler as described in the PDF specifications. + * A security handler as described in the PDF specifications. * A security handler is responsible of documents protection. * - * @author <a href="mailto:b...@benlitchfield.com">Ben Litchfield</a> - * @author Benoit Guillon (benoit.guil...@snv.jussieu.fr) - * + * @author Ben Litchfield + * @author Benoit Guillon */ - public abstract class SecurityHandler { - - /** - * CONSTANTS. - */ - private static final int DEFAULT_KEY_LENGTH = 40; - /* - * See 7.6.2, page 58, PDF 32000-1:2008 - */ + // see 7.6.2, page 58, PDF 32000-1:2008 private static final byte[] AES_SALT = { (byte) 0x73, (byte) 0x41, (byte) 0x6c, (byte) 0x54 }; - /** - * The value of V field of the Encryption dictionary. - */ + /** The value of V field of the Encryption dictionary. */ protected int version; - /** - * The length of the secret key used to encrypt the document. - */ + /** The length of the secret key used to encrypt the document. */ protected int keyLength = DEFAULT_KEY_LENGTH; - /** - * The encryption key that will used to encrypt / decrypt. - */ + /** The encryption key that will used to encrypt / decrypt.*/ protected byte[] encryptionKey; - /** - * The document whose security is handled by this security handler. - */ - + /** The document whose security is handled by this security handler.*/ protected PDDocument document; - /** - * The RC4 implementation used for cryptographic functions. - */ + /** The RC4 implementation used for cryptographic functions. */ protected ARCFour rc4 = new ARCFour(); - private Set<COSBase> objects = new HashSet<COSBase>(); + private final Set<COSBase> objects = new HashSet<COSBase>(); + private final Set<COSDictionary> potentialSignatures = new HashSet<COSDictionary>(); - private Set<COSDictionary> potentialSignatures = new HashSet<COSDictionary>(); - - /** - * If true, AES will be used. - */ - private boolean aes; + private boolean useAES; /** * The access permission granted to the current user for the document. These * permissions are computed during decryption and are in read only mode. */ - protected AccessPermission currentAccessPermission = null; /** @@ -247,7 +222,7 @@ public abstract class SecurityHandler public void encryptData(long objectNumber, long genNumber, InputStream data, OutputStream output, boolean decrypt) throws CryptographyException, IOException { - if (aes && !decrypt) + if (useAES && !decrypt) { throw new IllegalArgumentException("AES encryption is not yet implemented."); } @@ -268,7 +243,7 @@ public abstract class SecurityHandler // step 3 MessageDigest md = MessageDigests.getMD5(); md.update(newKey); - if (aes) + if (useAES) { md.update(AES_SALT); } @@ -279,7 +254,7 @@ public abstract class SecurityHandler byte[] finalKey = new byte[length]; System.arraycopy(digestedKey, 0, finalKey, 0, length); - if (aes) + if (useAES) { byte[] iv = new byte[16]; @@ -295,7 +270,7 @@ public abstract class SecurityHandler catch (NoSuchAlgorithmException e) { // should never happen - throw new RuntimeException("Could not find a suitable javax.crypto provider", e); + throw new RuntimeException(e); } SecretKey aesKey = new SecretKeySpec(finalKey, "AES"); @@ -531,7 +506,7 @@ public abstract class SecurityHandler */ public boolean isAES() { - return aes; + return useAES; } /** @@ -542,6 +517,6 @@ public abstract class SecurityHandler */ public void setAES(boolean aesValue) { - aes = aesValue; + useAES = aesValue; } } Copied: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlerFactory.java (from r1576483, pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlersManager.java) URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlerFactory.java?p2=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlerFactory.java&p1=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlersManager.java&r1=1576483&r2=1576570&rev=1576570&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlersManager.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandlerFactory.java Wed Mar 12 02:57:28 2014 @@ -18,206 +18,157 @@ package org.apache.pdfbox.pdmodel.encryption; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.security.Security; -import java.util.Hashtable; +import java.util.HashMap; +import java.util.Map; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** - * This class manages security handlers for the application. It follows the singleton pattern. - * To be usable, security managers must be registered in it. Security managers are retrieved by - * the application when necessary. - * - * @author Benoit Guillon (benoit.guil...@snv.jussieu.fr) - * - * @version $Revision: 1.3 $ + * Manages security handlers for the application. + * It follows the singleton pattern. + * To be usable, security managers must be registered in it. + * Security managers are retrieved by the application when necessary. * + * @author Benoit Guillon */ -public class SecurityHandlersManager +public class SecurityHandlerFactory { + /** Singleton instance */ + public static SecurityHandlerFactory INSTANCE = new SecurityHandlerFactory(); - /** - * The unique instance of this manager. - */ - private static SecurityHandlersManager instance; + static + { + Security.addProvider(new BouncyCastleProvider()); + } - /** - * hashtable used to index handlers regarding their name. - * Basically this will be used when opening an encrypted - * document to find the appropriate security handler to handle - * security features of the document. - */ - private Hashtable handlerNames = null; + private final Map<String, Class<? extends SecurityHandler>> nameToHandler = + new HashMap<String, Class<? extends SecurityHandler>>(); - /** - * Hashtable used to index handlers regarding the class of - * protection policy they use. Basically this will be used when - * encrypting a document. - */ - private Hashtable handlerPolicyClasses = null; + private final Map<Class<? extends ProtectionPolicy>, + Class<? extends SecurityHandler>> policyToHandler = + new HashMap<Class<? extends ProtectionPolicy>, + Class<? extends SecurityHandler>>(); - /** - * private constructor. - */ - private SecurityHandlersManager() + private SecurityHandlerFactory() { - handlerNames = new Hashtable(); - handlerPolicyClasses = new Hashtable(); - try - { - this.registerHandler( - StandardSecurityHandler.FILTER, - StandardSecurityHandler.class, - StandardProtectionPolicy.class); - this.registerHandler( - PublicKeySecurityHandler.FILTER, - PublicKeySecurityHandler.class, - PublicKeyProtectionPolicy.class); - } - catch(Exception e) - { - System.err.println("SecurityHandlersManager strange error with builtin handlers: " + e.getMessage()); - System.exit(1); - } + registerHandler(StandardSecurityHandler.FILTER, + StandardSecurityHandler.class, + StandardProtectionPolicy.class); + + registerHandler(PublicKeySecurityHandler.FILTER, + PublicKeySecurityHandler.class, + PublicKeyProtectionPolicy.class); } /** - * register a security handler. + * Registers a security handler. * * If the security handler was already registered an exception is thrown. * If another handler was previously registered for the same filter name or * for the same policy name, an exception is thrown * - * @param filterName The name of the filter. - * @param securityHandlerClass Security Handler class to register. - * @param protectionPolicyClass Protection Policy class to register. - * - * @throws BadSecurityHandlerException If there is an error registering the security handler. - */ - public void registerHandler(String filterName, Class securityHandlerClass, Class protectionPolicyClass) - throws BadSecurityHandlerException + * @param name the name of the filter + * @param securityHandler security handler class to register + * @param protectionPolicy protection policy class to register + */ + public void registerHandler(String name, + Class<? extends SecurityHandler> securityHandler, + Class<? extends ProtectionPolicy> protectionPolicy) { - if(handlerNames.contains(securityHandlerClass) || handlerPolicyClasses.contains(securityHandlerClass)) + if (nameToHandler.containsKey(name)) { - throw new BadSecurityHandlerException("the following security handler was already registered: " + - securityHandlerClass.getName()); + throw new IllegalStateException("The security handler name is already registered"); } - if(SecurityHandler.class.isAssignableFrom(securityHandlerClass)) - { - try - { - if(handlerNames.containsKey(filterName)) - { - throw new BadSecurityHandlerException("a security handler was already registered " + - "for the filter name " + filterName); - } - if(handlerPolicyClasses.containsKey(protectionPolicyClass)) - { - throw new BadSecurityHandlerException("a security handler was already registered " + - "for the policy class " + protectionPolicyClass.getName()); - } - - handlerNames.put(filterName, securityHandlerClass); - handlerPolicyClasses.put(protectionPolicyClass, securityHandlerClass); - } - catch(Exception e) - { - throw new BadSecurityHandlerException(e); - } - } - else - { - throw new BadSecurityHandlerException("The class is not a super class of SecurityHandler"); - } + nameToHandler.put(name, securityHandler); + policyToHandler.put(protectionPolicy, securityHandler); } - /** - * Get the singleton instance. - * - * @return The SecurityHandlersManager. + * Returns a new security handler for the given protection policy, or null none is available. + * @param policy the protection policy for which to create a security handler + * @return a new SecurityHandler instance, or null none is available */ - public static SecurityHandlersManager getInstance() + public SecurityHandler newSecurityHandlerForPolicy(ProtectionPolicy policy) { - if(instance == null) + Class<? extends SecurityHandler> handlerClass = policyToHandler.get(policy.getClass()); + if (handlerClass == null) { - instance = new SecurityHandlersManager(); - Security.addProvider(new BouncyCastleProvider()); + return null; } - return instance; - } - /** - * Get the security handler for the protection policy. - * - * @param policy The policy to get the security handler for. - * - * @return The appropriate security handler. - * - * @throws BadSecurityHandlerException If it is unable to create a SecurityHandler. - */ - public SecurityHandler getSecurityHandler(ProtectionPolicy policy) throws BadSecurityHandlerException - { - - Object found = handlerPolicyClasses.get(policy.getClass()); - if(found == null) + Class[] argsClasses = { policy.getClass() }; + Object[] args = { policy }; + try { - throw new BadSecurityHandlerException( - "Cannot find an appropriate security handler for " + policy.getClass().getName()); + Constructor<? extends SecurityHandler> ctor = + handlerClass.getDeclaredConstructor(argsClasses); + return ctor.newInstance(args); } - Class handlerclass = (Class) found; - Class[] argsClasses = {policy.getClass()}; - Object[] args = {policy}; - try + catch(NoSuchMethodException e) { - Constructor c = handlerclass.getDeclaredConstructor(argsClasses); - SecurityHandler handler = (SecurityHandler)c.newInstance(args); - return handler; - } - catch(Exception e) - { - e.printStackTrace(); - throw new BadSecurityHandlerException( - "problem while trying to instanciate the security handler "+ - handlerclass.getName() + ": " + e.getMessage()); + // should not happen in normal operation + throw new RuntimeException(e); + } + catch(IllegalAccessException e) + { + // should not happen in normal operation + throw new RuntimeException(e); + } + catch(InstantiationException e) + { + // should not happen in normal operation + throw new RuntimeException(e); + } + catch(InvocationTargetException e) + { + // should not happen in normal operation + throw new RuntimeException(e); } } - - /** - * Retrieve the appropriate SecurityHandler for a the given filter name. - * The filter name is an entry of the encryption dictionary of an encrypted document. - * - * @param filterName The filter name. - * - * @return The appropriate SecurityHandler if it exists. - * - * @throws BadSecurityHandlerException If the security handler does not exist. + * Returns a new security handler for the given Filter name, or null none is available. + * @param name the Filter name from the PDF encryption dictionary + * @return a new SecurityHandler instance, or null none is available */ - public SecurityHandler getSecurityHandler(String filterName) throws BadSecurityHandlerException + public SecurityHandler newSecurityHandler(String name) { - Object found = handlerNames.get(filterName); - if(found == null) + Class<? extends SecurityHandler> handlerClass = nameToHandler.get(name); + if (handlerClass == null) { - throw new BadSecurityHandlerException("Cannot find an appropriate security handler for " + filterName); + return null; } - Class handlerclass = (Class) found; - Class[] argsClasses = {}; - Object[] args = {}; + + Class[] argsClasses = { }; + Object[] args = { }; try { - Constructor c = handlerclass.getDeclaredConstructor(argsClasses); - SecurityHandler handler = (SecurityHandler)c.newInstance(args); - return handler; - } - catch(Exception e) - { - e.printStackTrace(); - throw new BadSecurityHandlerException( - "problem while trying to instanciate the security handler "+ - handlerclass.getName() + ": " + e.getMessage()); + Constructor<? extends SecurityHandler> ctor = + handlerClass.getDeclaredConstructor(argsClasses); + return ctor.newInstance(args); + } + catch(NoSuchMethodException e) + { + // should not happen in normal operation + throw new RuntimeException(e); + } + catch(IllegalAccessException e) + { + // should not happen in normal operation + throw new RuntimeException(e); + } + catch(InstantiationException e) + { + // should not happen in normal operation + throw new RuntimeException(e); + } + catch(InvocationTargetException e) + { + // should not happen in normal operation + throw new RuntimeException(e); } } } Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardProtectionPolicy.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardProtectionPolicy.java?rev=1576570&r1=1576569&r2=1576570&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardProtectionPolicy.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardProtectionPolicy.java Wed Mar 12 02:57:28 2014 @@ -17,8 +17,7 @@ package org.apache.pdfbox.pdmodel.encryption; /** - * This class represents the protection policy to add to a document - * for password-based protection. + * The protection policy to add to a document for password-based protection. * * The following example shows how to protect a PDF document with password. * In this example, the document will be protected so that someone opening @@ -32,38 +31,33 @@ package org.apache.pdfbox.pdmodel.encryp * doc.protect(policy); * </pre> * - * @author Benoit Guillon (benoit.guil...@snv.jussieu.fr) - * @version $Revision: 1.3 $ + * @author Benoit Guillon */ -public class StandardProtectionPolicy extends ProtectionPolicy +public final class StandardProtectionPolicy extends ProtectionPolicy { - private AccessPermission permissions; - private String ownerPassword = ""; - private String userPassword = ""; - /** * Creates an new instance of the standard protection policy * in order to protect a PDF document with passwords. * - * @param ownerPass The owner's password. - * @param userPass The users's password. - * @param perms The access permissions given to the user. + * @param ownerPassword The owner's password. + * @param userPassword The users's password. + * @param permissions The access permissions given to the user. */ - public StandardProtectionPolicy(String ownerPass, String userPass, AccessPermission perms) + public StandardProtectionPolicy(String ownerPassword, String userPassword, + AccessPermission permissions) { - this.permissions = perms; - this.userPassword = userPass; - this.ownerPassword = ownerPass; + this.ownerPassword = ownerPassword; + this.userPassword = userPassword; + this.permissions = permissions; } /** - * Getter of the property <tt>permissions</tt>. - * - * @return Returns the permissions. + * Returns the access permissions + * @return the access permissions */ public AccessPermission getPermissions() { @@ -71,19 +65,17 @@ public class StandardProtectionPolicy ex } /** - * Setter of the property <tt>permissions</tt>. - * - * @param perms The permissions to set. + * Sets the access permissions + * @param permissions the new access permissions */ - public void setPermissions(AccessPermission perms) + public void setPermissions(AccessPermission permissions) { - this.permissions = perms; + this.permissions = permissions; } /** - * Getter of the property <tt>ownerPassword</tt>. - * - * @return Returns the ownerPassword. + * Returns the owner password. + * @return the owner password */ public String getOwnerPassword() { @@ -91,19 +83,17 @@ public class StandardProtectionPolicy ex } /** - * Setter of the property <tt>ownerPassword</tt>. - * - * @param ownerPass The ownerPassword to set. + * Sets the owner password + * @param ownerPassword the new owner password */ - public void setOwnerPassword(String ownerPass) + public void setOwnerPassword(String ownerPassword) { - this.ownerPassword = ownerPass; + this.ownerPassword = ownerPassword; } /** - * Getter of the property <tt>userPassword</tt>. - * - * @return Returns the userPassword. + * Returns the user password. + * @return the user password */ public String getUserPassword() { @@ -111,12 +101,11 @@ public class StandardProtectionPolicy ex } /** - * Setter of the property <tt>userPassword</tt>. - * - * @param userPass The userPassword to set. + * Sets the user password. + * @param userPassword the new user password */ - public void setUserPassword(String userPass) + public void setUserPassword(String userPassword) { - this.userPassword = userPass; + this.userPassword = userPassword; } }