Commit d6ce922e4f03fd32940ce22f59997ffdc4f39100
1 parent
070b38bf
Refactor `QPDF::EncryptionData`: move to private `QPDF::Doc::Encryption` and update references.
Showing
4 changed files
with
276 additions
and
101 deletions
include/qpdf/QPDF.hh
| ... | ... | @@ -472,7 +472,7 @@ class QPDF |
| 472 | 472 | V(V), |
| 473 | 473 | R(R), |
| 474 | 474 | Length_bytes(Length_bytes), |
| 475 | - P(static_cast<unsigned long long>(P)), | |
| 475 | + P(P), | |
| 476 | 476 | O(O), |
| 477 | 477 | U(U), |
| 478 | 478 | OE(OE), |
| ... | ... | @@ -482,20 +482,11 @@ class QPDF |
| 482 | 482 | encrypt_metadata(encrypt_metadata) |
| 483 | 483 | { |
| 484 | 484 | } |
| 485 | - EncryptionData(int V, int R, int Length_bytes, bool encrypt_metadata) : | |
| 486 | - V(V), | |
| 487 | - R(R), | |
| 488 | - Length_bytes(Length_bytes), | |
| 489 | - encrypt_metadata(encrypt_metadata) | |
| 490 | - { | |
| 491 | - } | |
| 492 | 485 | |
| 493 | 486 | int getV() const; |
| 494 | 487 | int getR() const; |
| 495 | 488 | int getLengthBytes() const; |
| 496 | 489 | int getP() const; |
| 497 | - // Bits in P are numbered from 1 as in the PDF spec. | |
| 498 | - bool getP(size_t bit) const; | |
| 499 | 490 | std::string const& getO() const; |
| 500 | 491 | std::string const& getU() const; |
| 501 | 492 | std::string const& getOE() const; |
| ... | ... | @@ -503,12 +494,9 @@ class QPDF |
| 503 | 494 | std::string const& getPerms() const; |
| 504 | 495 | std::string const& getId1() const; |
| 505 | 496 | bool getEncryptMetadata() const; |
| 506 | - // Bits in P are numbered from 1 as in the PDF spec. | |
| 507 | - void setP(size_t bit, bool val); | |
| 508 | - void setP(unsigned long val); | |
| 497 | + | |
| 509 | 498 | void setO(std::string const&); |
| 510 | 499 | void setU(std::string const&); |
| 511 | - void setId1(std::string const& val); | |
| 512 | 500 | void setV5EncryptionParameters( |
| 513 | 501 | std::string const& O, |
| 514 | 502 | std::string const& OE, |
| ... | ... | @@ -516,51 +504,14 @@ class QPDF |
| 516 | 504 | std::string const& UE, |
| 517 | 505 | std::string const& Perms); |
| 518 | 506 | |
| 519 | - std::string compute_encryption_key(std::string const& password) const; | |
| 520 | - | |
| 521 | - bool | |
| 522 | - check_owner_password(std::string& user_password, std::string const& owner_password) const; | |
| 523 | - | |
| 524 | - bool check_user_password(std::string const& user_password) const; | |
| 525 | - | |
| 526 | - std::string | |
| 527 | - recover_encryption_key_with_password(std::string const& password, bool& perms_valid) const; | |
| 528 | - | |
| 529 | - void compute_encryption_O_U(char const* user_password, char const* owner_password); | |
| 530 | - | |
| 531 | - std::string | |
| 532 | - compute_encryption_parameters_V5(char const* user_password, char const* owner_password); | |
| 533 | - | |
| 534 | - std::string compute_parameters(char const* user_password, char const* owner_password); | |
| 535 | - | |
| 536 | 507 | private: |
| 537 | - static constexpr unsigned int OU_key_bytes_V4 = 16; // ( == sizeof(MD5::Digest) | |
| 538 | - | |
| 539 | 508 | EncryptionData(EncryptionData const&) = delete; |
| 540 | 509 | EncryptionData& operator=(EncryptionData const&) = delete; |
| 541 | 510 | |
| 542 | - std::string hash_V5( | |
| 543 | - std::string const& password, std::string const& salt, std::string const& udata) const; | |
| 544 | - std::string | |
| 545 | - compute_O_value(std::string const& user_password, std::string const& owner_password) const; | |
| 546 | - std::string compute_U_value(std::string const& user_password) const; | |
| 547 | - std::string compute_encryption_key_from_password(std::string const& password) const; | |
| 548 | - std::string recover_encryption_key_with_password(std::string const& password) const; | |
| 549 | - bool check_owner_password_V4( | |
| 550 | - std::string& user_password, std::string const& owner_password) const; | |
| 551 | - bool check_owner_password_V5(std::string const& owner_passworda) const; | |
| 552 | - std::string compute_Perms_value_V5_clear() const; | |
| 553 | - std::string compute_O_rc4_key( | |
| 554 | - std::string const& user_password, std::string const& owner_password) const; | |
| 555 | - std::string compute_U_value_R2(std::string const& user_password) const; | |
| 556 | - std::string compute_U_value_R3(std::string const& user_password) const; | |
| 557 | - bool check_user_password_V4(std::string const& user_password) const; | |
| 558 | - bool check_user_password_V5(std::string const& user_password) const; | |
| 559 | - | |
| 560 | 511 | int V; |
| 561 | 512 | int R; |
| 562 | 513 | int Length_bytes; |
| 563 | - std::bitset<32> P{0xfffffffc}; // Specification always requires bits 1 and 2 to be cleared. | |
| 514 | + int P; | |
| 564 | 515 | std::string O; |
| 565 | 516 | std::string U; |
| 566 | 517 | std::string OE; |
| ... | ... | @@ -569,7 +520,6 @@ class QPDF |
| 569 | 520 | std::string id1; |
| 570 | 521 | bool encrypt_metadata; |
| 571 | 522 | }; |
| 572 | - | |
| 573 | 523 | QPDF_DLL |
| 574 | 524 | bool isEncrypted() const; |
| 575 | 525 | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -27,6 +27,8 @@ |
| 27 | 27 | using namespace std::literals; |
| 28 | 28 | using namespace qpdf; |
| 29 | 29 | |
| 30 | +using Encryption = QPDF::Doc::Encryption; | |
| 31 | + | |
| 30 | 32 | QPDFWriter::ProgressReporter::~ProgressReporter() // NOLINT (modernize-use-equals-default) |
| 31 | 33 | { |
| 32 | 34 | // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer |
| ... | ... | @@ -504,7 +506,7 @@ class QPDFWriter::Members: QPDF::Doc::Writer |
| 504 | 506 | bool pclm{false}; |
| 505 | 507 | qpdf_object_stream_e object_stream_mode{qpdf_o_preserve}; |
| 506 | 508 | |
| 507 | - std::unique_ptr<QPDF::EncryptionData> encryption; | |
| 509 | + std::unique_ptr<QPDF::Doc::Encryption> encryption; | |
| 508 | 510 | std::string encryption_key; |
| 509 | 511 | bool encrypt_use_aes{false}; |
| 510 | 512 | |
| ... | ... | @@ -829,7 +831,7 @@ QPDFWriter::setR2EncryptionParametersInsecure( |
| 829 | 831 | bool allow_extract, |
| 830 | 832 | bool allow_annotate) |
| 831 | 833 | { |
| 832 | - m->encryption = std::make_unique<QPDF::EncryptionData>(1, 2, 5, true); | |
| 834 | + m->encryption = std::make_unique<Encryption>(1, 2, 5, true); | |
| 833 | 835 | if (!allow_print) { |
| 834 | 836 | m->encryption->setP(3, false); |
| 835 | 837 | } |
| ... | ... | @@ -857,7 +859,7 @@ QPDFWriter::setR3EncryptionParametersInsecure( |
| 857 | 859 | bool allow_modify_other, |
| 858 | 860 | qpdf_r3_print_e print) |
| 859 | 861 | { |
| 860 | - m->encryption = std::make_unique<QPDF::EncryptionData>(2, 3, 16, true); | |
| 862 | + m->encryption = std::make_unique<Encryption>(2, 3, 16, true); | |
| 861 | 863 | m->interpretR3EncryptionParameters( |
| 862 | 864 | allow_accessibility, |
| 863 | 865 | allow_extract, |
| ... | ... | @@ -884,7 +886,7 @@ QPDFWriter::setR4EncryptionParametersInsecure( |
| 884 | 886 | bool encrypt_metadata, |
| 885 | 887 | bool use_aes) |
| 886 | 888 | { |
| 887 | - m->encryption = std::make_unique<QPDF::EncryptionData>(4, 4, 16, encrypt_metadata); | |
| 889 | + m->encryption = std::make_unique<Encryption>(4, 4, 16, encrypt_metadata); | |
| 888 | 890 | m->encrypt_use_aes = use_aes; |
| 889 | 891 | m->interpretR3EncryptionParameters( |
| 890 | 892 | allow_accessibility, |
| ... | ... | @@ -911,7 +913,7 @@ QPDFWriter::setR5EncryptionParameters( |
| 911 | 913 | qpdf_r3_print_e print, |
| 912 | 914 | bool encrypt_metadata) |
| 913 | 915 | { |
| 914 | - m->encryption = std::make_unique<QPDF::EncryptionData>(5, 5, 32, encrypt_metadata); | |
| 916 | + m->encryption = std::make_unique<Encryption>(5, 5, 32, encrypt_metadata); | |
| 915 | 917 | m->encrypt_use_aes = true; |
| 916 | 918 | m->interpretR3EncryptionParameters( |
| 917 | 919 | allow_accessibility, |
| ... | ... | @@ -938,7 +940,7 @@ QPDFWriter::setR6EncryptionParameters( |
| 938 | 940 | qpdf_r3_print_e print, |
| 939 | 941 | bool encrypt_metadata) |
| 940 | 942 | { |
| 941 | - m->encryption = std::make_unique<QPDF::EncryptionData>(5, 6, 32, encrypt_metadata); | |
| 943 | + m->encryption = std::make_unique<Encryption>(5, 6, 32, encrypt_metadata); | |
| 942 | 944 | m->interpretR3EncryptionParameters( |
| 943 | 945 | allow_accessibility, |
| 944 | 946 | allow_extract, |
| ... | ... | @@ -1094,7 +1096,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) |
| 1094 | 1096 | QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", encrypt_metadata ? 0 : 1); |
| 1095 | 1097 | QTC::TC("qpdf", "QPDFWriter copy use_aes", encrypt_use_aes ? 0 : 1); |
| 1096 | 1098 | |
| 1097 | - encryption = std::make_unique<QPDF::EncryptionData>( | |
| 1099 | + encryption = std::make_unique<Encryption>( | |
| 1098 | 1100 | V, |
| 1099 | 1101 | encrypt.getKey("/R").getIntValueAsInt(), |
| 1100 | 1102 | key_len, | ... | ... |
libqpdf/QPDF_encryption.cc
| ... | ... | @@ -21,6 +21,8 @@ |
| 21 | 21 | using namespace qpdf; |
| 22 | 22 | using namespace std::literals; |
| 23 | 23 | |
| 24 | +using Encryption = QPDF::Doc::Encryption; | |
| 25 | + | |
| 24 | 26 | static std::string padding_string = |
| 25 | 27 | "\x28\xbf\x4e\x5e\x4e\x75\x8a\x41\x64\x00\x4e\x56\xff\xfa\x01\x08" |
| 26 | 28 | "\x2e\x2e\x00\xb6\xd0\x68\x3e\x80\x2f\x0c\xa9\xfe\x64\x53\x69\x7a"s; |
| ... | ... | @@ -52,11 +54,104 @@ QPDF::EncryptionData::getLengthBytes() const |
| 52 | 54 | int |
| 53 | 55 | QPDF::EncryptionData::getP() const |
| 54 | 56 | { |
| 57 | + return this->P; | |
| 58 | +} | |
| 59 | + | |
| 60 | +std::string const& | |
| 61 | +QPDF::EncryptionData::getO() const | |
| 62 | +{ | |
| 63 | + return this->O; | |
| 64 | +} | |
| 65 | + | |
| 66 | +std::string const& | |
| 67 | +QPDF::EncryptionData::getU() const | |
| 68 | +{ | |
| 69 | + return this->U; | |
| 70 | +} | |
| 71 | + | |
| 72 | +std::string const& | |
| 73 | +QPDF::EncryptionData::getOE() const | |
| 74 | +{ | |
| 75 | + return this->OE; | |
| 76 | +} | |
| 77 | + | |
| 78 | +std::string const& | |
| 79 | +QPDF::EncryptionData::getUE() const | |
| 80 | +{ | |
| 81 | + return this->UE; | |
| 82 | +} | |
| 83 | + | |
| 84 | +std::string const& | |
| 85 | +QPDF::EncryptionData::getPerms() const | |
| 86 | +{ | |
| 87 | + return this->Perms; | |
| 88 | +} | |
| 89 | + | |
| 90 | +std::string const& | |
| 91 | +QPDF::EncryptionData::getId1() const | |
| 92 | +{ | |
| 93 | + return this->id1; | |
| 94 | +} | |
| 95 | + | |
| 96 | +bool | |
| 97 | +QPDF::EncryptionData::getEncryptMetadata() const | |
| 98 | +{ | |
| 99 | + return this->encrypt_metadata; | |
| 100 | +} | |
| 101 | + | |
| 102 | +void | |
| 103 | +QPDF::EncryptionData::setO(std::string const& O) | |
| 104 | +{ | |
| 105 | + this->O = O; | |
| 106 | +} | |
| 107 | + | |
| 108 | +void | |
| 109 | +QPDF::EncryptionData::setU(std::string const& U) | |
| 110 | +{ | |
| 111 | + this->U = U; | |
| 112 | +} | |
| 113 | + | |
| 114 | +void | |
| 115 | +QPDF::EncryptionData::setV5EncryptionParameters( | |
| 116 | + std::string const& O, | |
| 117 | + std::string const& OE, | |
| 118 | + std::string const& U, | |
| 119 | + std::string const& UE, | |
| 120 | + std::string const& Perms) | |
| 121 | +{ | |
| 122 | + this->O = O; | |
| 123 | + this->OE = OE; | |
| 124 | + this->U = U; | |
| 125 | + this->UE = UE; | |
| 126 | + this->Perms = Perms; | |
| 127 | +} | |
| 128 | + | |
| 129 | +int | |
| 130 | +Encryption::getV() const | |
| 131 | +{ | |
| 132 | + return this->V; | |
| 133 | +} | |
| 134 | + | |
| 135 | +int | |
| 136 | +Encryption::getR() const | |
| 137 | +{ | |
| 138 | + return this->R; | |
| 139 | +} | |
| 140 | + | |
| 141 | +int | |
| 142 | +Encryption::getLengthBytes() const | |
| 143 | +{ | |
| 144 | + return this->Length_bytes; | |
| 145 | +} | |
| 146 | + | |
| 147 | +int | |
| 148 | +Encryption::getP() const | |
| 149 | +{ | |
| 55 | 150 | return static_cast<int>(P.to_ulong()); |
| 56 | 151 | } |
| 57 | 152 | |
| 58 | 153 | bool |
| 59 | -QPDF::EncryptionData::getP(size_t bit) const | |
| 154 | +Encryption::getP(size_t bit) const | |
| 60 | 155 | { |
| 61 | 156 | qpdf_assert_debug(bit); |
| 62 | 157 | return P.test(bit - 1); |
| ... | ... | @@ -70,80 +165,80 @@ QPDF::EncryptionParameters::P(size_t bit) const |
| 70 | 165 | } |
| 71 | 166 | |
| 72 | 167 | std::string const& |
| 73 | -QPDF::EncryptionData::getO() const | |
| 168 | +Encryption::getO() const | |
| 74 | 169 | { |
| 75 | 170 | return this->O; |
| 76 | 171 | } |
| 77 | 172 | |
| 78 | 173 | std::string const& |
| 79 | -QPDF::EncryptionData::getU() const | |
| 174 | +Encryption::getU() const | |
| 80 | 175 | { |
| 81 | 176 | return this->U; |
| 82 | 177 | } |
| 83 | 178 | |
| 84 | 179 | std::string const& |
| 85 | -QPDF::EncryptionData::getOE() const | |
| 180 | +Encryption::getOE() const | |
| 86 | 181 | { |
| 87 | 182 | return this->OE; |
| 88 | 183 | } |
| 89 | 184 | |
| 90 | 185 | std::string const& |
| 91 | -QPDF::EncryptionData::getUE() const | |
| 186 | +Encryption::getUE() const | |
| 92 | 187 | { |
| 93 | 188 | return this->UE; |
| 94 | 189 | } |
| 95 | 190 | |
| 96 | 191 | std::string const& |
| 97 | -QPDF::EncryptionData::getPerms() const | |
| 192 | +Encryption::getPerms() const | |
| 98 | 193 | { |
| 99 | 194 | return this->Perms; |
| 100 | 195 | } |
| 101 | 196 | |
| 102 | 197 | std::string const& |
| 103 | -QPDF::EncryptionData::getId1() const | |
| 198 | +Encryption::getId1() const | |
| 104 | 199 | { |
| 105 | 200 | return this->id1; |
| 106 | 201 | } |
| 107 | 202 | |
| 108 | 203 | bool |
| 109 | -QPDF::EncryptionData::getEncryptMetadata() const | |
| 204 | +Encryption::getEncryptMetadata() const | |
| 110 | 205 | { |
| 111 | 206 | return this->encrypt_metadata; |
| 112 | 207 | } |
| 113 | 208 | |
| 114 | 209 | void |
| 115 | -QPDF::EncryptionData::setO(std::string const& O) | |
| 210 | +Encryption::setO(std::string const& O) | |
| 116 | 211 | { |
| 117 | 212 | this->O = O; |
| 118 | 213 | } |
| 119 | 214 | |
| 120 | 215 | void |
| 121 | -QPDF::EncryptionData::setU(std::string const& U) | |
| 216 | +Encryption::setU(std::string const& U) | |
| 122 | 217 | { |
| 123 | 218 | this->U = U; |
| 124 | 219 | } |
| 125 | 220 | |
| 126 | 221 | void |
| 127 | -QPDF::EncryptionData::setP(size_t bit, bool val) | |
| 222 | +Encryption::setP(size_t bit, bool val) | |
| 128 | 223 | { |
| 129 | 224 | qpdf_assert_debug(bit); |
| 130 | 225 | P.set(bit - 1, val); |
| 131 | 226 | } |
| 132 | 227 | |
| 133 | 228 | void |
| 134 | -QPDF::EncryptionData::setP(unsigned long val) | |
| 229 | +Encryption::setP(unsigned long val) | |
| 135 | 230 | { |
| 136 | 231 | P = std::bitset<32>(val); |
| 137 | 232 | } |
| 138 | 233 | |
| 139 | 234 | void |
| 140 | -QPDF::EncryptionData::setId1(std::string const& val) | |
| 235 | +Encryption::setId1(std::string const& val) | |
| 141 | 236 | { |
| 142 | 237 | id1 = val; |
| 143 | 238 | } |
| 144 | 239 | |
| 145 | 240 | void |
| 146 | -QPDF::EncryptionData::setV5EncryptionParameters( | |
| 241 | +Encryption::setV5EncryptionParameters( | |
| 147 | 242 | std::string const& O, |
| 148 | 243 | std::string const& OE, |
| 149 | 244 | std::string const& U, |
| ... | ... | @@ -246,7 +341,7 @@ process_with_aes( |
| 246 | 341 | } |
| 247 | 342 | |
| 248 | 343 | std::string |
| 249 | -QPDF::EncryptionData::hash_V5( | |
| 344 | +Encryption::hash_V5( | |
| 250 | 345 | std::string const& password, std::string const& salt, std::string const& udata) const |
| 251 | 346 | { |
| 252 | 347 | Pl_SHA2 hash(256); |
| ... | ... | @@ -358,13 +453,25 @@ QPDF::compute_data_key( |
| 358 | 453 | } |
| 359 | 454 | |
| 360 | 455 | std::string |
| 361 | -QPDF::compute_encryption_key(std::string const& password, EncryptionData const& data) | |
| 362 | -{ | |
| 363 | - return data.compute_encryption_key(password); | |
| 456 | +QPDF::compute_encryption_key(std::string const& password, EncryptionData const& ed) | |
| 457 | +{ | |
| 458 | + return Encryption( | |
| 459 | + ed.getV(), | |
| 460 | + ed.getR(), | |
| 461 | + ed.getLengthBytes(), | |
| 462 | + ed.getP(), | |
| 463 | + ed.getO(), | |
| 464 | + ed.getU(), | |
| 465 | + ed.getOE(), | |
| 466 | + ed.getUE(), | |
| 467 | + ed.getPerms(), | |
| 468 | + ed.getId1(), | |
| 469 | + ed.getEncryptMetadata()) | |
| 470 | + .compute_encryption_key(password); | |
| 364 | 471 | } |
| 365 | 472 | |
| 366 | 473 | std::string |
| 367 | -QPDF::EncryptionData::compute_encryption_key(std::string const& password) const | |
| 474 | +Encryption::compute_encryption_key(std::string const& password) const | |
| 368 | 475 | { |
| 369 | 476 | if (getV() >= 5) { |
| 370 | 477 | // For V >= 5, the encryption key is generated and stored in the file, encrypted separately |
| ... | ... | @@ -378,7 +485,7 @@ QPDF::EncryptionData::compute_encryption_key(std::string const& password) const |
| 378 | 485 | } |
| 379 | 486 | |
| 380 | 487 | std::string |
| 381 | -QPDF::EncryptionData::compute_encryption_key_from_password(std::string const& password) const | |
| 488 | +Encryption::compute_encryption_key_from_password(std::string const& password) const | |
| 382 | 489 | { |
| 383 | 490 | // Algorithm 3.2 from the PDF 1.7 Reference Manual |
| 384 | 491 | |
| ... | ... | @@ -405,7 +512,7 @@ QPDF::EncryptionData::compute_encryption_key_from_password(std::string const& pa |
| 405 | 512 | } |
| 406 | 513 | |
| 407 | 514 | std::string |
| 408 | -QPDF::EncryptionData::compute_O_rc4_key( | |
| 515 | +Encryption::compute_O_rc4_key( | |
| 409 | 516 | std::string const& user_password, std::string const& owner_password) const |
| 410 | 517 | { |
| 411 | 518 | if (getV() >= 5) { |
| ... | ... | @@ -418,7 +525,7 @@ QPDF::EncryptionData::compute_O_rc4_key( |
| 418 | 525 | } |
| 419 | 526 | |
| 420 | 527 | std::string |
| 421 | -QPDF::EncryptionData::compute_O_value( | |
| 528 | +Encryption::compute_O_value( | |
| 422 | 529 | std::string const& user_password, std::string const& owner_password) const |
| 423 | 530 | { |
| 424 | 531 | // Algorithm 3.3 from the PDF 1.7 Reference Manual |
| ... | ... | @@ -431,7 +538,7 @@ QPDF::EncryptionData::compute_O_value( |
| 431 | 538 | } |
| 432 | 539 | |
| 433 | 540 | std::string |
| 434 | -QPDF::EncryptionData::compute_U_value_R2(std::string const& user_password) const | |
| 541 | +Encryption::compute_U_value_R2(std::string const& user_password) const | |
| 435 | 542 | { |
| 436 | 543 | // Algorithm 3.4 from the PDF 1.7 Reference Manual |
| 437 | 544 | |
| ... | ... | @@ -443,7 +550,7 @@ QPDF::EncryptionData::compute_U_value_R2(std::string const& user_password) const |
| 443 | 550 | } |
| 444 | 551 | |
| 445 | 552 | std::string |
| 446 | -QPDF::EncryptionData::compute_U_value_R3(std::string const& user_password) const | |
| 553 | +Encryption::compute_U_value_R3(std::string const& user_password) const | |
| 447 | 554 | { |
| 448 | 555 | // Algorithm 3.5 from the PDF 1.7 Reference Manual |
| 449 | 556 | |
| ... | ... | @@ -460,7 +567,7 @@ QPDF::EncryptionData::compute_U_value_R3(std::string const& user_password) const |
| 460 | 567 | } |
| 461 | 568 | |
| 462 | 569 | std::string |
| 463 | -QPDF::EncryptionData::compute_U_value(std::string const& user_password) const | |
| 570 | +Encryption::compute_U_value(std::string const& user_password) const | |
| 464 | 571 | { |
| 465 | 572 | if (getR() >= 3) { |
| 466 | 573 | return compute_U_value_R3(user_password); |
| ... | ... | @@ -470,7 +577,7 @@ QPDF::EncryptionData::compute_U_value(std::string const& user_password) const |
| 470 | 577 | } |
| 471 | 578 | |
| 472 | 579 | bool |
| 473 | -QPDF::EncryptionData::check_user_password_V4(std::string const& user_password) const | |
| 580 | +Encryption::check_user_password_V4(std::string const& user_password) const | |
| 474 | 581 | { |
| 475 | 582 | // Algorithm 3.6 from the PDF 1.7 Reference Manual |
| 476 | 583 | |
| ... | ... | @@ -480,7 +587,7 @@ QPDF::EncryptionData::check_user_password_V4(std::string const& user_password) c |
| 480 | 587 | } |
| 481 | 588 | |
| 482 | 589 | bool |
| 483 | -QPDF::EncryptionData::check_user_password_V5(std::string const& user_password) const | |
| 590 | +Encryption::check_user_password_V5(std::string const& user_password) const | |
| 484 | 591 | { |
| 485 | 592 | // Algorithm 3.11 from the PDF 1.7 extension level 3 |
| 486 | 593 | |
| ... | ... | @@ -491,7 +598,7 @@ QPDF::EncryptionData::check_user_password_V5(std::string const& user_password) c |
| 491 | 598 | } |
| 492 | 599 | |
| 493 | 600 | bool |
| 494 | -QPDF::EncryptionData::check_user_password(std::string const& user_password) const | |
| 601 | +Encryption::check_user_password(std::string const& user_password) const | |
| 495 | 602 | { |
| 496 | 603 | if (getV() < 5) { |
| 497 | 604 | return check_user_password_V4(user_password); |
| ... | ... | @@ -501,7 +608,7 @@ QPDF::EncryptionData::check_user_password(std::string const& user_password) cons |
| 501 | 608 | } |
| 502 | 609 | |
| 503 | 610 | bool |
| 504 | -QPDF::EncryptionData::check_owner_password_V4( | |
| 611 | +Encryption::check_owner_password_V4( | |
| 505 | 612 | std::string& user_password, std::string const& owner_password) const |
| 506 | 613 | { |
| 507 | 614 | // Algorithm 3.7 from the PDF 1.7 Reference Manual |
| ... | ... | @@ -518,7 +625,7 @@ QPDF::EncryptionData::check_owner_password_V4( |
| 518 | 625 | } |
| 519 | 626 | |
| 520 | 627 | bool |
| 521 | -QPDF::EncryptionData::check_owner_password_V5(std::string const& owner_password) const | |
| 628 | +Encryption::check_owner_password_V5(std::string const& owner_password) const | |
| 522 | 629 | { |
| 523 | 630 | // Algorithm 3.12 from the PDF 1.7 extension level 3 |
| 524 | 631 | |
| ... | ... | @@ -529,7 +636,7 @@ QPDF::EncryptionData::check_owner_password_V5(std::string const& owner_password) |
| 529 | 636 | } |
| 530 | 637 | |
| 531 | 638 | bool |
| 532 | -QPDF::EncryptionData::check_owner_password( | |
| 639 | +Encryption::check_owner_password( | |
| 533 | 640 | std::string& user_password, std::string const& owner_password) const |
| 534 | 641 | { |
| 535 | 642 | if (getV() < 5) { |
| ... | ... | @@ -540,7 +647,7 @@ QPDF::EncryptionData::check_owner_password( |
| 540 | 647 | } |
| 541 | 648 | |
| 542 | 649 | std::string |
| 543 | -QPDF::EncryptionData::recover_encryption_key_with_password(std::string const& password) const | |
| 650 | +Encryption::recover_encryption_key_with_password(std::string const& password) const | |
| 544 | 651 | { |
| 545 | 652 | // Disregard whether Perms is valid. |
| 546 | 653 | bool disregard; |
| ... | ... | @@ -548,7 +655,7 @@ QPDF::EncryptionData::recover_encryption_key_with_password(std::string const& pa |
| 548 | 655 | } |
| 549 | 656 | |
| 550 | 657 | std::string |
| 551 | -QPDF::EncryptionData::compute_Perms_value_V5_clear() const | |
| 658 | +Encryption::compute_Perms_value_V5_clear() const | |
| 552 | 659 | { |
| 553 | 660 | // From algorithm 3.10 from the PDF 1.7 extension level 3 |
| 554 | 661 | std::string k = " \xff\xff\xff\xffTadb "; |
| ... | ... | @@ -565,7 +672,7 @@ QPDF::EncryptionData::compute_Perms_value_V5_clear() const |
| 565 | 672 | } |
| 566 | 673 | |
| 567 | 674 | std::string |
| 568 | -QPDF::EncryptionData::recover_encryption_key_with_password( | |
| 675 | +Encryption::recover_encryption_key_with_password( | |
| 569 | 676 | std::string const& password, bool& perms_valid) const |
| 570 | 677 | { |
| 571 | 678 | // Algorithm 3.2a from the PDF 1.7 extension level 3 |
| ... | ... | @@ -795,7 +902,7 @@ QPDF::EncryptionParameters::initialize(QPDF& qpdf) |
| 795 | 902 | } |
| 796 | 903 | } |
| 797 | 904 | |
| 798 | - EncryptionData data(V, R, Length / 8, p, O, U, OE, UE, Perms, id1, encrypt_metadata); | |
| 905 | + Encryption data(V, R, Length / 8, p, O, U, OE, UE, Perms, id1, encrypt_metadata); | |
| 799 | 906 | if (qm.provided_password_is_hex_key) { |
| 800 | 907 | // ignore passwords in file |
| 801 | 908 | encryption_key = QUtil::hex_decode(provided_password); |
| ... | ... | @@ -1023,14 +1130,14 @@ QPDF::compute_encryption_O_U( |
| 1023 | 1130 | std::string& out_O, |
| 1024 | 1131 | std::string& out_U) |
| 1025 | 1132 | { |
| 1026 | - EncryptionData data(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata); | |
| 1133 | + Encryption data(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata); | |
| 1027 | 1134 | data.compute_encryption_O_U(user_password, owner_password); |
| 1028 | 1135 | out_O = data.getO(); |
| 1029 | 1136 | out_U = data.getU(); |
| 1030 | 1137 | } |
| 1031 | 1138 | |
| 1032 | 1139 | void |
| 1033 | -QPDF::EncryptionData::compute_encryption_O_U(char const* user_password, char const* owner_password) | |
| 1140 | +Encryption::compute_encryption_O_U(char const* user_password, char const* owner_password) | |
| 1034 | 1141 | { |
| 1035 | 1142 | if (V >= 5) { |
| 1036 | 1143 | throw std::logic_error("compute_encryption_O_U called for file with V >= 5"); |
| ... | ... | @@ -1056,7 +1163,7 @@ QPDF::compute_encryption_parameters_V5( |
| 1056 | 1163 | std::string& out_UE, |
| 1057 | 1164 | std::string& out_Perms) |
| 1058 | 1165 | { |
| 1059 | - EncryptionData data(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata); | |
| 1166 | + Encryption data(V, R, key_len, P, "", "", "", "", "", id1, encrypt_metadata); | |
| 1060 | 1167 | encryption_key = data.compute_encryption_parameters_V5(user_password, owner_password); |
| 1061 | 1168 | |
| 1062 | 1169 | out_O = data.getO(); |
| ... | ... | @@ -1067,8 +1174,7 @@ QPDF::compute_encryption_parameters_V5( |
| 1067 | 1174 | } |
| 1068 | 1175 | |
| 1069 | 1176 | std::string |
| 1070 | -QPDF::EncryptionData::compute_encryption_parameters_V5( | |
| 1071 | - char const* user_password, char const* owner_password) | |
| 1177 | +Encryption::compute_encryption_parameters_V5(char const* user_password, char const* owner_password) | |
| 1072 | 1178 | { |
| 1073 | 1179 | auto out_encryption_key = util::random_string(key_bytes); |
| 1074 | 1180 | // Algorithm 8 from the PDF 2.0 |
| ... | ... | @@ -1089,7 +1195,7 @@ QPDF::EncryptionData::compute_encryption_parameters_V5( |
| 1089 | 1195 | } |
| 1090 | 1196 | |
| 1091 | 1197 | std::string |
| 1092 | -QPDF::EncryptionData::compute_parameters(char const* user_password, char const* owner_password) | |
| 1198 | +Encryption::compute_parameters(char const* user_password, char const* owner_password) | |
| 1093 | 1199 | { |
| 1094 | 1200 | if (V < 5) { |
| 1095 | 1201 | compute_encryption_O_U(user_password, owner_password); | ... | ... |
libqpdf/qpdf/QPDF_private.hh
| ... | ... | @@ -338,6 +338,123 @@ class QPDF::Doc |
| 338 | 338 | class Streams; |
| 339 | 339 | class Writer; |
| 340 | 340 | |
| 341 | + class Encryption | |
| 342 | + { | |
| 343 | + public: | |
| 344 | + // This class holds data read from the encryption dictionary. | |
| 345 | + Encryption( | |
| 346 | + int V, | |
| 347 | + int R, | |
| 348 | + int Length_bytes, | |
| 349 | + int P, | |
| 350 | + std::string const& O, | |
| 351 | + std::string const& U, | |
| 352 | + std::string const& OE, | |
| 353 | + std::string const& UE, | |
| 354 | + std::string const& Perms, | |
| 355 | + std::string const& id1, | |
| 356 | + bool encrypt_metadata) : | |
| 357 | + V(V), | |
| 358 | + R(R), | |
| 359 | + Length_bytes(Length_bytes), | |
| 360 | + P(static_cast<unsigned long long>(P)), | |
| 361 | + O(O), | |
| 362 | + U(U), | |
| 363 | + OE(OE), | |
| 364 | + UE(UE), | |
| 365 | + Perms(Perms), | |
| 366 | + id1(id1), | |
| 367 | + encrypt_metadata(encrypt_metadata) | |
| 368 | + { | |
| 369 | + } | |
| 370 | + Encryption(int V, int R, int Length_bytes, bool encrypt_metadata) : | |
| 371 | + V(V), | |
| 372 | + R(R), | |
| 373 | + Length_bytes(Length_bytes), | |
| 374 | + encrypt_metadata(encrypt_metadata) | |
| 375 | + { | |
| 376 | + } | |
| 377 | + | |
| 378 | + int getV() const; | |
| 379 | + int getR() const; | |
| 380 | + int getLengthBytes() const; | |
| 381 | + int getP() const; | |
| 382 | + // Bits in P are numbered from 1 as in the PDF spec. | |
| 383 | + bool getP(size_t bit) const; | |
| 384 | + std::string const& getO() const; | |
| 385 | + std::string const& getU() const; | |
| 386 | + std::string const& getOE() const; | |
| 387 | + std::string const& getUE() const; | |
| 388 | + std::string const& getPerms() const; | |
| 389 | + std::string const& getId1() const; | |
| 390 | + bool getEncryptMetadata() const; | |
| 391 | + // Bits in P are numbered from 1 as in the PDF spec. | |
| 392 | + void setP(size_t bit, bool val); | |
| 393 | + void setP(unsigned long val); | |
| 394 | + void setO(std::string const&); | |
| 395 | + void setU(std::string const&); | |
| 396 | + void setId1(std::string const& val); | |
| 397 | + void setV5EncryptionParameters( | |
| 398 | + std::string const& O, | |
| 399 | + std::string const& OE, | |
| 400 | + std::string const& U, | |
| 401 | + std::string const& UE, | |
| 402 | + std::string const& Perms); | |
| 403 | + | |
| 404 | + std::string compute_encryption_key(std::string const& password) const; | |
| 405 | + | |
| 406 | + bool | |
| 407 | + check_owner_password(std::string& user_password, std::string const& owner_password) const; | |
| 408 | + | |
| 409 | + bool check_user_password(std::string const& user_password) const; | |
| 410 | + | |
| 411 | + std::string | |
| 412 | + recover_encryption_key_with_password(std::string const& password, bool& perms_valid) const; | |
| 413 | + | |
| 414 | + void compute_encryption_O_U(char const* user_password, char const* owner_password); | |
| 415 | + | |
| 416 | + std::string | |
| 417 | + compute_encryption_parameters_V5(char const* user_password, char const* owner_password); | |
| 418 | + | |
| 419 | + std::string compute_parameters(char const* user_password, char const* owner_password); | |
| 420 | + | |
| 421 | + private: | |
| 422 | + static constexpr unsigned int OU_key_bytes_V4 = 16; // ( == sizeof(MD5::Digest) | |
| 423 | + | |
| 424 | + Encryption(Encryption const&) = delete; | |
| 425 | + Encryption& operator=(Encryption const&) = delete; | |
| 426 | + | |
| 427 | + std::string hash_V5( | |
| 428 | + std::string const& password, std::string const& salt, std::string const& udata) const; | |
| 429 | + std::string | |
| 430 | + compute_O_value(std::string const& user_password, std::string const& owner_password) const; | |
| 431 | + std::string compute_U_value(std::string const& user_password) const; | |
| 432 | + std::string compute_encryption_key_from_password(std::string const& password) const; | |
| 433 | + std::string recover_encryption_key_with_password(std::string const& password) const; | |
| 434 | + bool check_owner_password_V4( | |
| 435 | + std::string& user_password, std::string const& owner_password) const; | |
| 436 | + bool check_owner_password_V5(std::string const& owner_passworda) const; | |
| 437 | + std::string compute_Perms_value_V5_clear() const; | |
| 438 | + std::string compute_O_rc4_key( | |
| 439 | + std::string const& user_password, std::string const& owner_password) const; | |
| 440 | + std::string compute_U_value_R2(std::string const& user_password) const; | |
| 441 | + std::string compute_U_value_R3(std::string const& user_password) const; | |
| 442 | + bool check_user_password_V4(std::string const& user_password) const; | |
| 443 | + bool check_user_password_V5(std::string const& user_password) const; | |
| 444 | + | |
| 445 | + int V; | |
| 446 | + int R; | |
| 447 | + int Length_bytes; | |
| 448 | + std::bitset<32> P{0xfffffffc}; // Specification always requires bits 1 and 2 to be cleared. | |
| 449 | + std::string O; | |
| 450 | + std::string U; | |
| 451 | + std::string OE; | |
| 452 | + std::string UE; | |
| 453 | + std::string Perms; | |
| 454 | + std::string id1; | |
| 455 | + bool encrypt_metadata; | |
| 456 | + }; | |
| 457 | + | |
| 341 | 458 | // StreamCopier class is restricted to QPDFObjectHandle so it can copy stream data. |
| 342 | 459 | class StreamCopier |
| 343 | 460 | { | ... | ... |