Mercurial > hg > orthanc-object-storage
diff Common/EncryptionHelpers.h @ 1:fc26a8fc54d5
initial release
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Fri, 03 Jul 2020 10:08:44 +0200 |
parents | |
children | 2a02b21f0a19 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Common/EncryptionHelpers.h Fri Jul 03 10:08:44 2020 +0200 @@ -0,0 +1,112 @@ +/** + * Cloud storage plugins for Orthanc + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ +#pragma once + +#include <memory.h> +#include <cryptopp/secblock.h> +#include "cryptopp/osrng.h" +#include <boost/thread/mutex.hpp> +#include "Core/MultiThreading/Semaphore.h" + +class EncryptionException : public std::runtime_error +{ +public: + EncryptionException(const std::string& what) + : std::runtime_error(what) + { + } +}; + +class EncryptionHelpers +{ +public: + static const size_t HEADER_VERSION_SIZE = 2; + static const size_t MASTER_KEY_ID_SIZE = 4; + static const size_t AES_KEY_SIZE = 32; // length of AES keys (in bytes) + static const size_t IV_SIZE = 32; // length of IVs (in bytes) + static const size_t INTEGRITY_CHECK_TAG_SIZE = 16; // length of the TAG that is used to check the integrity of data (in bytes) + + static const size_t OVERHEAD_SIZE = HEADER_VERSION_SIZE + MASTER_KEY_ID_SIZE + AES_KEY_SIZE + IV_SIZE + INTEGRITY_CHECK_TAG_SIZE; + + + static const std::string HEADER_VERSION; + +private: + Orthanc::Semaphore concurrentInputSizeSemaphore_; + size_t maxConcurrentInputSize_; + + CryptoPP::AutoSeededRandomPool randomGenerator_; + + CryptoPP::SecByteBlock encryptionMasterKey_; // at a given time, there's only one master key that is used for encryption + std::string encryptionMasterKeyId_; + + std::map<std::string, CryptoPP::SecByteBlock> previousMasterKeys_; // for decryption, we might use older master keys too + +public: + + // since the memory used during encryption/decryption can grow up to a bit more than 2 times the input, + // we want to limit the number of threads doing concurrent processing according to the available memory + // instead of the number of concurrent threads + EncryptionHelpers(size_t maxConcurrentInputSize = 1024*1024*1024); + + void SetCurrentMasterKey(uint32_t id, const std::string& path); + + void SetCurrentMasterKey(uint32_t id, const CryptoPP::SecByteBlock& key); + + void AddPreviousMasterKey(uint32_t id, const std::string& path); + + void AddPreviousMasterKey(uint32_t id, const CryptoPP::SecByteBlock& key); + + // input: plain text data + // output: prefix/encrypted data/integrity check tag + void Encrypt(std::string& output, const std::string& input); + void Encrypt(std::string& output, const char* data, size_t size); + + // input: prefix/encrypted data/integrity check tag + // output: plain text data + void Decrypt(std::string& output, const std::string& input); + void Decrypt(char* output, const char* data, size_t size); + + static void GenerateKey(CryptoPP::SecByteBlock& key); + +private: + + void EncryptInternal(std::string& output, const char* data, size_t size, const CryptoPP::SecByteBlock& masterKey); + + void DecryptInternal(char* output, const char* data, size_t size, const CryptoPP::SecByteBlock& masterKey); + + void EncryptPrefixSecBlock(std::string& output, const CryptoPP::SecByteBlock& input, const CryptoPP::SecByteBlock& masterKey); + + void DecryptPrefixSecBlock(CryptoPP::SecByteBlock& output, const std::string& input, const CryptoPP::SecByteBlock& masterKey); + + std::string GetMasterKeyIdentifier(const CryptoPP::SecByteBlock& masterKey); + + const CryptoPP::SecByteBlock& GetMasterKey(const std::string& keyId); + +public: + + static std::string ToHexString(const CryptoPP::byte* block, size_t size); + static std::string ToHexString(const std::string& block); + static std::string ToHexString(const CryptoPP::SecByteBlock& block); + static std::string ToString(const CryptoPP::SecByteBlock& block); + static std::string ToString(uint32_t value); + + static void ReadKey(CryptoPP::SecByteBlock& key, const std::string& path); + //static void EncryptionHelpers::Encrypt(std::string& output, const std::string& input, const std::string& key, const std::string& iv); +}; +