You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/03/12 03:57:28 UTC

svn commit: r1576570 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: pdfparser/ pdmodel/ pdmodel/encryption/

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.guillon@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.guillon@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:ben@benlitchfield.com">Ben Litchfield</a>
- * @author Benoit Guillon (benoit.guillon@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.guillon@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.guillon@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;
     }
 }