gradido/login_server/src/cpp/Crypto/SecretKeyCryptography.h

102 lines
3.3 KiB
C++

#ifndef __GRADIDO_LOGIN_SERVER_CRYPTO_AUTHENTICATED_ENCRYPTION_H
#define __GRADIDO_LOGIN_SERVER_CRYPTO_AUTHENTICATED_ENCRYPTION_H
#include "../SingletonManager/MemoryManager.h"
#include "../lib/AutoPtrContainer.h"
#include "Poco/AutoPtr.h"
#include <shared_mutex>
#include <vector>
/*!
*
* \author: Dario Rekowski
*
* \date: 07-06-2020
*
* \brief: Wrapper Class for make using libsodium secret key encryption easy, used for encrypt private keys for user with pwhash
*
*/
typedef Poco::UInt64 KeyHashed;
class SecretKeyCryptography : public AutoPtrContainer
{
public:
enum ResultType {
AUTH_ENCRYPT_OK,
AUTH_DECRYPT_OK,
AUTH_CREATE_ENCRYPTION_KEY_SUCCEED,
AUTH_CREATE_ENCRYPTION_KEY_FAILED,
AUTH_NO_KEY,
AUTH_ENCRYPT_MESSAGE_FAILED,
AUTH_DECRYPT_MESSAGE_FAILED
};
//! \brief init with default algorithms parameter
SecretKeyCryptography();
//! \brief init with custom algorithms parameter
//!
//! details see in libsodium crypto_pwhash
SecretKeyCryptography(unsigned long long opslimit, size_t memlimit, int algo);
~SecretKeyCryptography();
inline KeyHashed getKeyHashed() const { std::shared_lock<std::shared_mutex> _lock(mWorkingMutex); return mEncryptionKeyHash; }
inline bool operator == (const Poco::AutoPtr<SecretKeyCryptography>& b) const {
return isTheSame(b);
}
inline bool isTheSame(const Poco::AutoPtr<SecretKeyCryptography>& b) const {
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
if (b.isNull()) return false;
return mEncryptionKeyHash == b->getKeyHashed();
}
inline bool operator == (const KeyHashed& hash) const {
return mEncryptionKeyHash == hash;
}
inline bool hasKey() const { std::shared_lock<std::shared_mutex> _lock(mWorkingMutex); return mEncryptionKey != nullptr; }
//! \brief generate encryption key, with default parameter use ca. 300 ms
//!
//! should be call from task, running in g_CryptoCPUScheduler, lock shared mutex for writing
//! \param salt_parameter for example email
//! \return AUTH_CREATE_ENCRYPTION_KEY_FAILED call strerror(errno) for more details
ResultType createKey(const std::string& salt_parameter, const std::string& passwd);
ResultType encrypt(const MemoryBin* message, MemoryBin** encryptedMessage) const;
inline ResultType decrypt(const MemoryBin* encryptedMessage, MemoryBin** message) const {
return decrypt(encryptedMessage->data(), encryptedMessage->size(), message);
}
//! \brief same as the other decrypt only in other format
//! \param encryptedMessage format from Poco Binary Data from DB, like returned from model/table/user for encrypted private key
inline ResultType decrypt(const std::vector<unsigned char>& encryptedMessage, MemoryBin** message) const {
return decrypt(encryptedMessage.data(), encryptedMessage.size(), message);
}
//! \brief raw decrypt function, actual implementation
ResultType decrypt(const unsigned char* encryptedMessage, size_t encryptedMessageSize, MemoryBin** message) const;
static const char* getErrorMessage(ResultType type);
protected:
// algorithms parameter
unsigned long long mOpsLimit;
size_t mMemLimit;
int mAlgo;
// encryption key and hash
MemoryBin* mEncryptionKey;
KeyHashed mEncryptionKeyHash;
mutable std::shared_mutex mWorkingMutex;
};
#endif //__GRADIDO_LOGIN_SERVER_CRYPTO_AUTHENTICATED_ENCRYPTION_H