summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2018-03-09 15:09:57 +0100
committerSebastian Rasmussen <sebras@gmail.com>2018-03-22 12:33:34 +0800
commit188d61ef347d644b3e122754af73decdfb8d8ab1 (patch)
tree2d94ed9d40758aa2a49db1141ddcdc47962a0b3f
parentbedb98a87a38a64b67d9a27e08b459dd216b2de9 (diff)
downloadmupdf-188d61ef347d644b3e122754af73decdfb8d8ab1.tar.xz
Rearrange user password authentication code.
pdf_authenticate_user_password() now looks similar to pdf_compute_user_password(), easing readability.
-rw-r--r--source/pdf/pdf-crypt.c105
1 files changed, 59 insertions, 46 deletions
diff --git a/source/pdf/pdf-crypt.c b/source/pdf/pdf-crypt.c
index 1ceaa1be..7150f66e 100644
--- a/source/pdf/pdf-crypt.c
+++ b/source/pdf/pdf-crypt.c
@@ -640,8 +640,8 @@ pdf_authenticate_user_password(fz_context *ctx, pdf_crypt *crypt, unsigned char
}
/*
- * Authenticating the owner password (PDF 1.7 algorithm 3.7
- * and ExtensionLevel 3 algorithm 3.12)
+ * Authenticating the owner password (PDF 1.7 algorithm 3.7,
+ * ExtensionLevel 3 algorithm 3.12, ExtensionLevel 8 algorithm)
* Generates the user password from the owner password
* and calls pdf_authenticate_user_password.
*/
@@ -649,63 +649,60 @@ pdf_authenticate_user_password(fz_context *ctx, pdf_crypt *crypt, unsigned char
static int
pdf_authenticate_owner_password(fz_context *ctx, pdf_crypt *crypt, unsigned char *ownerpass, size_t pwlen)
{
- unsigned char pwbuf[32];
- unsigned char key[32];
- unsigned char xor[32];
- unsigned char userpass[32];
- int i, n, x;
- fz_md5 md5;
- fz_arc4 arc4;
-
- if (crypt->r == 5)
- {
- /* PDF 1.7 ExtensionLevel 3 algorithm 3.12 */
- pdf_compute_encryption_key_r5(ctx, crypt, ownerpass, pwlen, 1, key);
- return !memcmp(key, crypt->o, 32);
- }
- else if (crypt->r == 6)
+ if (crypt->r == 2)
{
- /* PDF 1.7 ExtensionLevel 8 algorithm */
- pdf_compute_encryption_key_r6(ctx, crypt, ownerpass, pwlen, 1, key);
- return !memcmp(key, crypt->o, 32);
- }
+ unsigned char pwbuf[32];
+ unsigned char key[32];
+ unsigned char userpass[32];
+ int n;
+ fz_md5 md5;
+ fz_arc4 arc4;
- n = crypt->length / 8;
+ n = crypt->length / 8;
- /* Step 1 -- steps 1 to 4 of PDF 1.7 algorithm 3.3 */
+ if (pwlen > 32)
+ pwlen = 32;
+ memcpy(pwbuf, ownerpass, pwlen);
+ memcpy(pwbuf + pwlen, padding, 32 - pwlen);
- /* copy and pad password string */
- if (pwlen > 32)
- pwlen = 32;
- memcpy(pwbuf, ownerpass, pwlen);
- memcpy(pwbuf + pwlen, padding, 32 - pwlen);
+ fz_md5_init(&md5);
+ fz_md5_update(&md5, pwbuf, 32);
+ fz_md5_final(&md5, key);
- /* take md5 hash of padded password */
- fz_md5_init(&md5);
- fz_md5_update(&md5, pwbuf, 32);
- fz_md5_final(&md5, key);
+ fz_arc4_init(&arc4, key, n);
+ fz_arc4_encrypt(&arc4, userpass, crypt->o, 32);
- /* do some voodoo 50 times (Revision 3 or greater) */
- if (crypt->r >= 3)
+ return pdf_authenticate_user_password(ctx, crypt, userpass, 32);
+ }
+
+ if (crypt->r == 3 || crypt->r == 4)
{
+ unsigned char pwbuf[32];
+ unsigned char key[32];
+ unsigned char xor[32];
+ unsigned char userpass[32];
+ int i, n, x;
+ fz_md5 md5;
+ fz_arc4 arc4;
+
+ n = crypt->length / 8;
+
+ if (pwlen > 32)
+ pwlen = 32;
+ memcpy(pwbuf, ownerpass, pwlen);
+ memcpy(pwbuf + pwlen, padding, 32 - pwlen);
+
+ fz_md5_init(&md5);
+ fz_md5_update(&md5, pwbuf, 32);
+ fz_md5_final(&md5, key);
+
for (i = 0; i < 50; i++)
{
fz_md5_init(&md5);
fz_md5_update(&md5, key, 16);
fz_md5_final(&md5, key);
}
- }
- /* Step 2 (Revision 2) */
- if (crypt->r == 2)
- {
- fz_arc4_init(&arc4, key, n);
- fz_arc4_encrypt(&arc4, userpass, crypt->o, 32);
- }
-
- /* Step 2 (Revision 3 or greater) */
- if (crypt->r >= 3)
- {
memcpy(userpass, crypt->o, 32);
for (x = 0; x < 20; x++)
{
@@ -714,9 +711,25 @@ pdf_authenticate_owner_password(fz_context *ctx, pdf_crypt *crypt, unsigned char
fz_arc4_init(&arc4, xor, n);
fz_arc4_encrypt(&arc4, userpass, userpass, 32);
}
+
+ return pdf_authenticate_user_password(ctx, crypt, userpass, 32);
+ }
+
+ if (crypt->r == 5)
+ {
+ unsigned char key[32];
+ pdf_compute_encryption_key_r5(ctx, crypt, ownerpass, pwlen, 1, key);
+ return !memcmp(key, crypt->o, 32);
}
- return pdf_authenticate_user_password(ctx, crypt, userpass, 32);
+ if (crypt->r == 6)
+ {
+ unsigned char key[32];
+ pdf_compute_encryption_key_r6(ctx, crypt, ownerpass, pwlen, 1, key);
+ return !memcmp(key, crypt->o, 32);
+ }
+
+ return 0;
}
static void pdf_docenc_from_utf8(char *password, const char *utf8, int n)