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,10 +544,8 @@ class QPDF | ||
| 544 | std::string& user_password, std::string const& owner_password) const; | 544 | std::string& user_password, std::string const& owner_password) const; |
| 545 | bool check_owner_password_V5(std::string const& owner_passworda) const; | 545 | bool check_owner_password_V5(std::string const& owner_passworda) const; |
| 546 | std::string compute_Perms_value_V5_clear() const; | 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 | std::string compute_U_value_R2(std::string const& user_password) const; | 549 | std::string compute_U_value_R2(std::string const& user_password) const; |
| 552 | std::string compute_U_value_R3(std::string const& user_password) const; | 550 | std::string compute_U_value_R3(std::string const& user_password) const; |
| 553 | bool check_user_password_V4(std::string const& user_password) const; | 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,11 +427,9 @@ QPDF::EncryptionData::compute_encryption_key_from_password(std::string const& pa | ||
| 427 | return {reinterpret_cast<char*>(digest), toS(key_len)}; | 427 | return {reinterpret_cast<char*>(digest), toS(key_len)}; |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | -void | 430 | +std::string |
| 431 | QPDF::EncryptionData::compute_O_rc4_key( | 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 | if (getV() >= 5) { | 434 | if (getV() >= 5) { |
| 437 | throw std::logic_error("compute_O_rc4_key called for file with V >= 5"); | 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,7 +443,7 @@ QPDF::EncryptionData::compute_O_rc4_key( | ||
| 445 | MD5::Digest digest; | 443 | MD5::Digest digest; |
| 446 | int key_len = std::min(QIntC::to_int(sizeof(digest)), getLengthBytes()); | 444 | int key_len = std::min(QIntC::to_int(sizeof(digest)), getLengthBytes()); |
| 447 | iterate_md5_digest(md5, digest, (getR() >= 3 ? 50 : 0), key_len); | 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 | std::string | 449 | std::string |
| @@ -454,16 +452,13 @@ QPDF::EncryptionData::compute_O_value( | @@ -454,16 +452,13 @@ QPDF::EncryptionData::compute_O_value( | ||
| 454 | { | 452 | { |
| 455 | // Algorithm 3.3 from the PDF 1.7 Reference Manual | 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 | auto upass = pad_or_truncate_password_V4(user_password); | 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 | iterate_rc4( | 458 | iterate_rc4( |
| 464 | QUtil::unsigned_char_pointer(upass), | 459 | QUtil::unsigned_char_pointer(upass), |
| 465 | key_bytes, | 460 | key_bytes, |
| 466 | - O_key, | 461 | + QUtil::unsigned_char_pointer(O_key.data()), |
| 467 | getLengthBytes(), | 462 | getLengthBytes(), |
| 468 | getR() >= 3 ? 20 : 1, | 463 | getR() >= 3 ? 20 : 1, |
| 469 | false); | 464 | false); |
| @@ -558,20 +553,16 @@ QPDF::EncryptionData::check_owner_password_V4( | @@ -558,20 +553,16 @@ QPDF::EncryptionData::check_owner_password_V4( | ||
| 558 | { | 553 | { |
| 559 | // Algorithm 3.7 from the PDF 1.7 Reference Manual | 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 | iterate_rc4( | 559 | iterate_rc4( |
| 568 | - O_data, | 560 | + QUtil::unsigned_char_pointer(new_user_password.data()), |
| 569 | key_bytes, | 561 | key_bytes, |
| 570 | - QUtil::unsigned_char_pointer(k1), | 562 | + QUtil::unsigned_char_pointer(key), |
| 571 | getLengthBytes(), | 563 | getLengthBytes(), |
| 572 | (getR() >= 3) ? 20 : 1, | 564 | (getR() >= 3) ? 20 : 1, |
| 573 | true); | 565 | true); |
| 574 | - std::string new_user_password = std::string(reinterpret_cast<char*>(O_data), key_bytes); | ||
| 575 | if (check_user_password(new_user_password)) { | 566 | if (check_user_password(new_user_password)) { |
| 576 | user_password = new_user_password; | 567 | user_password = new_user_password; |
| 577 | return true; | 568 | return true; |