]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/Decrypt.cc
Reused eog HIG dialog in GPdf.
[evince.git] / pdf / xpdf / Decrypt.cc
index 8de40911a0e192366ac2e9e891521b5cce0278ae..dca3762c1b37c96458fca0c47f05bfc2d67a7f34 100644 (file)
@@ -2,15 +2,16 @@
 //
 // Decrypt.cc
 //
-// Copyright 1996-2002 Glyph & Cog, LLC
+// Copyright 1996-2003 Glyph & Cog, LLC
 //
 //========================================================================
 
-#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);
     }
   }
 
@@ -366,20 +382,20 @@ static void md5(Guchar *msg, int msgLen, Guchar *digest) {
   }
 
   // break digest into bytes
-  digest[0] = a & 0xff;
-  digest[1] = (a >>= 8) & 0xff;
-  digest[2] = (a >>= 8) & 0xff;
-  digest[3] = (a >>= 8) & 0xff;
-  digest[4] = b & 0xff;
-  digest[5] = (b >>= 8) & 0xff;
-  digest[6] = (b >>= 8) & 0xff;
-  digest[7] = (b >>= 8) & 0xff;
-  digest[8] = c & 0xff;
-  digest[9] = (c >>= 8) & 0xff;
-  digest[10] = (c >>= 8) & 0xff;
-  digest[11] = (c >>= 8) & 0xff;
-  digest[12] = d & 0xff;
-  digest[13] = (d >>= 8) & 0xff;
-  digest[14] = (d >>= 8) & 0xff;
-  digest[15] = (d >>= 8) & 0xff;
+  digest[0] = (Guchar)(a & 0xff);
+  digest[1] = (Guchar)((a >>= 8) & 0xff);
+  digest[2] = (Guchar)((a >>= 8) & 0xff);
+  digest[3] = (Guchar)((a >>= 8) & 0xff);
+  digest[4] = (Guchar)(b & 0xff);
+  digest[5] = (Guchar)((b >>= 8) & 0xff);
+  digest[6] = (Guchar)((b >>= 8) & 0xff);
+  digest[7] = (Guchar)((b >>= 8) & 0xff);
+  digest[8] = (Guchar)(c & 0xff);
+  digest[9] = (Guchar)((c >>= 8) & 0xff);
+  digest[10] = (Guchar)((c >>= 8) & 0xff);
+  digest[11] = (Guchar)((c >>= 8) & 0xff);
+  digest[12] = (Guchar)(d & 0xff);
+  digest[13] = (Guchar)((d >>= 8) & 0xff);
+  digest[14] = (Guchar)((d >>= 8) & 0xff);
+  digest[15] = (Guchar)((d >>= 8) & 0xff);
 }