Commit 8fe0b06cd879f503d0e5be63f706d3adda3b8203

Authored by Jay Berkenbilt
1 parent 0c99cf87

Pad encryption parameters that are too short (fixes #96)

ChangeLog
  1 +2017-08-11 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Handle encrypted files whose encryption parameters are too
  4 + short. Fixes #96.
  5 +
1 6 2017-08-10 Jay Berkenbilt <ejb@ql.org>
2 7  
3 8 * Remove dependency on libpcre.
... ...
libqpdf/QPDF_encryption.cc
... ... @@ -340,6 +340,16 @@ hash_V5(std::string const&amp; password,
340 340 return result;
341 341 }
342 342  
  343 +static
  344 +void pad_short_parameter(std::string& param, unsigned int max_len)
  345 +{
  346 + if (param.length() < max_len)
  347 + {
  348 + QTC::TC("qpdf", "QPDF_encryption pad short parameter");
  349 + param.append(max_len - param.length(), '\0');
  350 + }
  351 +}
  352 +
343 353 std::string
344 354 QPDF::compute_data_key(std::string const& encryption_key,
345 355 int objid, int generation, bool use_aes,
... ... @@ -876,6 +886,8 @@ QPDF::initializeEncryption()
876 886  
877 887 if (V < 5)
878 888 {
  889 + pad_short_parameter(O, key_bytes);
  890 + pad_short_parameter(U, key_bytes);
879 891 if (! ((O.length() == key_bytes) && (U.length() == key_bytes)))
880 892 {
881 893 throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(),
... ... @@ -899,6 +911,11 @@ QPDF::initializeEncryption()
899 911 UE = encryption_dict.getKey("/UE").getStringValue();
900 912 Perms = encryption_dict.getKey("/Perms").getStringValue();
901 913  
  914 + pad_short_parameter(O, OU_key_bytes_V5);
  915 + pad_short_parameter(U, OU_key_bytes_V5);
  916 + pad_short_parameter(OE, OUE_key_bytes_V5);
  917 + pad_short_parameter(UE, OUE_key_bytes_V5);
  918 + pad_short_parameter(Perms, Perms_key_bytes_V5);
902 919 if ((O.length() < OU_key_bytes_V5) ||
903 920 (U.length() < OU_key_bytes_V5) ||
904 921 (OE.length() < OUE_key_bytes_V5) ||
... ...
qpdf/qpdf.testcov
... ... @@ -293,3 +293,4 @@ QPDF ignore first space in xref entry 0
293 293 QPDF ignore first extra space in xref entry 0
294 294 QPDF ignore second extra space in xref entry 0
295 295 QPDF ignore length error xref entry 0
  296 +QPDF_encryption pad short parameter 0
... ...
qpdf/qtest/qpdf.test
... ... @@ -232,7 +232,7 @@ foreach my $d (@bug_tests)
232 232 show_ntests();
233 233 # ----------
234 234 $td->notify("--- Miscellaneous Tests ---");
235   -$n_tests += 87;
  235 +$n_tests += 88;
236 236  
237 237 $td->runtest("qpdf version",
238 238 {$td->COMMAND => "qpdf --version"},
... ... @@ -676,6 +676,16 @@ $td-&gt;runtest(&quot;recoverable xref errors&quot;,
676 676 $td->EXIT_STATUS => 3},
677 677 $td->NORMALIZE_NEWLINES);
678 678  
  679 +# A file was emailed privately with issue 96. short-O-U.pdf was
  680 +# created by copying encryption parameters from that file. It exhibits
  681 +# the same behavior as the original file.
  682 +$td->runtest("short /O or /U",
  683 + {$td->COMMAND =>
  684 + "qpdf --password=19723102477 --check short-O-U.pdf"},
  685 + {$td->FILE => "short-O-U.out",
  686 + $td->EXIT_STATUS => 0},
  687 + $td->NORMALIZE_NEWLINES);
  688 +
679 689 show_ntests();
680 690 # ----------
681 691 $td->notify("--- Single Page ---");
... ...
qpdf/qtest/qpdf/short-O-U.out 0 → 100644
  1 +checking short-O-U.pdf
  2 +PDF Version: 1.6
  3 +R = 4
  4 +P = -4
  5 +User password = 19723102477
  6 +extract for accessibility: allowed
  7 +extract for any purpose: allowed
  8 +print low resolution: allowed
  9 +print high resolution: allowed
  10 +modify document assembly: allowed
  11 +modify forms: allowed
  12 +modify annotations: allowed
  13 +modify other: allowed
  14 +modify anything: allowed
  15 +stream encryption method: AESv2
  16 +string encryption method: AESv2
  17 +file encryption method: AESv2
  18 +File is not linearized
  19 +No syntax or stream encoding errors found; the file may still contain
  20 +errors that qpdf cannot detect
... ...
qpdf/qtest/qpdf/short-O-U.pdf 0 → 100644
No preview for this file type