diff --git a/.gitmodules b/.gitmodules index 5d30a150..08eb78a7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -27,3 +27,6 @@ url = https://github.com/madler/zlib.git branch = develop ignore = dirty +[submodule "third-party/cryptopp"] + path = third-party/cryptopp + url = https://github.com/weidai11/cryptopp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 7e84e523..35939373 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -4,6 +4,15 @@ project(${LIBRARY_NAME} VERSION ${LIBRARY_VERSION} LANGUAGES CXX C) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../third-party ${CMAKE_CURRENT_BINARY_DIR}/third-party) +include(ExternalProject) +ExternalProject_Add(cryptopp + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../third-party/cryptopp + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/cryptopp + INSTALL_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_COMMAND "") +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../third-party/cryptopp ${CMAKE_CURRENT_BINARY_DIR}/cryptopp EXCLUDE_FROM_ALL) + if(APPLE) option(FRAMEWORK "Set to ON to package dylib and headers into a .framework, OSX only" OFF) endif() @@ -75,8 +84,8 @@ include_directories(${XLNT_INCLUDE_DIR} ${THIRD_PARTY_DIR}/libstudxml ${THIRD_PARTY_DIR}/utfcpp/source ${THIRD_PARTY_DIR}/pole - ${THIRD_PARTY_DIR}/botan - ${THIRD_PARTY_DIR}/zlib) + ${THIRD_PARTY_DIR}/zlib + ${THIRD_PARTY_DIR}/cryptopp) file(GLOB ROOT_HEADERS ${XLNT_INCLUDE_DIR}/xlnt/*.hpp) file(GLOB CELL_HEADERS ${XLNT_INCLUDE_DIR}/xlnt/cell/*.hpp) @@ -112,7 +121,7 @@ set(XLNT_SOURCES ${CELL_SOURCES} ${CHARTS_SOURCES} ${CHARTSHEET_SOURCES} ${WORKSHEET_SOURCES} ${DETAIL_SOURCES}) if(NOT STATIC) - add_library(xlnt SHARED ${XLNT_HEADERS} ${XLNT_SOURCES} $) + add_library(xlnt SHARED ${XLNT_HEADERS} ${XLNT_SOURCES} $ $) target_compile_definitions(xlnt PRIVATE XLNT_SHARED=1) if(MSVC) @@ -142,7 +151,7 @@ if(NOT STATIC) ) endif() else() - add_library(xlnt STATIC ${XLNT_HEADERS} ${XLNT_SOURCES} $) + add_library(xlnt STATIC ${XLNT_HEADERS} ${XLNT_SOURCES} $ $) target_compile_definitions(xlnt PUBLIC XLNT_STATIC=1) if(MSVC) diff --git a/source/detail/include_botan.hpp b/source/detail/include_cryptopp.hpp similarity index 79% rename from source/detail/include_botan.hpp rename to source/detail/include_cryptopp.hpp index 94a12e63..0bc49a84 100644 --- a/source/detail/include_botan.hpp +++ b/source/detail/include_cryptopp.hpp @@ -27,7 +27,16 @@ #pragma clang diagnostic ignored "-Wdocumentation" #pragma clang diagnostic ignored "-Wweak-vtables" #pragma clang diagnostic ignored "-Wconversion" +#pragma clang diagnostic ignored "-Wundef" +#pragma clang diagnostic ignored "-Wold-style-cast" +#pragma clang diagnostic ignored "-Wdeprecated" +#pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#pragma clang diagnostic ignored "-Wextra-semi" +#pragma clang diagnostic ignored "-Wexit-time-destructors" -#include +#include +#include +#include +#include #pragma clang diagnostic pop diff --git a/source/detail/xlsx_crypto.cpp b/source/detail/xlsx_crypto.cpp index 7067b1bf..abc998c1 100644 --- a/source/detail/xlsx_crypto.cpp +++ b/source/detail/xlsx_crypto.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -129,34 +129,68 @@ struct crypto_helper const std::vector &encrypted, cipher_chaining chaining, cipher_direction direction) { - std::string cipher_name("AES-"); - cipher_name.append(std::to_string(key.size() * 8)); - cipher_name.append(chaining == cipher_chaining::ecb - ? "/ECB/NoPadding" : "/CBC/NoPadding"); + std::vector destination(encrypted.size(), 0); - auto botan_direction = direction == cipher_direction::decryption - ? Botan::DECRYPTION : Botan::ENCRYPTION; - Botan::Pipe pipe(Botan::get_cipher(cipher_name, key, iv, botan_direction)); - pipe.process_msg(encrypted); - auto decrypted = pipe.read_all(); + if (direction == cipher_direction::encryption && chaining == cipher_chaining::cbc) + { + CryptoPP::AES::Decryption aesEncryption(key.data(), key.size()); + CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv.data()); - return std::vector(decrypted.begin(), decrypted.end()); + CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::ArraySink(destination.data(), destination.size())); + stfEncryptor.Put(reinterpret_cast(encrypted.data()), encrypted.size()); + stfEncryptor.MessageEnd(); + } + else if (direction == cipher_direction::decryption && chaining == cipher_chaining::cbc) + { + CryptoPP::AES::Encryption aesEncryption(key.data(), key.size()); + CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv.data()); + + CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::ArraySink(destination.data(), destination.size())); + stfEncryptor.Put(reinterpret_cast(encrypted.data()), encrypted.size()); + stfEncryptor.MessageEnd(); + } + else if (direction == cipher_direction::encryption && chaining == cipher_chaining::ecb) + { + CryptoPP::AES::Encryption aesEncryption(key.data(), key.size()); + CryptoPP::ECB_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv.data()); + + CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::ArraySink(destination.data(), destination.size())); + stfEncryptor.Put(reinterpret_cast(encrypted.data()), encrypted.size()); + stfEncryptor.MessageEnd(); + } + else if (direction == cipher_direction::decryption && chaining == cipher_chaining::ecb) + { + CryptoPP::AES::Encryption aesEncryption(key.data(), key.size()); + CryptoPP::ECB_Mode_ExternalCipher::Decryption cbcEncryption(aesEncryption, iv.data()); + + CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::ArraySink(destination.data(), destination.size())); + stfEncryptor.Put(reinterpret_cast(encrypted.data()), encrypted.size()); + stfEncryptor.MessageEnd(); + } + + return destination; } static std::vector decode_base64(const std::string &encoded) { - Botan::Pipe pipe(new Botan::Base64_Decoder); - pipe.process_msg(encoded); - auto decoded = pipe.read_all(); + CryptoPP::Base64Decoder decoder; + decoder.Put(reinterpret_cast(encoded.data()), encoded.size()); + decoder.MessageEnd(); + + std::vector decoded(decoder.MaxRetrievable(), 0); + decoder.Get(decoded.data(), decoded.size()); - return std::vector(decoded.begin(), decoded.end()); + return decoded; } static std::string encode_base64(const std::vector &decoded) { - Botan::Pipe pipe(new Botan::Base64_Encoder); - pipe.process_msg(decoded); - auto encoded = pipe.read_all(); + CryptoPP::Base64Decoder encoder; + encoder.Put(reinterpret_cast(decoded.data()), decoded.size()); + encoder.MessageEnd(); + + std::vector encoded(encoder.MaxRetrievable(), 0); + encoder.Get(encoded.data(), encoded.size()); return std::string(encoded.begin(), encoded.end()); } @@ -164,12 +198,22 @@ struct crypto_helper static std::vector hash(hash_algorithm algorithm, const std::vector &input) { - Botan::Pipe pipe(new Botan::Hash_Filter( - algorithm == hash_algorithm::sha512 ? "SHA-512" : "SHA-1")); - pipe.process_msg(input); - auto hash = pipe.read_all(); - - return std::vector(hash.begin(), hash.end()); + std::vector digest; + + if (algorithm == hash_algorithm::sha512) + { + CryptoPP::SHA512 sha512; + digest.resize(CryptoPP::SHA512::DIGESTSIZE, 0); + sha512.CalculateDigest(digest.data(), input.data(), input.size()); + } + else if (algorithm == hash_algorithm::sha1) + { + CryptoPP::SHA1 sha1; + digest.resize(CryptoPP::SHA1::DIGESTSIZE, 0); + sha1.CalculateDigest(digest.data(), input.data(), input.size()); + } + + return digest; } static std::vector file(POLE::Storage &storage, const std::string &name) diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 5c6fd1cb..531b429d 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -1,11 +1,12 @@ +cmake_minimum_required(VERSION 3.1) include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/common.cmake) project(${LIBRARY_NAME}.third-party VERSION ${LIBRARY_VERSION} LANGUAGES CXX C) # Includes include_directories(libstudxml utfcpp/source - botan zlib + cryptopp ${LIBRARY_SOURCE_DIR}/detail) set(LIBSTUDXML @@ -46,28 +47,6 @@ set(GENX ${CMAKE_CURRENT_SOURCE_DIR}/libstudxml/xml/details/genx/genx.c ${CMAKE_CURRENT_SOURCE_DIR}/libstudxml/xml/details/genx/genx.h) -set(BOTAN - ${CMAKE_CURRENT_SOURCE_DIR}/botan/botan_all.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/botan/botan_all_internal.h - ${CMAKE_CURRENT_SOURCE_DIR}/botan/botan_all.h) - -if(MSVC) - set_source_files_properties(${BOTAN} PROPERTIES COMPILE_FLAGS "/wd\"4244\" /wd\"4267\"") -else() - set_source_files_properties(${BOTAN} PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations") -endif() - -if (CMAKE_SIZEOF_VOID_P EQUAL 8) - set(CPU "x64") -else() - set(CPU "x86") -endif() - -add_custom_command(OUTPUT ${BOTAN} - COMMAND python configure.py --minimized-build --enable-modules=sha1,aes,filters,codec_filt,cbc,ecb,sha2_32,sha2_64 --without-sphinx --disable-shared --amalgamation --cpu=${CPU} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/botan - COMMENT "Generating botan amalgamation") - set(ZLIB ${CMAKE_CURRENT_SOURCE_DIR}/zlib/adler32.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/compress.c ${CMAKE_CURRENT_SOURCE_DIR}/zlib/crc32.c @@ -96,7 +75,7 @@ else() set_source_files_properties(${ZLIB} PROPERTIES COMPILE_FLAGS "/wd\"4018\"") endif() -add_library(xlnt.third-party OBJECT ${LIBSTUDXML} ${GENX} ${EXPAT} ${BOTAN} ${ZLIB}) +add_library(xlnt.third-party OBJECT ${LIBSTUDXML} ${GENX} ${EXPAT} ${ZLIB}) target_compile_definitions(xlnt.third-party PRIVATE LIBSTUDXML_STATIC_LIB=1) if(NOT STATIC) @@ -109,7 +88,6 @@ if(MSVC) set_target_properties(xlnt.third-party PROPERTIES COMPILE_FLAGS "/MP") endif() -source_group(botan FILES ${BOTAN}) source_group(libstudxml FILES ${LIBSTUDXML}) source_group(libstudxml\\genx FILES ${GENX}) source_group(libstudxml\\expat FILES ${EXPAT}) diff --git a/third-party/botan b/third-party/botan deleted file mode 160000 index 7c9d431d..00000000 --- a/third-party/botan +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7c9d431d11fe2f3e7e43f2f8585e9be4495135c5 diff --git a/third-party/cryptopp b/third-party/cryptopp new file mode 160000 index 00000000..1a17ade2 --- /dev/null +++ b/third-party/cryptopp @@ -0,0 +1 @@ +Subproject commit 1a17ade299c3a05e5a63a8cb3f390d21845c21c6