# HG changeset patch # User Alain Mazy # Date 1661864398 -7200 # Node ID ac596874d99794852824ed9ddf7d0af1040720f8 # Parent a25b4140e7e41bde5747ef170c88f299b19ed00b fix client side encryption diff -r a25b4140e7e4 -r ac596874d997 Common/EncryptionHelpers.cpp --- a/Common/EncryptionHelpers.cpp Tue Feb 15 06:01:47 2022 +0100 +++ b/Common/EncryptionHelpers.cpp Tue Aug 30 14:59:58 2022 +0200 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -73,10 +74,12 @@ try { FileSource fs(path.c_str(), true, - new HexDecoder( + new Base64Decoder( new ArraySink(key.begin(), key.size()) ) ); + + // std::cout << "ReadKey " << ToHexString(key) << std::endl; } catch (CryptoPP::Exception& ex) { @@ -259,20 +262,26 @@ void EncryptionHelpers::EncryptInternal(std::string& output, const char* data, size_t size, const CryptoPP::SecByteBlock& masterKey) { + // std::cout << "EncryptInternal" << std::endl; + // std::cout << "masterKey " << ToHexString(masterKey) << std::endl; + SecByteBlock iv(IV_SIZE); randomGenerator_.GenerateBlock(iv, iv.size()); // with GCM, the iv is supposed to be a nonce (not a random number). However, since each dataKey is used only once, we consider a random number is fine. SecByteBlock dataKey; GenerateKey(dataKey); -// std::cout << ToHexString(dataKey) << std::endl; -// std::cout << ToHexString(iv) << std::endl; + // std::cout << "dataKey " << ToHexString(dataKey) << std::endl; + // std::cout << "iv " << ToHexString(iv) << std::endl; std::string encryptedDataKey; std::string encryptedIv; EncryptPrefixSecBlock(encryptedIv, iv, masterKey); EncryptPrefixSecBlock(encryptedDataKey, dataKey, masterKey); + // std::cout << "encryptedIv " << ToHexString(encryptedIv) << std::endl; + // std::cout << "encryptedDataKey " << ToHexString(encryptedDataKey) << std::endl; + std::string prefix = HEADER_VERSION + encryptionMasterKeyId_ + encryptedIv + encryptedDataKey; try @@ -309,21 +318,30 @@ void EncryptionHelpers::DecryptInternal(char* output, const char* data, size_t size, const CryptoPP::SecByteBlock& masterKey) { + // std::cout << "DecryptInternal" << std::endl; + // std::cout << "masterKey " << ToHexString(masterKey) << std::endl; + size_t prefixSize = HEADER_VERSION_SIZE + MASTER_KEY_ID_SIZE + IV_SIZE + AES_KEY_SIZE; std::string prefix = std::string(data, prefixSize); std::string mac = std::string(data + size - INTEGRITY_CHECK_TAG_SIZE, INTEGRITY_CHECK_TAG_SIZE); + // std::cout << "prefix " << ToHexString(prefix) << std::endl; + // std::cout << "mac " << ToHexString(mac) << std::endl; + std::string encryptedIv = prefix.substr(HEADER_VERSION_SIZE + MASTER_KEY_ID_SIZE, IV_SIZE); std::string encryptedDataKey = prefix.substr(HEADER_VERSION_SIZE + MASTER_KEY_ID_SIZE + IV_SIZE, AES_KEY_SIZE); + // std::cout << "encryptedIv " << ToHexString(encryptedIv) << std::endl; + // std::cout << "encryptedDataKey " << ToHexString(encryptedDataKey) << std::endl; + SecByteBlock dataKey; SecByteBlock iv; DecryptPrefixSecBlock(iv, encryptedIv, masterKey); DecryptPrefixSecBlock(dataKey, encryptedDataKey, masterKey); -// std::cout << ToHexString(dataKey) << std::endl; -// std::cout << ToHexString(iv) << std::endl; + // std::cout << "dataKey " << ToHexString(dataKey) << std::endl; + // std::cout << "iv " << ToHexString(iv) << std::endl; GCM::Decryption d; d.SetKeyWithIV(dataKey, dataKey.size(), iv, iv.size()); diff -r a25b4140e7e4 -r ac596874d997 Dockerfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Dockerfile Tue Aug 30 14:59:58 2022 +0200 @@ -0,0 +1,31 @@ +# This is a dev Dockerfile in case you need to rebuild an osimis/orthanc image with a test +# version of the s3 plugin +# docker build -t osimis/orthanc:s3test . + +FROM osimis/orthanc-builder-base:bullseye-20220328-slim-stable as orthanc-builder-base + +FROM orthanc-builder-base as build-s3-object-storage + +WORKDIR / + +WORKDIR /sources + +# (framework version used to build the cloud storage plugins) +RUN hg clone https://hg.orthanc-server.com/orthanc/ -r "Orthanc-1.10.1" + +RUN mkdir orthanc-object-storage + +COPY . /sources/orthanc-object-storage + + +RUN mkdir -p /build/cloud-storage/aws +WORKDIR /build/cloud-storage/aws +RUN cmake -DCMAKE_BUILD_TYPE:STRING=Release -DUSE_VCPKG_PACKAGES=OFF -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=/sources/orthanc/OrthancFramework/Sources /sources/orthanc-object-storage/Aws/ +RUN make -j 8 + + +FROM osimis/orthanc:22.7.0 + +COPY --from=build-s3-object-storage /build/cloud-storage/aws/libOrthancAwsS3Storage.so /usr/share/orthanc/plugins-available/ + +RUN chmod +x /usr/share/orthanc/plugins-available/* \ No newline at end of file diff -r a25b4140e7e4 -r ac596874d997 NEWS --- a/NEWS Tue Feb 15 06:01:47 2022 +0100 +++ b/NEWS Tue Aug 30 14:59:58 2022 +0200 @@ -1,6 +1,12 @@ -Pending changes in the mainline -=============================== +2022-08-30 - v 2.0.0 +==================== +* AWS, Google & Azure: BREAKING CHANGE with client-side encryption: + Fixed reading the master key. Although the documentation stated that the master key had to be + encoded in Base64, the master key was interpreted as an Hex string. All non hex characters were + ignored and could even end up in a non-deterministic master key (see details in https://groups.google.com/g/orthanc-users/c/FKmq9EuvQkU/m/gbz_bSuwBwAJ). + The plugin v 2.0.0 won't be able to read data encrypted with v 1.3.3. You'll have to start a new Orthanc instance + and transfer all data from old to new Orthanc. * AWS: added the content MD5 in the request when writing. This adds integrity check and enables some feature on AWS side like https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock-overview.html