summaryrefslogtreecommitdiff
path: root/src/manager/crypto/sw-backend/store.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/manager/crypto/sw-backend/store.cpp')
-rw-r--r--src/manager/crypto/sw-backend/store.cpp291
1 files changed, 154 insertions, 137 deletions
diff --git a/src/manager/crypto/sw-backend/store.cpp b/src/manager/crypto/sw-backend/store.cpp
index b3143ebd..ca44df90 100644
--- a/src/manager/crypto/sw-backend/store.cpp
+++ b/src/manager/crypto/sw-backend/store.cpp
@@ -44,193 +44,210 @@ const int STORE_AES_GCM_TAG_SIZE = 16; // length of AES GCM tag
// internal SW encryption scheme flags
enum EncryptionScheme {
- NONE = 0,
- PASSWORD = 1 << 0
+ NONE = 0,
+ PASSWORD = 1 << 0
};
template <typename T, typename ...Args>
-std::unique_ptr<T> make_unique(Args&& ...args)
+std::unique_ptr<T> make_unique(Args &&...args)
{
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
RawBuffer generateRandIV()
{
- RawBuffer civ(EVP_MAX_IV_LENGTH);
+ RawBuffer civ(EVP_MAX_IV_LENGTH);
- if (1 != RAND_bytes(civ.data(), civ.size()))
- ThrowErr(Exc::Crypto::InternalError, "RAND_bytes failed to generate IV.");
- return civ;
+ if (1 != RAND_bytes(civ.data(), civ.size()))
+ ThrowErr(Exc::Crypto::InternalError, "RAND_bytes failed to generate IV.");
+
+ return civ;
}
-RawBuffer passwordToKey(const Password &password, const RawBuffer &salt, size_t keySize)
+RawBuffer passwordToKey(const Password &password, const RawBuffer &salt,
+ size_t keySize)
{
- RawBuffer result(keySize);
-
- if (1 != PKCS5_PBKDF2_HMAC_SHA1(
- password.c_str(),
- password.size(),
- salt.data(),
- salt.size(),
- ITERATIONS,
- result.size(),
- result.data()))
- ThrowErr(Exc::InternalError, "PCKS5_PKKDF2_HMAC_SHA1 failed.");
-
- return result;
+ RawBuffer result(keySize);
+
+ if (1 != PKCS5_PBKDF2_HMAC_SHA1(
+ password.c_str(),
+ password.size(),
+ salt.data(),
+ salt.size(),
+ ITERATIONS,
+ result.size(),
+ result.data()))
+ ThrowErr(Exc::InternalError, "PCKS5_PKKDF2_HMAC_SHA1 failed.");
+
+ return result;
}
-RawBuffer unpack(const RawBuffer& packed, const Password& pass)
+RawBuffer unpack(const RawBuffer &packed, const Password &pass)
{
- MessageBuffer buffer;
- buffer.Push(packed);
- int encryptionScheme = 0;
- RawBuffer data;
- buffer.Deserialize(encryptionScheme, data);
-
- if (encryptionScheme == 0)
- return data;
-
- MessageBuffer internalBuffer;
- internalBuffer.Push(data);
- RawBuffer encrypted;
- RawBuffer iv;
- RawBuffer tag;
-
- // serialization exceptions will be catched as CKM::Exception and will cause
- // CKM_API_ERROR_SERVER_ERROR
- internalBuffer.Deserialize(encrypted, iv, tag);
-
- /*
- * AES GCM will check data integrity and handle cases where:
- * - wrong password is used
- * - password is empty when it shouldn't be
- * - password is not empty when it should be
- */
- RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH);
-
- RawBuffer ret;
- try {
- ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag);
- } catch( const Exc::Crypto::InternalError& e) {
- ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed");
- }
- return ret;
+ MessageBuffer buffer;
+ buffer.Push(packed);
+ int encryptionScheme = 0;
+ RawBuffer data;
+ buffer.Deserialize(encryptionScheme, data);
+
+ if (encryptionScheme == 0)
+ return data;
+
+ MessageBuffer internalBuffer;
+ internalBuffer.Push(data);
+ RawBuffer encrypted;
+ RawBuffer iv;
+ RawBuffer tag;
+
+ // serialization exceptions will be catched as CKM::Exception and will cause
+ // CKM_API_ERROR_SERVER_ERROR
+ internalBuffer.Deserialize(encrypted, iv, tag);
+
+ /*
+ * AES GCM will check data integrity and handle cases where:
+ * - wrong password is used
+ * - password is empty when it shouldn't be
+ * - password is not empty when it should be
+ */
+ RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH);
+
+ RawBuffer ret;
+
+ try {
+ ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag);
+ } catch (const Exc::Crypto::InternalError &e) {
+ ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed");
+ }
+
+ return ret;
}
-RawBuffer pack(const RawBuffer& data, const Password& pass)
+RawBuffer pack(const RawBuffer &data, const Password &pass)
{
- int scheme = EncryptionScheme::NONE;
- RawBuffer packed = data;
- if (!pass.empty()) {
- RawBuffer iv = generateRandIV();
- RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH);
-
- std::pair<RawBuffer, RawBuffer> ret;
- try {
- ret = Crypto::SW::Internals::encryptDataAesGcm(key, data, iv, STORE_AES_GCM_TAG_SIZE);
- } catch( const Exc::Crypto::InternalError& e) {
- ThrowErr(Exc::AuthenticationFailed, "Encryption with custom password failed");
- }
- scheme |= EncryptionScheme::PASSWORD;
-
- // serialization exceptions will be catched as CKM::Exception and will cause
- // CKM_API_ERROR_SERVER_ERROR
- packed = MessageBuffer::Serialize(ret.first, iv, ret.second).Pop();
- }
- // encryption scheme + internal buffer
- return MessageBuffer::Serialize(scheme, packed).Pop();
+ int scheme = EncryptionScheme::NONE;
+ RawBuffer packed = data;
+
+ if (!pass.empty()) {
+ RawBuffer iv = generateRandIV();
+ RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH);
+
+ std::pair<RawBuffer, RawBuffer> ret;
+
+ try {
+ ret = Crypto::SW::Internals::encryptDataAesGcm(key, data, iv,
+ STORE_AES_GCM_TAG_SIZE);
+ } catch (const Exc::Crypto::InternalError &e) {
+ ThrowErr(Exc::AuthenticationFailed, "Encryption with custom password failed");
+ }
+
+ scheme |= EncryptionScheme::PASSWORD;
+
+ // serialization exceptions will be catched as CKM::Exception and will cause
+ // CKM_API_ERROR_SERVER_ERROR
+ packed = MessageBuffer::Serialize(ret.first, iv, ret.second).Pop();
+ }
+
+ // encryption scheme + internal buffer
+ return MessageBuffer::Serialize(scheme, packed).Pop();
}
} // namespace anonymous
-namespace
-{
-const char * const DEVICE_KEY_XSD = RO_DATA_DIR "/sw_key.xsd";
-const char * const DEVICE_KEY_SW_FILE = RW_DATA_DIR "/device_key.xml";
+namespace {
+const char *const DEVICE_KEY_XSD = RO_DATA_DIR "/sw_key.xsd";
+const char *const DEVICE_KEY_SW_FILE = RW_DATA_DIR "/device_key.xml";
}
Store::Store(CryptoBackend backendId)
- : GStore(backendId)
+ : GStore(backendId)
{
- // get the device key if present
- InitialValues::SWKeyFile keyFile(DEVICE_KEY_SW_FILE);
- int rc = keyFile.Validate(DEVICE_KEY_XSD);
- if (rc == XML::Parser::PARSE_SUCCESS) {
- rc = keyFile.Parse();
- if (rc == XML::Parser::PARSE_SUCCESS)
- m_deviceKey = keyFile.getPrivKey();
- else
- // do nothing, bypass encrypted elements
- LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", parsing code: " << rc);
- } else {
- LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", validation code: " << rc);
- }
+ // get the device key if present
+ InitialValues::SWKeyFile keyFile(DEVICE_KEY_SW_FILE);
+ int rc = keyFile.Validate(DEVICE_KEY_XSD);
+
+ if (rc == XML::Parser::PARSE_SUCCESS) {
+ rc = keyFile.Parse();
+
+ if (rc == XML::Parser::PARSE_SUCCESS)
+ m_deviceKey = keyFile.getPrivKey();
+ else
+ // do nothing, bypass encrypted elements
+ LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", parsing code: "
+ << rc);
+ } else {
+ LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE <<
+ ", validation code: " << rc);
+ }
}
GObjUPtr Store::getObject(const Token &token, const Password &pass)
{
- if (token.backendId != m_backendId)
- ThrowErr(Exc::Crypto::WrongBackend, "Decider choose wrong backend!");
+ if (token.backendId != m_backendId)
+ ThrowErr(Exc::Crypto::WrongBackend, "Decider choose wrong backend!");
- RawBuffer data = unpack(token.data, pass);
+ RawBuffer data = unpack(token.data, pass);
- if (token.dataType.isKeyPrivate() || token.dataType.isKeyPublic())
- return make_unique<AKey>(data, token.dataType);
+ if (token.dataType.isKeyPrivate() || token.dataType.isKeyPublic())
+ return make_unique<AKey>(data, token.dataType);
- if (token.dataType == DataType(DataType::KEY_AES))
- return make_unique<SKey>(data, token.dataType);
+ if (token.dataType == DataType(DataType::KEY_AES))
+ return make_unique<SKey>(data, token.dataType);
- if (token.dataType.isCertificate() || token.dataType.isChainCert())
- return make_unique<Cert>(data, token.dataType);
+ if (token.dataType.isCertificate() || token.dataType.isChainCert())
+ return make_unique<Cert>(data, token.dataType);
- if (token.dataType.isBinaryData())
- return make_unique<BData>(data, token.dataType);
+ if (token.dataType.isBinaryData())
+ return make_unique<BData>(data, token.dataType);
- ThrowErr(Exc::Crypto::DataTypeNotSupported,
- "This type of data is not supported by openssl backend: ", (int)token.dataType);
+ ThrowErr(Exc::Crypto::DataTypeNotSupported,
+ "This type of data is not supported by openssl backend: ", (int)token.dataType);
}
TokenPair Store::generateAKey(const CryptoAlgorithm &algorithm,
- const Password &prvPass,
- const Password &pubPass)
+ const Password &prvPass,
+ const Password &pubPass)
{
- Internals::DataPair ret = Internals::generateAKey(algorithm);
- return std::make_pair<Token, Token>(
- Token(m_backendId, ret.first.type, pack(ret.first.buffer, prvPass)),
- Token(m_backendId, ret.second.type, pack(ret.second.buffer, pubPass)));
+ Internals::DataPair ret = Internals::generateAKey(algorithm);
+ return std::make_pair<Token, Token>(
+ Token(m_backendId, ret.first.type, pack(ret.first.buffer, prvPass)),
+ Token(m_backendId, ret.second.type, pack(ret.second.buffer, pubPass)));
}
-Token Store::generateSKey(const CryptoAlgorithm &algorithm, const Password &pass)
+Token Store::generateSKey(const CryptoAlgorithm &algorithm,
+ const Password &pass)
{
- Internals::Data ret = Internals::generateSKey(algorithm);
- return Token(m_backendId, ret.type, pack(ret.buffer, pass));
+ Internals::Data ret = Internals::generateSKey(algorithm);
+ return Token(m_backendId, ret.type, pack(ret.buffer, pass));
}
Token Store::import(const Data &data, const Password &pass)
{
- return Token(m_backendId, data.type, pack(data.data, pass));
+ return Token(m_backendId, data.type, pack(data.data, pass));
}
-Token Store::importEncrypted(const Data &data, const Password &pass, const DataEncryption &enc)
+Token Store::importEncrypted(const Data &data, const Password &pass,
+ const DataEncryption &enc)
{
- if (!m_deviceKey)
- ThrowErr(Exc::Crypto::InternalError, "No device key present");
-
- // decrypt the AES key using device key
- CryptoAlgorithm algorithmRSAOAEP;
- algorithmRSAOAEP.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
- Crypto::SW::SKey aesKey(m_deviceKey->decrypt(algorithmRSAOAEP, enc.encryptedKey), DataType::KEY_AES);
-
- // decrypt the buffer using AES key
- CryptoAlgorithm algorithmAESCBC;
- algorithmAESCBC.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
- algorithmAESCBC.setParam(ParamName::ED_IV, enc.iv);
- RawBuffer rawData = aesKey.decrypt(algorithmAESCBC, data.data);
- if (!Internals::verifyBinaryData(data.type, rawData))
- ThrowErr(Exc::Crypto::InputParam, "Verification failed. Data could not be imported!");
-
- return Token(m_backendId, data.type, pack(rawData, pass));
+ if (!m_deviceKey)
+ ThrowErr(Exc::Crypto::InternalError, "No device key present");
+
+ // decrypt the AES key using device key
+ CryptoAlgorithm algorithmRSAOAEP;
+ algorithmRSAOAEP.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP);
+ Crypto::SW::SKey aesKey(m_deviceKey->decrypt(algorithmRSAOAEP,
+ enc.encryptedKey), DataType::KEY_AES);
+
+ // decrypt the buffer using AES key
+ CryptoAlgorithm algorithmAESCBC;
+ algorithmAESCBC.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
+ algorithmAESCBC.setParam(ParamName::ED_IV, enc.iv);
+ RawBuffer rawData = aesKey.decrypt(algorithmAESCBC, data.data);
+
+ if (!Internals::verifyBinaryData(data.type, rawData))
+ ThrowErr(Exc::Crypto::InputParam,
+ "Verification failed. Data could not be imported!");
+
+ return Token(m_backendId, data.type, pack(rawData, pass));
}
} // namespace SW