X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=pdf%2Fxpdf%2FDecrypt.cc;h=dca3762c1b37c96458fca0c47f05bfc2d67a7f34;hb=884f739665dc56e66f51e104350f2affd33f2dd8;hp=8de40911a0e192366ac2e9e891521b5cce0278ae;hpb=2a393c134fe3fe8eb85bf818cb7ad6ae4396322a;p=evince.git diff --git a/pdf/xpdf/Decrypt.cc b/pdf/xpdf/Decrypt.cc index 8de40911..dca3762c 100644 --- a/pdf/xpdf/Decrypt.cc +++ b/pdf/xpdf/Decrypt.cc @@ -2,15 +2,16 @@ // // Decrypt.cc // -// Copyright 1996-2002 Glyph & Cog, LLC +// Copyright 1996-2003 Glyph & Cog, LLC // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #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); }