Commit 8fe0b06cd879f503d0e5be63f706d3adda3b8203
1 parent
0c99cf87
Pad encryption parameters that are too short (fixes #96)
Showing
6 changed files
with
93 additions
and
1 deletions
ChangeLog
libqpdf/QPDF_encryption.cc
| @@ -340,6 +340,16 @@ hash_V5(std::string const& password, | @@ -340,6 +340,16 @@ hash_V5(std::string const& password, | ||
| 340 | return result; | 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 | std::string | 353 | std::string |
| 344 | QPDF::compute_data_key(std::string const& encryption_key, | 354 | QPDF::compute_data_key(std::string const& encryption_key, |
| 345 | int objid, int generation, bool use_aes, | 355 | int objid, int generation, bool use_aes, |
| @@ -876,6 +886,8 @@ QPDF::initializeEncryption() | @@ -876,6 +886,8 @@ QPDF::initializeEncryption() | ||
| 876 | 886 | ||
| 877 | if (V < 5) | 887 | if (V < 5) |
| 878 | { | 888 | { |
| 889 | + pad_short_parameter(O, key_bytes); | ||
| 890 | + pad_short_parameter(U, key_bytes); | ||
| 879 | if (! ((O.length() == key_bytes) && (U.length() == key_bytes))) | 891 | if (! ((O.length() == key_bytes) && (U.length() == key_bytes))) |
| 880 | { | 892 | { |
| 881 | throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), | 893 | throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), |
| @@ -899,6 +911,11 @@ QPDF::initializeEncryption() | @@ -899,6 +911,11 @@ QPDF::initializeEncryption() | ||
| 899 | UE = encryption_dict.getKey("/UE").getStringValue(); | 911 | UE = encryption_dict.getKey("/UE").getStringValue(); |
| 900 | Perms = encryption_dict.getKey("/Perms").getStringValue(); | 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 | if ((O.length() < OU_key_bytes_V5) || | 919 | if ((O.length() < OU_key_bytes_V5) || |
| 903 | (U.length() < OU_key_bytes_V5) || | 920 | (U.length() < OU_key_bytes_V5) || |
| 904 | (OE.length() < OUE_key_bytes_V5) || | 921 | (OE.length() < OUE_key_bytes_V5) || |
qpdf/qpdf.testcov
| @@ -293,3 +293,4 @@ QPDF ignore first space in xref entry 0 | @@ -293,3 +293,4 @@ QPDF ignore first space in xref entry 0 | ||
| 293 | QPDF ignore first extra space in xref entry 0 | 293 | QPDF ignore first extra space in xref entry 0 |
| 294 | QPDF ignore second extra space in xref entry 0 | 294 | QPDF ignore second extra space in xref entry 0 |
| 295 | QPDF ignore length error xref entry 0 | 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,7 +232,7 @@ foreach my $d (@bug_tests) | ||
| 232 | show_ntests(); | 232 | show_ntests(); |
| 233 | # ---------- | 233 | # ---------- |
| 234 | $td->notify("--- Miscellaneous Tests ---"); | 234 | $td->notify("--- Miscellaneous Tests ---"); |
| 235 | -$n_tests += 87; | 235 | +$n_tests += 88; |
| 236 | 236 | ||
| 237 | $td->runtest("qpdf version", | 237 | $td->runtest("qpdf version", |
| 238 | {$td->COMMAND => "qpdf --version"}, | 238 | {$td->COMMAND => "qpdf --version"}, |
| @@ -676,6 +676,16 @@ $td->runtest("recoverable xref errors", | @@ -676,6 +676,16 @@ $td->runtest("recoverable xref errors", | ||
| 676 | $td->EXIT_STATUS => 3}, | 676 | $td->EXIT_STATUS => 3}, |
| 677 | $td->NORMALIZE_NEWLINES); | 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 | show_ntests(); | 689 | show_ntests(); |
| 680 | # ---------- | 690 | # ---------- |
| 681 | $td->notify("--- Single Page ---"); | 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