You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2016/01/07 18:33:37 UTC

svn commit: r1723601 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption: SecurityHandler.java StandardSecurityHandler.java

Author: tilman
Date: Thu Jan  7 17:33:36 2016
New Revision: 1723601

URL: http://svn.apache.org/viewvc?rev=1723601&view=rev
Log:
PDFBOX-2729: prepare AES 128 bit encryption

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java

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=1723601&r1=1723600&r2=1723601&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 Thu Jan  7 17:33:36 2016
@@ -143,11 +143,6 @@ public abstract class SecurityHandler
         }
         else
         {
-            if (useAES && !decrypt)
-            {
-                throw new IllegalArgumentException("AES encryption with key length other than 256 bits is not yet implemented.");
-            }
-
             byte[] finalKey = calcFinalKey(objectNumber, genNumber);
 
             if (useAES)
@@ -244,20 +239,11 @@ public abstract class SecurityHandler
     {
         byte[] iv = new byte[16];
 
-        int ivSize = data.read(iv);
-
-        if (decrypt && ivSize == -1)
+        if (!prepareAESInitializationVector(decrypt, iv, data, output))
         {
             return;
         }
 
-        if (ivSize != iv.length)
-        {
-            throw new IOException(
-                    "AES initialization vector not fully read: only "
-                    + ivSize + " bytes read instead of " + iv.length);
-        }
-
         try
         {
             Cipher decryptCipher;
@@ -317,29 +303,9 @@ public abstract class SecurityHandler
     {
         byte[] iv = new byte[16];
 
-        if (decrypt)
-        {
-            // read IV from stream
-            int ivSize = data.read(iv);
-
-            if (ivSize == -1)
-            {
-                return;
-            }
-
-            if (ivSize != iv.length)
-            {
-                throw new IOException(
-                        "AES initialization vector not fully read: only "
-                        + ivSize + " bytes read instead of " + iv.length);
-            }
-        }
-        else
+        if (!prepareAESInitializationVector(decrypt, iv, data, output))
         {
-            // generate random IV and write to stream
-            SecureRandom rnd = new SecureRandom();
-            rnd.nextBytes(iv);
-            output.write(iv);
+            return;
         }
 
         Cipher cipher;
@@ -376,6 +342,33 @@ public abstract class SecurityHandler
         }
     }
 
+    private boolean prepareAESInitializationVector(boolean decrypt, byte[] iv, InputStream data, OutputStream output) throws IOException
+    {
+        if (decrypt)
+        {
+            // read IV from stream
+            int ivSize = data.read(iv);
+            if (ivSize == -1)
+            {
+                return false;
+            }
+            if (ivSize != iv.length)
+            {
+                throw new IOException(
+                        "AES initialization vector not fully read: only "
+                                + ivSize + " bytes read instead of " + iv.length);
+            }
+        }
+        else
+        {
+            // generate random IV and write to stream
+            SecureRandom rnd = new SecureRandom();
+            rnd.nextBytes(iv);
+            output.write(iv);
+        }
+        return true;
+    }
+
     /**
      * This will dispatch to the correct method.
      *

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java?rev=1723601&r1=1723600&r2=1723601&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java Thu Jan  7 17:33:36 2016
@@ -109,6 +109,7 @@ public final class StandardSecurityHandl
         {
             return DEFAULT_VERSION;
         }
+        //TODO return 4 if keyLength is 128 to enable AES128 functionality
         else if(keyLength == 256)
         {
             return 5;
@@ -137,6 +138,10 @@ public final class StandardSecurityHandl
             // note about revision 5: "Shall not be used. This value was used by a deprecated Adobe extension."
             return 6;    
         }
+        if (version == 4)
+        {
+            return 4;
+        }
         if ( version == 2 || version == 3 || policy.getPermissions().hasAnyRevision3PermissionSet())
         {
             return 3;
@@ -471,17 +476,6 @@ public final class StandardSecurityHandl
         }
     }
 
-    private void prepareEncryptionDictAES(PDEncryption encryptionDictionary, COSName aesVName)
-    {
-        PDCryptFilterDictionary cryptFilterDictionary = new PDCryptFilterDictionary();
-        cryptFilterDictionary.setCryptFilterMethod(aesVName);
-        cryptFilterDictionary.setLength(keyLength);
-        encryptionDictionary.setStdCryptFilterDictionary(cryptFilterDictionary);
-        encryptionDictionary.setStreamFilterName(COSName.STD_CF);
-        encryptionDictionary.setStringFilterName(COSName.STD_CF);
-        setAES(true);
-    }
-
     private void prepareEncryptionDictRev2345(String ownerPassword, String userPassword,
             PDEncryption encryptionDictionary, int permissionInt, PDDocument document, 
             int revision, int length)
@@ -523,6 +517,22 @@ public final class StandardSecurityHandl
 
         encryptionDictionary.setOwnerKey(ownerBytes);
         encryptionDictionary.setUserKey(userBytes);
+        
+        if (revision == 4)
+        {
+            prepareEncryptionDictAES(encryptionDictionary, COSName.AESV2);
+        }
+    }
+
+    private void prepareEncryptionDictAES(PDEncryption encryptionDictionary, COSName aesVName)
+    {
+        PDCryptFilterDictionary cryptFilterDictionary = new PDCryptFilterDictionary();
+        cryptFilterDictionary.setCryptFilterMethod(aesVName);
+        cryptFilterDictionary.setLength(keyLength);
+        encryptionDictionary.setStdCryptFilterDictionary(cryptFilterDictionary);
+        encryptionDictionary.setStreamFilterName(COSName.STD_CF);
+        encryptionDictionary.setStringFilterName(COSName.STD_CF);
+        setAES(true);
     }
 
     /**