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 | 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
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->runtest("recoverable xref errors", |
| 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