Commit 9faffb7441bcadbaec21089c7d1d629ffaf0328d
1 parent
4278a557
Refactor `Pl_AES_PDF` and `Pl_RC4` constructors to simplify key handling
Replaced raw key pointer and length parameters with a `std::string` in `Pl_AES_PDF` and `Pl_RC4` constructors for improved safety and clarity. Updated all usage sites accordingly, reducing reliance on manual memory management and redundant conversions.
Showing
8 changed files
with
27 additions
and
70 deletions
libqpdf/Pl_AES_PDF.cc
| @@ -9,25 +9,18 @@ | @@ -9,25 +9,18 @@ | ||
| 9 | 9 | ||
| 10 | bool Pl_AES_PDF::use_static_iv = false; | 10 | bool Pl_AES_PDF::use_static_iv = false; |
| 11 | 11 | ||
| 12 | -Pl_AES_PDF::Pl_AES_PDF( | ||
| 13 | - char const* identifier, | ||
| 14 | - Pipeline* next, | ||
| 15 | - bool encrypt, | ||
| 16 | - unsigned char const* key, | ||
| 17 | - size_t key_bytes) : | 12 | +Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next, bool encrypt, std::string key) : |
| 18 | Pipeline(identifier, next), | 13 | Pipeline(identifier, next), |
| 14 | + key(key), | ||
| 19 | crypto(QPDFCryptoProvider::getImpl()), | 15 | crypto(QPDFCryptoProvider::getImpl()), |
| 20 | - encrypt(encrypt), | ||
| 21 | - key_bytes(key_bytes) | 16 | + encrypt(encrypt) |
| 22 | { | 17 | { |
| 23 | if (!next) { | 18 | if (!next) { |
| 24 | throw std::logic_error("Attempt to create Pl_AES_PDF with nullptr as next"); | 19 | throw std::logic_error("Attempt to create Pl_AES_PDF with nullptr as next"); |
| 25 | } | 20 | } |
| 26 | - if (!(key_bytes == 32 || key_bytes == 16)) { | 21 | + if (!(key.size() == 32 || key.size() == 16)) { |
| 27 | throw std::runtime_error("unsupported key length"); | 22 | throw std::runtime_error("unsupported key length"); |
| 28 | } | 23 | } |
| 29 | - this->key = std::make_unique<unsigned char[]>(key_bytes); | ||
| 30 | - std::memcpy(this->key.get(), key, key_bytes); | ||
| 31 | std::memset(this->inbuf, 0, this->buf_size); | 24 | std::memset(this->inbuf, 0, this->buf_size); |
| 32 | std::memset(this->outbuf, 0, this->buf_size); | 25 | std::memset(this->outbuf, 0, this->buf_size); |
| 33 | std::memset(this->cbc_block, 0, this->buf_size); | 26 | std::memset(this->cbc_block, 0, this->buf_size); |
| @@ -170,7 +163,12 @@ Pl_AES_PDF::flush(bool strip_padding) | @@ -170,7 +163,12 @@ Pl_AES_PDF::flush(bool strip_padding) | ||
| 170 | return_after_init = true; | 163 | return_after_init = true; |
| 171 | } | 164 | } |
| 172 | } | 165 | } |
| 173 | - crypto->rijndael_init(encrypt, key.get(), key_bytes, cbc_mode, cbc_block); | 166 | + crypto->rijndael_init( |
| 167 | + encrypt, | ||
| 168 | + reinterpret_cast<const unsigned char*>(key.data()), | ||
| 169 | + key.size(), | ||
| 170 | + cbc_mode, | ||
| 171 | + cbc_block); | ||
| 174 | if (return_after_init) { | 172 | if (return_after_init) { |
| 175 | return; | 173 | return; |
| 176 | } | 174 | } |
libqpdf/Pl_RC4.cc
| @@ -2,15 +2,10 @@ | @@ -2,15 +2,10 @@ | ||
| 2 | 2 | ||
| 3 | #include <qpdf/QUtil.hh> | 3 | #include <qpdf/QUtil.hh> |
| 4 | 4 | ||
| 5 | -Pl_RC4::Pl_RC4( | ||
| 6 | - char const* identifier, | ||
| 7 | - Pipeline* next, | ||
| 8 | - unsigned char const* key_data, | ||
| 9 | - int key_len, | ||
| 10 | - size_t out_bufsize) : | 5 | +Pl_RC4::Pl_RC4(char const* identifier, Pipeline* next, std::string key, size_t out_bufsize) : |
| 11 | Pipeline(identifier, next), | 6 | Pipeline(identifier, next), |
| 12 | out_bufsize(out_bufsize), | 7 | out_bufsize(out_bufsize), |
| 13 | - rc4(key_data, key_len) | 8 | + rc4(reinterpret_cast<unsigned char const*>(key.data()), static_cast<int>(key.size())) |
| 14 | { | 9 | { |
| 15 | if (!next) { | 10 | if (!next) { |
| 16 | throw std::logic_error("Attempt to create Pl_RC4 with nullptr as next"); | 11 | throw std::logic_error("Attempt to create Pl_RC4 with nullptr as next"); |
libqpdf/QPDFWriter.cc
| @@ -1109,18 +1109,9 @@ QPDFWriter::write_encrypted(std::string_view str) | @@ -1109,18 +1109,9 @@ QPDFWriter::write_encrypted(std::string_view str) | ||
| 1109 | if (!(m->encryption && !m->cur_data_key.empty())) { | 1109 | if (!(m->encryption && !m->cur_data_key.empty())) { |
| 1110 | write(str); | 1110 | write(str); |
| 1111 | } else if (m->encrypt_use_aes) { | 1111 | } else if (m->encrypt_use_aes) { |
| 1112 | - write( | ||
| 1113 | - pl::pipe<Pl_AES_PDF>( | ||
| 1114 | - str, | ||
| 1115 | - true, | ||
| 1116 | - QUtil::unsigned_char_pointer(m->cur_data_key), | ||
| 1117 | - m->cur_data_key.length())); | 1112 | + write(pl::pipe<Pl_AES_PDF>(str, true, m->cur_data_key)); |
| 1118 | } else { | 1113 | } else { |
| 1119 | - write( | ||
| 1120 | - pl::pipe<Pl_RC4>( | ||
| 1121 | - str, | ||
| 1122 | - QUtil::unsigned_char_pointer(m->cur_data_key), | ||
| 1123 | - QIntC::to_int(m->cur_data_key.length()))); | 1114 | + write(pl::pipe<Pl_RC4>(str, m->cur_data_key)); |
| 1124 | } | 1115 | } |
| 1125 | 1116 | ||
| 1126 | return *this; | 1117 | return *this; |
| @@ -1654,12 +1645,7 @@ QPDFWriter::unparseObject( | @@ -1654,12 +1645,7 @@ QPDFWriter::unparseObject( | ||
| 1654 | val = object.getStringValue(); | 1645 | val = object.getStringValue(); |
| 1655 | if (m->encrypt_use_aes) { | 1646 | if (m->encrypt_use_aes) { |
| 1656 | Pl_Buffer bufpl("encrypted string"); | 1647 | Pl_Buffer bufpl("encrypted string"); |
| 1657 | - Pl_AES_PDF pl( | ||
| 1658 | - "aes encrypt string", | ||
| 1659 | - &bufpl, | ||
| 1660 | - true, | ||
| 1661 | - QUtil::unsigned_char_pointer(m->cur_data_key), | ||
| 1662 | - m->cur_data_key.length()); | 1648 | + Pl_AES_PDF pl("aes encrypt string", &bufpl, true, m->cur_data_key); |
| 1663 | pl.writeString(val); | 1649 | pl.writeString(val); |
| 1664 | pl.finish(); | 1650 | pl.finish(); |
| 1665 | val = QPDF_String(bufpl.getString()).unparse(true); | 1651 | val = QPDF_String(bufpl.getString()).unparse(true); |
libqpdf/QPDF_encryption.cc
| @@ -230,8 +230,7 @@ process_with_aes( | @@ -230,8 +230,7 @@ process_with_aes( | ||
| 230 | size_t iv_length = 0) | 230 | size_t iv_length = 0) |
| 231 | { | 231 | { |
| 232 | Pl_Buffer buffer("buffer"); | 232 | Pl_Buffer buffer("buffer"); |
| 233 | - Pl_AES_PDF aes( | ||
| 234 | - "aes", &buffer, encrypt, QUtil::unsigned_char_pointer(key), QIntC::to_uint(key.length())); | 233 | + Pl_AES_PDF aes("aes", &buffer, encrypt, key); |
| 235 | if (iv) { | 234 | if (iv) { |
| 236 | aes.setIV(iv, iv_length); | 235 | aes.setIV(iv, iv_length); |
| 237 | } else { | 236 | } else { |
| @@ -902,12 +901,7 @@ QPDF::decryptString(std::string& str, QPDFObjGen og) | @@ -902,12 +901,7 @@ QPDF::decryptString(std::string& str, QPDFObjGen og) | ||
| 902 | if (use_aes) { | 901 | if (use_aes) { |
| 903 | QTC::TC("qpdf", "QPDF_encryption aes decode string"); | 902 | QTC::TC("qpdf", "QPDF_encryption aes decode string"); |
| 904 | Pl_Buffer bufpl("decrypted string"); | 903 | Pl_Buffer bufpl("decrypted string"); |
| 905 | - Pl_AES_PDF pl( | ||
| 906 | - "aes decrypt string", | ||
| 907 | - &bufpl, | ||
| 908 | - false, | ||
| 909 | - QUtil::unsigned_char_pointer(key), | ||
| 910 | - key.length()); | 904 | + Pl_AES_PDF pl("aes decrypt string", &bufpl, false, key); |
| 911 | pl.writeString(str); | 905 | pl.writeString(str); |
| 912 | pl.finish(); | 906 | pl.finish(); |
| 913 | str = bufpl.getString(); | 907 | str = bufpl.getString(); |
| @@ -1028,19 +1022,11 @@ QPDF::decryptStream( | @@ -1028,19 +1022,11 @@ QPDF::decryptStream( | ||
| 1028 | std::string key = getKeyForObject(encp, og, use_aes); | 1022 | std::string key = getKeyForObject(encp, og, use_aes); |
| 1029 | if (use_aes) { | 1023 | if (use_aes) { |
| 1030 | QTC::TC("qpdf", "QPDF_encryption aes decode stream"); | 1024 | QTC::TC("qpdf", "QPDF_encryption aes decode stream"); |
| 1031 | - decrypt_pipeline = std::make_unique<Pl_AES_PDF>( | ||
| 1032 | - "AES stream decryption", | ||
| 1033 | - pipeline, | ||
| 1034 | - false, | ||
| 1035 | - QUtil::unsigned_char_pointer(key), | ||
| 1036 | - key.length()); | 1025 | + decrypt_pipeline = |
| 1026 | + std::make_unique<Pl_AES_PDF>("AES stream decryption", pipeline, false, key); | ||
| 1037 | } else { | 1027 | } else { |
| 1038 | QTC::TC("qpdf", "QPDF_encryption rc4 decode stream"); | 1028 | QTC::TC("qpdf", "QPDF_encryption rc4 decode stream"); |
| 1039 | - decrypt_pipeline = std::make_unique<Pl_RC4>( | ||
| 1040 | - "RC4 stream decryption", | ||
| 1041 | - pipeline, | ||
| 1042 | - QUtil::unsigned_char_pointer(key), | ||
| 1043 | - toI(key.length())); | 1029 | + decrypt_pipeline = std::make_unique<Pl_RC4>("RC4 stream decryption", pipeline, key); |
| 1044 | } | 1030 | } |
| 1045 | pipeline = decrypt_pipeline.get(); | 1031 | pipeline = decrypt_pipeline.get(); |
| 1046 | } | 1032 | } |
libqpdf/qpdf/Pl_AES_PDF.hh
| @@ -11,12 +11,7 @@ class Pl_AES_PDF final: public Pipeline | @@ -11,12 +11,7 @@ class Pl_AES_PDF final: public Pipeline | ||
| 11 | { | 11 | { |
| 12 | public: | 12 | public: |
| 13 | // key should be a pointer to key_bytes bytes of data | 13 | // key should be a pointer to key_bytes bytes of data |
| 14 | - Pl_AES_PDF( | ||
| 15 | - char const* identifier, | ||
| 16 | - Pipeline* next, | ||
| 17 | - bool encrypt, | ||
| 18 | - unsigned char const* key, | ||
| 19 | - size_t key_bytes); | 14 | + Pl_AES_PDF(char const* identifier, Pipeline* next, bool encrypt, std::string key); |
| 20 | ~Pl_AES_PDF() final = default; | 15 | ~Pl_AES_PDF() final = default; |
| 21 | 16 | ||
| 22 | void write(unsigned char const* data, size_t len) final; | 17 | void write(unsigned char const* data, size_t len) final; |
| @@ -42,13 +37,12 @@ class Pl_AES_PDF final: public Pipeline | @@ -42,13 +37,12 @@ class Pl_AES_PDF final: public Pipeline | ||
| 42 | static unsigned int const buf_size = QPDFCryptoImpl::rijndael_buf_size; | 37 | static unsigned int const buf_size = QPDFCryptoImpl::rijndael_buf_size; |
| 43 | static bool use_static_iv; | 38 | static bool use_static_iv; |
| 44 | 39 | ||
| 40 | + std::string key; | ||
| 45 | std::shared_ptr<QPDFCryptoImpl> crypto; | 41 | std::shared_ptr<QPDFCryptoImpl> crypto; |
| 46 | bool encrypt; | 42 | bool encrypt; |
| 47 | bool cbc_mode{true}; | 43 | bool cbc_mode{true}; |
| 48 | bool first{true}; | 44 | bool first{true}; |
| 49 | size_t offset{0}; // offset into memory buffer | 45 | size_t offset{0}; // offset into memory buffer |
| 50 | - std::unique_ptr<unsigned char[]> key; | ||
| 51 | - size_t key_bytes{0}; | ||
| 52 | unsigned char inbuf[buf_size]; | 46 | unsigned char inbuf[buf_size]; |
| 53 | unsigned char outbuf[buf_size]; | 47 | unsigned char outbuf[buf_size]; |
| 54 | unsigned char cbc_block[buf_size]; | 48 | unsigned char cbc_block[buf_size]; |
libqpdf/qpdf/Pl_RC4.hh
| @@ -12,11 +12,7 @@ class Pl_RC4 final: public Pipeline | @@ -12,11 +12,7 @@ class Pl_RC4 final: public Pipeline | ||
| 12 | 12 | ||
| 13 | // key_len of -1 means treat key_data as a null-terminated string | 13 | // key_len of -1 means treat key_data as a null-terminated string |
| 14 | Pl_RC4( | 14 | Pl_RC4( |
| 15 | - char const* identifier, | ||
| 16 | - Pipeline* next, | ||
| 17 | - unsigned char const* key_data, | ||
| 18 | - int key_len = -1, | ||
| 19 | - size_t out_bufsize = def_bufsize); | 15 | + char const* identifier, Pipeline* next, std::string key, size_t out_bufsize = def_bufsize); |
| 20 | ~Pl_RC4() final = default; | 16 | ~Pl_RC4() final = default; |
| 21 | 17 | ||
| 22 | void write(unsigned char const* data, size_t len) final; | 18 | void write(unsigned char const* data, size_t len) final; |
libtests/aes.cc
| @@ -84,8 +84,9 @@ main(int argc, char* argv[]) | @@ -84,8 +84,9 @@ main(int argc, char* argv[]) | ||
| 84 | key[i / 2] = static_cast<unsigned char>(val); | 84 | key[i / 2] = static_cast<unsigned char>(val); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | + std::string keystr(reinterpret_cast<char const*>(key), keylen); | ||
| 87 | auto* out = new Pl_StdioFile("stdout", outfile); | 88 | auto* out = new Pl_StdioFile("stdout", outfile); |
| 88 | - auto* aes = new Pl_AES_PDF("aes_128_cbc", out, encrypt, key, keylen); | 89 | + auto* aes = new Pl_AES_PDF("aes_128_cbc", out, encrypt, keystr); |
| 89 | delete[] key; | 90 | delete[] key; |
| 90 | key = nullptr; | 91 | key = nullptr; |
| 91 | if (!cbc_mode) { | 92 | if (!cbc_mode) { |
libtests/rc4.cc
| @@ -58,7 +58,8 @@ main(int argc, char* argv[]) | @@ -58,7 +58,8 @@ main(int argc, char* argv[]) | ||
| 58 | FILE* outfile = QUtil::safe_fopen(outfilename, "wb"); | 58 | FILE* outfile = QUtil::safe_fopen(outfilename, "wb"); |
| 59 | auto* out = new Pl_StdioFile("stdout", outfile); | 59 | auto* out = new Pl_StdioFile("stdout", outfile); |
| 60 | // Use a small buffer size (64) for testing | 60 | // Use a small buffer size (64) for testing |
| 61 | - auto* rc4 = new Pl_RC4("rc4", out, key, QIntC::to_int(keylen), 64U); | 61 | + std::string keystr(reinterpret_cast<char const*>(key), keylen); |
| 62 | + auto* rc4 = new Pl_RC4("rc4", out, keystr, 64U); | ||
| 62 | delete[] key; | 63 | delete[] key; |
| 63 | 64 | ||
| 64 | // 64 < buffer size < 512, buffer_size is not a power of 2 for testing | 65 | // 64 < buffer size < 512, buffer_size is not a power of 2 for testing |