]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/Decrypt.cc
Import of Xpdf 2.00 for merge
[evince.git] / pdf / xpdf / Decrypt.cc
index 8de40911a0e192366ac2e9e891521b5cce0278ae..bb3e3f1f6ef06be5d33e088a33564af4631651ed 100644 (file)
@@ -6,11 +6,12 @@
 //
 //========================================================================
 
-#ifdef __GNUC__
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
 #pragma implementation
 #endif
 
-#include <aconf.h>
 #include "gmem.h"
 #include "Decrypt.h"
 
@@ -65,11 +66,12 @@ GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
                           int permissions, GString *fileID,
                           GString *ownerPassword, GString *userPassword,
                           Guchar *fileKey, GBool *ownerPasswordOk) {
-  Guchar test[32];
+  Guchar test[32], test2[32];
   GString *userPassword2;
   Guchar fState[256];
+  Guchar tmpKey[16];
   Guchar fx, fy;
-  int len, i;
+  int len, i, j;
 
   // try using the supplied owner password to generate the user password
   if (ownerPassword) {
@@ -89,12 +91,26 @@ GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
       md5(test, 16, test);
     }
   }
-  rc4InitKey(test, keyLength, fState);
-  fx = fy = 0;
-  for (i = 0; i < 32; ++i) {
-    test[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
+  if (encRevision == 2) {
+    rc4InitKey(test, keyLength, fState);
+    fx = fy = 0;
+    for (i = 0; i < 32; ++i) {
+      test2[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
+    }
+  } else {
+    memcpy(test2, ownerKey->getCString(), 32);
+    for (i = 19; i >= 0; --i) {
+      for (j = 0; j < keyLength; ++j) {
+       tmpKey[j] = test[j] ^ i;
+      }
+      rc4InitKey(tmpKey, keyLength, fState);
+      fx = fy = 0;
+      for (j = 0; j < 32; ++j) {
+       test2[j] = rc4DecryptByte(fState, &fx, &fy, test2[j]);
+      }
+    }
   }
-  userPassword2 = new GString((char *)test, 32);
+  userPassword2 = new GString((char *)test2, 32);
   if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
                   permissions, fileID, userPassword2, fileKey)) {
     *ownerPasswordOk = gTrue;
@@ -143,7 +159,7 @@ GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
   md5(buf, 68 + fileID->getLength(), fileKey);
   if (encRevision == 3) {
     for (i = 0; i < 50; ++i) {
-      md5(fileKey, 16, fileKey);
+      md5(fileKey, keyLength, fileKey);
     }
   }