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,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;