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 511 std::string
512 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 521 private:
528 522 static constexpr unsigned int OU_key_bytes_V4 = 16; // ( == sizeof(MD5::Digest)
... ...
libqpdf/QPDFWriter.cc
... ... @@ -619,34 +619,22 @@ QPDFWriter::setEncryptionParameters(
619 619 P = ~P;
620 620  
621 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 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 640 void
... ...
libqpdf/QPDF_encryption.cc
... ... @@ -1116,23 +1116,23 @@ QPDF::compute_encryption_O_U(
1116 1116 int P,
1117 1117 bool encrypt_metadata,
1118 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 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 1131 if (V >= 5) {
1131 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 1138 void
... ... @@ -1146,44 +1146,53 @@ QPDF::compute_encryption_parameters_V5(
1146 1146 bool encrypt_metadata,
1147 1147 std::string const& id1,
1148 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 1149 std::string& out_O,
1166 1150 std::string& out_U,
1167 1151 std::string& out_OE,
1168 1152 std::string& out_UE,
1169 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 1170 // Algorithm 8 from the PDF 2.0
1173 1171 auto validation_salt = util::random_string(8);
1174 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 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 1176 // Algorithm 9 from the PDF 2.0
1179 1177 validation_salt = util::random_string(8);
1180 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 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 1198 std::string const&
... ...