Commit e623caf264ce989aa74c98496b13c6fc01209d95
1 parent
aab00a1a
Refactor `compute_O_rc4_key` to return `std::string`, replace raw character arra…
…ys with `std::string`, and simplify related password handling logic.
Showing
2 changed files
with
13 additions
and
24 deletions
include/qpdf/QPDF.hh
| ... | ... | @@ -544,10 +544,8 @@ class QPDF |
| 544 | 544 | std::string& user_password, std::string const& owner_password) const; |
| 545 | 545 | bool check_owner_password_V5(std::string const& owner_passworda) const; |
| 546 | 546 | std::string compute_Perms_value_V5_clear() const; |
| 547 | - void compute_O_rc4_key( | |
| 548 | - std::string const& user_password, | |
| 549 | - std::string const& owner_password, | |
| 550 | - unsigned char key[OU_key_bytes_V4]) const; | |
| 547 | + std::string compute_O_rc4_key( | |
| 548 | + std::string const& user_password, std::string const& owner_password) const; | |
| 551 | 549 | std::string compute_U_value_R2(std::string const& user_password) const; |
| 552 | 550 | std::string compute_U_value_R3(std::string const& user_password) const; |
| 553 | 551 | bool check_user_password_V4(std::string const& user_password) const; | ... | ... |
libqpdf/QPDF_encryption.cc
| ... | ... | @@ -427,11 +427,9 @@ QPDF::EncryptionData::compute_encryption_key_from_password(std::string const& pa |
| 427 | 427 | return {reinterpret_cast<char*>(digest), toS(key_len)}; |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | -void | |
| 430 | +std::string | |
| 431 | 431 | QPDF::EncryptionData::compute_O_rc4_key( |
| 432 | - std::string const& user_password, | |
| 433 | - std::string const& owner_password, | |
| 434 | - unsigned char key[OU_key_bytes_V4]) const | |
| 432 | + std::string const& user_password, std::string const& owner_password) const | |
| 435 | 433 | { |
| 436 | 434 | if (getV() >= 5) { |
| 437 | 435 | throw std::logic_error("compute_O_rc4_key called for file with V >= 5"); |
| ... | ... | @@ -445,7 +443,7 @@ QPDF::EncryptionData::compute_O_rc4_key( |
| 445 | 443 | MD5::Digest digest; |
| 446 | 444 | int key_len = std::min(QIntC::to_int(sizeof(digest)), getLengthBytes()); |
| 447 | 445 | iterate_md5_digest(md5, digest, (getR() >= 3 ? 50 : 0), key_len); |
| 448 | - memcpy(key, digest, OU_key_bytes_V4); | |
| 446 | + return {reinterpret_cast<const char*>(digest), OU_key_bytes_V4}; | |
| 449 | 447 | } |
| 450 | 448 | |
| 451 | 449 | std::string |
| ... | ... | @@ -454,16 +452,13 @@ QPDF::EncryptionData::compute_O_value( |
| 454 | 452 | { |
| 455 | 453 | // Algorithm 3.3 from the PDF 1.7 Reference Manual |
| 456 | 454 | |
| 457 | - unsigned char O_key[OU_key_bytes_V4]; | |
| 458 | - compute_O_rc4_key(user_password, owner_password, O_key); | |
| 459 | - | |
| 460 | 455 | auto upass = pad_or_truncate_password_V4(user_password); |
| 461 | - std::string k1(reinterpret_cast<char*>(O_key), OU_key_bytes_V4); | |
| 462 | - pad_short_parameter(k1, QIntC::to_size(getLengthBytes())); | |
| 456 | + std::string O_key = compute_O_rc4_key(user_password, owner_password); | |
| 457 | + pad_short_parameter(O_key, QIntC::to_size(getLengthBytes())); | |
| 463 | 458 | iterate_rc4( |
| 464 | 459 | QUtil::unsigned_char_pointer(upass), |
| 465 | 460 | key_bytes, |
| 466 | - O_key, | |
| 461 | + QUtil::unsigned_char_pointer(O_key.data()), | |
| 467 | 462 | getLengthBytes(), |
| 468 | 463 | getR() >= 3 ? 20 : 1, |
| 469 | 464 | false); |
| ... | ... | @@ -558,20 +553,16 @@ QPDF::EncryptionData::check_owner_password_V4( |
| 558 | 553 | { |
| 559 | 554 | // Algorithm 3.7 from the PDF 1.7 Reference Manual |
| 560 | 555 | |
| 561 | - unsigned char key[OU_key_bytes_V4]; | |
| 562 | - compute_O_rc4_key(user_password, owner_password, key); | |
| 563 | - unsigned char O_data[key_bytes]; | |
| 564 | - memcpy(O_data, QUtil::unsigned_char_pointer(getO()), key_bytes); | |
| 565 | - std::string k1(reinterpret_cast<char*>(key), OU_key_bytes_V4); | |
| 566 | - pad_short_parameter(k1, QIntC::to_size(getLengthBytes())); | |
| 556 | + auto key = compute_O_rc4_key(user_password, owner_password); | |
| 557 | + pad_short_parameter(key, QIntC::to_size(getLengthBytes())); | |
| 558 | + auto new_user_password = O.substr(0, key_bytes); | |
| 567 | 559 | iterate_rc4( |
| 568 | - O_data, | |
| 560 | + QUtil::unsigned_char_pointer(new_user_password.data()), | |
| 569 | 561 | key_bytes, |
| 570 | - QUtil::unsigned_char_pointer(k1), | |
| 562 | + QUtil::unsigned_char_pointer(key), | |
| 571 | 563 | getLengthBytes(), |
| 572 | 564 | (getR() >= 3) ? 20 : 1, |
| 573 | 565 | true); |
| 574 | - std::string new_user_password = std::string(reinterpret_cast<char*>(O_data), key_bytes); | |
| 575 | 566 | if (check_user_password(new_user_password)) { |
| 576 | 567 | user_password = new_user_password; |
| 577 | 568 | return true; | ... | ... |