From 077e18161700c1386889be3bdc76639c681a9b75 Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Tue, 11 Apr 2017 14:23:54 -0400 Subject: [PATCH] pare down ltc --- source/detail/crypto/xlsx_crypto.cpp | 134 +++++++++++---------------- 1 file changed, 53 insertions(+), 81 deletions(-) diff --git a/source/detail/crypto/xlsx_crypto.cpp b/source/detail/crypto/xlsx_crypto.cpp index e4279913..a213c2d9 100644 --- a/source/detail/crypto/xlsx_crypto.cpp +++ b/source/detail/crypto/xlsx_crypto.cpp @@ -36,52 +36,40 @@ namespace { +const std::size_t ole_segment_length = 4096; + enum class hash_algorithm { sha1, - sha256, - sha384, - sha512, - md5, - md4, - md2, - ripemd128, - ripemd160, - whirlpool + sha512 }; -struct XLNT_API crypto_helper +enum class cipher_algorithm { - static const std::size_t segment_length; + aes, + rc2, + rc4, + des, + desx, + triple_des, + triple_des_112 +}; - enum class cipher_algorithm - { - aes, - rc2, - rc4, - des, - desx, - triple_des, - triple_des_112 - }; +enum class cipher_chaining +{ + ecb, // electronic code book + cbc // cipher block chaining +}; - enum class cipher_chaining - { - ecb, // electronic code book - cbc, // cipher block chaining - cfb // cipher feedback chaining - }; +enum class cipher_direction +{ + encryption, + decryption +}; - enum class cipher_direction - { - encryption, - decryption - }; - - static std::vector hash(hash_algorithm algorithm, const std::vector &input); - - static std::vector file(POLE::Storage &storage, const std::string &name); +struct encryption_info +{ struct standard_encryption_info { const std::size_t spin_count = 50000; @@ -96,10 +84,7 @@ struct XLNT_API crypto_helper std::vector verifier_hash_input; std::vector verifier_hash_value; std::vector encrypted_key_value; - }; - - static std::vector decrypt_xlsx_standard(const std::vector &encryption_info, - const std::string &password, const std::vector &encrypted_package); + } standard; struct agile_encryption_info { @@ -137,18 +122,7 @@ struct XLNT_API crypto_helper std::vector verifier_hash_value; std::vector encrypted_key_value; } key_encryptor; - }; - - static agile_encryption_info generate_agile_encryption_info(const std::string &password); - - //static std::vector write_agile_encryption_info(const std::string &password); - - static std::vector decrypt_xlsx_agile(const std::vector &encryption_info, - const std::string &password, const std::vector &encrypted_package); - - static std::vector decrypt_xlsx(const std::vector &bytes, const std::string &password); - - static std::vector encrypt_xlsx(const std::vector &bytes, const std::string &password); + } agile; }; template @@ -302,7 +276,7 @@ static std::vector decode_base64(const std::string &input) return output; } -std::vector crypto_helper::hash(hash_algorithm algorithm, const std::vector &input) +std::vector hash(hash_algorithm algorithm, const std::vector &input) { if (algorithm == hash_algorithm::sha512) { @@ -316,7 +290,7 @@ std::vector crypto_helper::hash(hash_algorithm algorithm, const st throw xlnt::exception("unsupported hash algorithm"); } -std::vector crypto_helper::file(POLE::Storage &storage, const std::string &name) +std::vector file(POLE::Storage &storage, const std::string &name) { POLE::Stream stream(&storage, name.c_str()); if (stream.fail()) return {}; @@ -325,14 +299,14 @@ std::vector crypto_helper::file(POLE::Storage &storage, const std: return bytes; } -std::vector crypto_helper::decrypt_xlsx_standard( +std::vector decrypt_xlsx_standard( const std::vector &encryption_info, const std::string &password, const std::vector &encrypted_package) { std::size_t offset = 0; - standard_encryption_info info; + encryption_info::standard_encryption_info info; auto header_length = read_int(offset, encryption_info); auto index_at_start = offset; @@ -463,15 +437,16 @@ std::vector crypto_helper::decrypt_xlsx_standard( return decrypted; } -crypto_helper::agile_encryption_info crypto_helper::generate_agile_encryption_info(const std::string &password) +encryption_info generate_encryption_info(const std::string &password) { - agile_encryption_info result; - result.key_data.salt_value.assign(password.begin(), password.end()); + encryption_info result; + result.agile.key_data.salt_value.assign(password.begin(), password.end()); + return result; } /* -std::vector crypto_helper::write_agile_encryption_info(const std::string &password) +std::vector write_agile_encryption_info(const std::string &password) { static const auto &xmlns = xlnt::constants::ns("encryption"); static const auto &xmlns_p = xlnt::constants::ns("encryption-password"); @@ -527,7 +502,7 @@ std::vector crypto_helper::write_agile_encryption_info(const std:: } */ -std::vector crypto_helper::decrypt_xlsx_agile( +std::vector decrypt_xlsx_agile( const std::vector &encryption_info, const std::string &password, const std::vector &encrypted_package) @@ -536,7 +511,7 @@ std::vector crypto_helper::decrypt_xlsx_agile( static const auto &xmlns_p = xlnt::constants::ns("encryption-password"); // static const auto &xmlns_c = xlnt::constants::namespace_("encryption-certificate"); - agile_encryption_info result; + encryption_info::agile_encryption_info result; xml::parser parser(encryption_info.data(), encryption_info.size(), "EncryptionInfo"); @@ -579,6 +554,7 @@ std::vector crypto_helper::decrypt_xlsx_agile( result.key_encryptor.cipher_chaining = parser.attribute("cipherChaining"); auto hash_algorithm_string = parser.attribute("hashAlgorithm"); + if (hash_algorithm_string == "SHA512") { result.key_encryptor.hash = hash_algorithm::sha512; @@ -587,13 +563,9 @@ std::vector crypto_helper::decrypt_xlsx_agile( { result.key_encryptor.hash = hash_algorithm::sha1; } - else if (hash_algorithm_string == "SHA256") + else { - result.key_encryptor.hash = hash_algorithm::sha256; - } - else if (hash_algorithm_string == "SHA384") - { - result.key_encryptor.hash = hash_algorithm::sha384; + throw xlnt::unsupported("hash"); } result.key_encryptor.salt_value = decode_base64(parser.attribute("saltValue")); @@ -692,17 +664,17 @@ std::vector crypto_helper::decrypt_xlsx_agile( auto &segment = *reinterpret_cast(salt_with_block_key.data() + salt_size); auto total_size = static_cast(*reinterpret_cast(encrypted_package.data())); - std::vector encrypted_segment(segment_length, 0); + std::vector encrypted_segment(ole_segment_length, 0); std::vector decrypted_package; decrypted_package.reserve(encrypted_package.size() - 8); - for (std::size_t i = 8; i < encrypted_package.size(); i += segment_length) + for (std::size_t i = 8; i < encrypted_package.size(); i += ole_segment_length) { auto iv = hash(result.key_encryptor.hash, salt_with_block_key); iv.resize(16); auto segment_begin = encrypted_package.begin() + static_cast(i); - auto current_segment_length = std::min(segment_length, encrypted_package.size() - i); + auto current_segment_length = std::min(ole_segment_length, encrypted_package.size() - i); auto segment_end = encrypted_package.begin() + static_cast(i + current_segment_length); encrypted_segment.assign(segment_begin, segment_end); auto decrypted_segment = xlnt::detail::aes_cbc_decrypt(encrypted_segment, key, iv); @@ -718,8 +690,9 @@ std::vector crypto_helper::decrypt_xlsx_agile( return decrypted_package; } -std::vector crypto_helper::decrypt_xlsx( - const std::vector &bytes, const std::string &password) +std::vector decrypt_xlsx( + const std::vector &bytes, + const std::string &password) { if (bytes.empty()) { @@ -782,21 +755,20 @@ std::vector crypto_helper::decrypt_xlsx( return decrypt_xlsx_standard(encryption_info, password, encrypted_package); } -std::vector crypto_helper::encrypt_xlsx( - const std::vector &bytes, const std::string &password) +std::vector encrypt_xlsx( + const std::vector &bytes, + const std::string &password) { if (bytes.empty()) { throw xlnt::exception("empty file"); } - generate_agile_encryption_info(password); + generate_encryption_info(password); return {}; } -const std::size_t crypto_helper::segment_length = 4096; - } // namespace namespace xml { @@ -869,13 +841,13 @@ namespace detail { std::vector XLNT_API decrypt_xlsx(const std::vector &data, const std::string &password) { - return crypto_helper::decrypt_xlsx(data, password); + return ::decrypt_xlsx(data, password); } void xlsx_consumer::read(std::istream &source, const std::string &password) { std::vector data((std::istreambuf_iterator(source)), (std::istreambuf_iterator())); - const auto decrypted = crypto_helper::decrypt_xlsx(data, password); + const auto decrypted = decrypt_xlsx(data, password); vector_istreambuf decrypted_buffer(decrypted); std::istream decrypted_stream(&decrypted_buffer); read(decrypted_stream); @@ -891,7 +863,7 @@ void xlsx_producer::write(std::ostream &destination, const std::string &password write(decrypted_stream); } - const auto encrypted = crypto_helper::encrypt_xlsx(decrypted, password); + const auto encrypted = encrypt_xlsx(decrypted, password); vector_istreambuf encrypted_buffer(encrypted); destination << &encrypted_buffer;