Commit e623caf264ce989aa74c98496b13c6fc01209d95

Authored by m-holger
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.
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;
... ...