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