Commit c8fd2f9bd95f82b403587370c63c2ab8c7f24682
1 parent
4635a59e
Refactor encryption data methods to reduce redundancy, streamline parameter hand…
…ling, and improve maintainability.
Showing
3 changed files
with
63 additions
and
72 deletions
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& | ... | ... |