summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2018-11-20 12:14:41 +0800
committerIru Cai <mytbk920423@gmail.com>2018-11-20 12:14:41 +0800
commit35c5c76c53466af4b3cf594fb27c435ce058c252 (patch)
tree0edfc2d2a0353ada06ce2f5a7a12ff247d006eeb
parent5ce137a2c7f9bdea70a7222ade9e99a069226b9d (diff)
downloadmupdf-35c5c76c53466af4b3cf594fb27c435ce058c252.tar.xz
the complete hashing, but not works
-rw-r--r--source/pdf/pdf-crypt.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/source/pdf/pdf-crypt.c b/source/pdf/pdf-crypt.c
index cc333039..e98f8989 100644
--- a/source/pdf/pdf-crypt.c
+++ b/source/pdf/pdf-crypt.c
@@ -3,6 +3,8 @@
#include <string.h>
#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
typedef struct
{
@@ -102,8 +104,28 @@ void mt19937_init(mt19937 *ctx, uint32_t seed)
ctx->MT[0] = seed;
for (int i = 1; i < 624; i++) {
- ctx->MT[i] = 0x6c078965 * (ctx->MT[i] ^ (ctx->MT[i-1] >> 30)) + i;
+ ctx->MT[i] = 0x6c078965UL * (ctx->MT[i] ^ (ctx->MT[i-1] >> 30)) + i;
+ }
+}
+
+uint32_t hex_to_dword(const char *hex)
+{
+ uint32_t result = 0;
+ for (int i = 0; i < 4; i++) {
+ uint32_t t = 0;
+ for (int j = 0; j < 2; j++) {
+ t *= 16;
+ if (hex[j] >= '0' && hex[j] <= '9')
+ t += hex[j] - '0';
+ else if (hex[j] >= 'A' && hex[j] <= 'F')
+ t += hex[j] - 'A' + 10;
+ else if (hex[j] >= 'a' && hex[j] <= 'f')
+ t += hex[j] - 'a' + 10;
+ }
+ result |= (t << (i * 8));
+ hex += 2;
}
+ return result;
}
enum
@@ -376,6 +398,7 @@ pdf_new_crypt(fz_context *ctx, pdf_obj *dict, pdf_obj *id)
unsigned char xml_hash_sum[32];
unsigned char *r_buf = NULL;
size_t r_size = 0;
+ mt19937 mtctx;
// crypt->encrypt_metadata = 0;
obj = pdf_dict_get(ctx, dict, PDF_NAME(Length));
@@ -433,7 +456,30 @@ pdf_new_crypt(fz_context *ctx, pdf_obj *dict, pdf_obj *id)
r_buf[i] ^= tmpbyte;
}
}
- /* hash some weird thing */
+
+ const char *sseed = strstr(r_buf, "Seed=\"");
+ if (!sseed) {
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot find the seed");
+ }
+ uint32_t seed = strtoll(sseed + 6, NULL, 10);
+ mt19937_init(&mtctx, seed);
+
+ const char *userpass = strstr(r_buf, "<xjc:UserPassword>");
+ if (!userpass) {
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot find UserPassword");
+ }
+ userpass += 18;
+
+ uint32_t tmpword = 0xffffffff;
+ uint32_t pass[0x20];
+ for (int i = 0; i < 0x20; i++) {
+ tmpword ^= mt19937_next(&mtctx);
+ uint32_t dw = hex_to_dword(userpass);
+ userpass += 8;
+ pass[i] = dw ^ tmpword;
+ }
+
+ fz_sha256_update(&sha256, pass, 0x80);
fz_sha256_update(&sha256, r_buf, r_size);
fz_sha256_init(&xml_hash);