Browse code

pdf: bb #7053

David Raynor authored on 2013/04/06 06:35:29
Showing 1 changed files
... ...
@@ -296,6 +296,9 @@ static void pdfobj_flag(struct pdf_struct *pdf, struct pdf_obj *obj, enum pdf_fl
296 296
 	case MANY_FILTERS:
297 297
 	    s = "more than 2 filters per obj";
298 298
 	    break;
299
+	case DECRYPTABLE_PDF:
300
+	    s = "decryptable PDF";
301
+	    break;
299 302
     }
300 303
     cli_dbgmsg("cli_pdf: %s flagged in object %u %u\n", s, obj->id>>8, obj->id&0xff);
301 304
 }
... ...
@@ -567,6 +570,8 @@ static int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj)
567 567
     char *ascii_decoded = NULL;
568 568
     int dump = 1;
569 569
 
570
+    cli_dbgmsg("pdf_extract_obj: obj %u %u\n", obj->id>>8, obj->id&0xff);
571
+
570 572
     /* TODO: call bytecode hook here, allow override dumpability */
571 573
     if ((!(obj->flags & (1 << OBJ_STREAM)) ||
572 574
 	(obj->flags & (1 << OBJ_HASFILTERS)))
... ...
@@ -585,7 +590,7 @@ static int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj)
585 585
     }
586 586
     if (!dump)
587 587
 	return CL_CLEAN;
588
-    cli_dbgmsg("cli_pdf: dumping obj %u %u\n", obj->id>>8, obj->id);
588
+    cli_dbgmsg("cli_pdf: dumping obj %u %u\n", obj->id>>8, obj->id&0xff);
589 589
     snprintf(fullname, sizeof(fullname), "%s"PATHSEP"pdf%02u", pdf->dir, pdf->files++);
590 590
     fout = open(fullname,O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
591 591
     if (fout < 0) {
... ...
@@ -907,6 +912,7 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
907 907
 	q2 = pdf_nextobject(q, bytesleft);
908 908
 	bytesleft -= q2 -q;
909 909
 	if (!q2 || bytesleft < 0) {
910
+            cli_dbgmsg("cli_pdf: %u %u obj: no dictionary\n", obj->id>>8, obj->id&0xff);
910 911
 	    return;
911 912
 	}
912 913
 	q3 = memchr(q-1, '<', q2-q+1);
... ...
@@ -922,6 +928,7 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
922 922
 	q2 = pdf_nextobject(q, bytesleft);
923 923
 	bytesleft -= q2 -q;
924 924
 	if (!q2 || bytesleft < 0) {
925
+            cli_dbgmsg("cli_pdf: %u %u obj: broken dictionary\n", obj->id>>8, obj->id&0xff);
925 926
 	    return;
926 927
 	}
927 928
 	q3 = memchr(q-1, '>', q2-q+1);
... ...
@@ -1262,7 +1269,7 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
1262 1262
 	    password_empty = 1;
1263 1263
 	    /* Algorithm 3.2a could be used to recover encryption key */
1264 1264
 	}
1265
-    } else {
1265
+    } else if ((R >= 2) && (R <= 4)) {
1266 1266
 	/* 7.6.3.3 Algorithm 2 */
1267 1267
 	cli_md5_init(&md5);
1268 1268
 	/* empty password, password == padding */
... ...
@@ -1276,9 +1283,9 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
1276 1276
 	    cli_md5_update(&md5, &v, 4);
1277 1277
 	}
1278 1278
 	cli_md5_final(result, &md5);
1279
+	if (length > 128)
1280
+	    length = 128;
1279 1281
 	if (R >= 3) {
1280
-	    if (length > 128)
1281
-		length = 128;
1282 1282
 	    for (i=0;i<50;i++) {
1283 1283
 		cli_md5_init(&md5);
1284 1284
 		cli_md5_update(&md5, result, length/8);
... ...
@@ -1329,6 +1336,11 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
1329 1329
 	    cli_dbgmsg("cli_pdf: invalid revision %d\n", R);
1330 1330
 	}
1331 1331
     }
1332
+    else {
1333
+	/* Supported R is in {2,3,4,5} */
1334
+	cli_dbgmsg("cli_pdf: R value out of range\n");
1335
+	return;
1336
+    }
1332 1337
     if (password_empty) {
1333 1338
 	cli_dbgmsg("cli_pdf: user password is empty\n");
1334 1339
 	/* The key we computed above is the key used to encrypt the streams.
... ...
@@ -1395,6 +1407,10 @@ static void pdf_handle_enc(struct pdf_struct *pdf)
1395 1395
 	    cli_dbgmsg("cli_pdf: invalid R\n");
1396 1396
 	    break;
1397 1397
 	}
1398
+	if ((R > 5) || (R < 2)) {
1399
+	    cli_dbgmsg("cli_pdf: R value outside supported range [2..5]\n");
1400
+	    break;
1401
+	}
1398 1402
 
1399 1403
 	if (R < 5)
1400 1404
 	    oulen = 32;