Commit c8fd2f9bd95f82b403587370c63c2ab8c7f24682

Authored by m-holger
1 parent 4635a59e

Refactor encryption data methods to reduce redundancy, streamline parameter hand…

…ling, and improve maintainability.
include/qpdf/QPDF.hh
@@ -511,18 +511,12 @@ class QPDF @@ -511,18 +511,12 @@ class QPDF
511 std::string 511 std::string
512 recover_encryption_key_with_password(std::string const& password, bool& perms_valid) const; 512 recover_encryption_key_with_password(std::string const& password, bool& perms_valid) const;
513 513
514 - void compute_encryption_O_U(  
515 - char const* user_password, char const* owner_password, std::string& O, std::string& U);  
516 -  
517 - void compute_encryption_parameters_V5(  
518 - char const* user_password,  
519 - char const* owner_password,  
520 - std::string& encryption_key,  
521 - std::string& O,  
522 - std::string& U,  
523 - std::string& OE,  
524 - std::string& UE,  
525 - std::string& Perms); 514 + void compute_encryption_O_U(char const* user_password, char const* owner_password);
  515 +
  516 + std::string
  517 + compute_encryption_parameters_V5(char const* user_password, char const* owner_password);
  518 +
  519 + std::string compute_parameters(char const* user_password, char const* owner_password);
526 520
527 private: 521 private:
528 static constexpr unsigned int OU_key_bytes_V4 = 16; // ( == sizeof(MD5::Digest) 522 static constexpr unsigned int OU_key_bytes_V4 = 16; // ( == sizeof(MD5::Digest)
libqpdf/QPDFWriter.cc
@@ -619,34 +619,22 @@ QPDFWriter::setEncryptionParameters( @@ -619,34 +619,22 @@ QPDFWriter::setEncryptionParameters(
619 P = ~P; 619 P = ~P;
620 620
621 generateID(); 621 generateID();
622 - std::string O;  
623 - std::string U;  
624 - std::string OE;  
625 - std::string UE;  
626 - std::string Perms;  
627 - std::string encryption_key;  
628 - if (V < 5) {  
629 - QPDF::compute_encryption_O_U(  
630 - user_password, owner_password, V, R, key_len, P, m->encrypt_metadata, m->id1, O, U);  
631 - } else {  
632 - QPDF::compute_encryption_parameters_V5(  
633 - user_password,  
634 - owner_password,  
635 - V,  
636 - R,  
637 - key_len,  
638 - P,  
639 - m->encrypt_metadata,  
640 - m->id1,  
641 - encryption_key,  
642 - O,  
643 - U,  
644 - OE,  
645 - UE,  
646 - Perms);  
647 - } 622 + QPDF::EncryptionData encryption_data(
  623 + V, R, key_len, P, "", "", "", "", "", m->id1, m->encrypt_metadata);
  624 + auto encryption_key = encryption_data.compute_parameters(user_password, owner_password);
648 setEncryptionParametersInternal( 625 setEncryptionParametersInternal(
649 - V, R, key_len, P, O, U, OE, UE, Perms, m->id1, user_password, encryption_key); 626 + V,
  627 + R,
  628 + key_len,
  629 + P,
  630 + encryption_data.getO(),
  631 + encryption_data.getU(),
  632 + encryption_data.getOE(),
  633 + encryption_data.getUE(),
  634 + encryption_data.getPerms(),
  635 + m->id1,
  636 + user_password,
  637 + encryption_key);
650 } 638 }
651 639
652 void 640 void
libqpdf/QPDF_encryption.cc
@@ -1116,23 +1116,23 @@ QPDF::compute_encryption_O_U( @@ -1116,23 +1116,23 @@ QPDF::compute_encryption_O_U(
1116 int P, 1116 int P,
1117 bool encrypt_metadata, 1117 bool encrypt_metadata,
1118 std::string const& id1, 1118 std::string const& id1,
1119 - std::string& O,  
1120 - std::string& U) 1119 + std::string& out_O,
  1120 + std::string& out_U)
1121 { 1121 {
1122 - EncryptionData(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata)  
1123 - .compute_encryption_O_U(user_password, owner_password, O, U); 1122 + EncryptionData data(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata);
  1123 + data.compute_encryption_O_U(user_password, owner_password);
  1124 + out_O = data.getO();
  1125 + out_U = data.getU();
1124 } 1126 }
1125 1127
1126 void 1128 void
1127 -QPDF::EncryptionData::compute_encryption_O_U(  
1128 - char const* user_password, char const* owner_password, std::string& out_O, std::string& out_U) 1129 +QPDF::EncryptionData::compute_encryption_O_U(char const* user_password, char const* owner_password)
1129 { 1130 {
1130 if (V >= 5) { 1131 if (V >= 5) {
1131 throw std::logic_error("compute_encryption_O_U called for file with V >= 5"); 1132 throw std::logic_error("compute_encryption_O_U called for file with V >= 5");
1132 } 1133 }
1133 - setO(compute_O_value(user_password, owner_password));  
1134 - out_O = getO();  
1135 - out_U = compute_U_value(user_password); 1134 + O = compute_O_value(user_password, owner_password);
  1135 + U = compute_U_value(user_password);
1136 } 1136 }
1137 1137
1138 void 1138 void
@@ -1146,44 +1146,53 @@ QPDF::compute_encryption_parameters_V5( @@ -1146,44 +1146,53 @@ QPDF::compute_encryption_parameters_V5(
1146 bool encrypt_metadata, 1146 bool encrypt_metadata,
1147 std::string const& id1, 1147 std::string const& id1,
1148 std::string& encryption_key, 1148 std::string& encryption_key,
1149 - std::string& O,  
1150 - std::string& U,  
1151 - std::string& OE,  
1152 - std::string& UE,  
1153 - std::string& Perms)  
1154 -{  
1155 - EncryptionData(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata)  
1156 - .compute_encryption_parameters_V5(  
1157 - user_password, owner_password, encryption_key, O, U, OE, UE, Perms);  
1158 -}  
1159 -  
1160 -void  
1161 -QPDF::EncryptionData::compute_encryption_parameters_V5(  
1162 - char const* user_password,  
1163 - char const* owner_password,  
1164 - std::string& out_encryption_key,  
1165 std::string& out_O, 1149 std::string& out_O,
1166 std::string& out_U, 1150 std::string& out_U,
1167 std::string& out_OE, 1151 std::string& out_OE,
1168 std::string& out_UE, 1152 std::string& out_UE,
1169 std::string& out_Perms) 1153 std::string& out_Perms)
1170 { 1154 {
1171 - out_encryption_key = util::random_string(key_bytes); 1155 + EncryptionData data(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata);
  1156 + encryption_key = data.compute_encryption_parameters_V5(user_password, owner_password);
  1157 +
  1158 + out_O = data.getO();
  1159 + out_U = data.getU();
  1160 + out_OE = data.getOE();
  1161 + out_UE = data.getUE();
  1162 + out_Perms = data.getPerms();
  1163 +}
  1164 +
  1165 +std::string
  1166 +QPDF::EncryptionData::compute_encryption_parameters_V5(
  1167 + char const* user_password, char const* owner_password)
  1168 +{
  1169 + auto out_encryption_key = util::random_string(key_bytes);
1172 // Algorithm 8 from the PDF 2.0 1170 // Algorithm 8 from the PDF 2.0
1173 auto validation_salt = util::random_string(8); 1171 auto validation_salt = util::random_string(8);
1174 auto key_salt = util::random_string(8); 1172 auto key_salt = util::random_string(8);
1175 - out_U = hash_V5(user_password, validation_salt, "").append(validation_salt).append(key_salt); 1173 + U = hash_V5(user_password, validation_salt, "").append(validation_salt).append(key_salt);
1176 auto intermediate_key = hash_V5(user_password, key_salt, ""); 1174 auto intermediate_key = hash_V5(user_password, key_salt, "");
1177 - out_UE = process_with_aes(intermediate_key, true, out_encryption_key); 1175 + UE = process_with_aes(intermediate_key, true, out_encryption_key);
1178 // Algorithm 9 from the PDF 2.0 1176 // Algorithm 9 from the PDF 2.0
1179 validation_salt = util::random_string(8); 1177 validation_salt = util::random_string(8);
1180 key_salt = util::random_string(8); 1178 key_salt = util::random_string(8);
1181 - out_O = hash_V5(owner_password, validation_salt, out_U) + validation_salt + key_salt;  
1182 - intermediate_key = hash_V5(owner_password, key_salt, out_U);  
1183 - out_OE = process_with_aes(intermediate_key, true, out_encryption_key); 1179 + O = hash_V5(owner_password, validation_salt, U) + validation_salt + key_salt;
  1180 + intermediate_key = hash_V5(owner_password, key_salt, U);
  1181 + OE = process_with_aes(intermediate_key, true, out_encryption_key);
1184 // Algorithm 10 from the PDF 2.0 1182 // Algorithm 10 from the PDF 2.0
1185 - out_Perms = process_with_aes(out_encryption_key, true, compute_Perms_value_V5_clear());  
1186 - setV5EncryptionParameters(out_O, out_OE, out_U, out_UE, out_Perms); 1183 + Perms = process_with_aes(out_encryption_key, true, compute_Perms_value_V5_clear());
  1184 + return out_encryption_key;
  1185 +}
  1186 +
  1187 +std::string
  1188 +QPDF::EncryptionData::compute_parameters(char const* user_password, char const* owner_password)
  1189 +{
  1190 + if (V < 5) {
  1191 + compute_encryption_O_U(user_password, owner_password);
  1192 + return {};
  1193 + } else {
  1194 + return compute_encryption_parameters_V5(user_password, owner_password);
  1195 + }
1187 } 1196 }
1188 1197
1189 std::string const& 1198 std::string const&