return m_accessControl.canRead(accessorCred, permission);
}
-Crypto::GObjUPtr CKMLogic::rowToObject(
+void CKMLogic::decryptRow(
UserData &handler,
- DB::Row row,
+ DB::Row &row,
const Password &password,
const RawBuffer &hash)
{
- Crypto::GStore &store = m_decider.getStore(row);
-
- Password pass = m_accessControl.isCCMode() ? "" : password;
-
- // decrypt row
- Crypto::GObjUPtr obj;
-
if (CryptoLogic::getSchemeVersion(row.encryptionScheme) ==
CryptoLogic::ENCRYPTION_V2) {
handler.crypto.decryptRow(Password(), row);
-
- obj = store.getObject(row, pass);
} else {
+ Crypto::GStore &store = m_decider.getStore(row);
+
+ Password pass = m_accessControl.isCCMode() ? "" : password;
+
// decrypt entirely with old scheme: b64(pass(appkey(data))) -> data
handler.crypto.decryptRow(pass, row);
// destroy it in store
Crypto::EncryptionParams(),
hash);
- // get it from the store (it can be different than the data we imported into store)
- obj = store.getObject(token, pass);
-
// update row with new token
*static_cast<Token *>(&row) = std::move(token);
// encrypt it with app key: pass(data) -> b64(appkey(pass(data))
- handler.crypto.encryptRow(row);
+ auto encryptedRow = handler.crypto.encryptRow(row);
// update it in db
- handler.database.updateRow(row);
+ handler.database.updateRow(encryptedRow);
}
+}
- return obj;
+Crypto::GObjUPtr CKMLogic::rowToObject(
+ UserData &handler,
+ DB::Row row,
+ const Password &password,
+ const RawBuffer &hash)
+{
+ decryptRow(handler, row, password, hash);
+
+ return decryptedRowToObj(row, password);
}
int CKMLogic::readDataHelper(
password, obj, objDataType);
}
-int CKMLogic::readDataHelper(
+int CKMLogic::readRowHelper(
bool exportFlag,
const Credentials &cred,
DataType dataType,
const Name &name,
const ClientId &owner,
const Password &password,
- Crypto::GObjUPtr &obj,
+ DB::Row &row,
DataType &objDataType)
{
auto [dbOp, permission, retCode] = beginAndGetPerm(cred, name, owner);
if (retCode != CKM_API_SUCCESS)
return retCode;
- DB::Row row;
retCode = readSingleRow(name, owner, dataType, dbOp.database(), row);
if (CKM_API_SUCCESS != retCode)
return retCode;
// check access rights
retCode = checkDataPermissionsHelper(cred, row, exportFlag, permission);
- if (CKM_API_SUCCESS != retCode)
+ if (retCode != CKM_API_SUCCESS)
return retCode;
auto digest = CryptoLogic::makeHash(name, owner, cred.clientUid);
if (digest.empty())
return CKM_API_ERROR_HASH_ERROR;
- obj = rowToObject(dbOp.handler(), std::move(row), password, digest);
- // rowToObject may modify db
+ decryptRow(dbOp.handler(), row, password, digest);
+
+ // decryptRow may modify db
dbOp.transaction().commit();
return CKM_API_SUCCESS;
}
+Crypto::GObjUPtr CKMLogic::decryptedRowToObj(const DB::Row& row, const Password &password)
+{
+ Crypto::GStore &store = m_decider.getStore(row);
+
+ Password pass = m_accessControl.isCCMode() ? "" : password;
+ return store.getObject(row, pass);
+}
+
+int CKMLogic::readDataHelper(
+ bool exportFlag,
+ const Credentials &cred,
+ DataType dataType,
+ const Name &name,
+ const ClientId &owner,
+ const Password &password,
+ Crypto::GObjUPtr &obj,
+ DataType &objDataType)
+{
+ DB::Row row;
+ int retCode = readRowHelper(exportFlag, cred, dataType, name, owner, password, row, objDataType);
+ if (retCode != CKM_API_SUCCESS)
+ return retCode;
+
+ obj = decryptedRowToObj(row, password);
+
+ return CKM_API_SUCCESS;
+}
+
RawBuffer CKMLogic::getData(
const Credentials &cred,
int msgId,
bool exportFlag,
const PermissionMask& permission);
+ void decryptRow(
+ UserData &handler,
+ DB::Row &row,
+ const Password &password,
+ const RawBuffer &hash);
+
Crypto::GObjUPtr rowToObject(
UserData &handler,
DB::Row row,
Crypto::GObjUPtr &obj);
private:
+ int readRowHelper(
+ bool exportFlag,
+ const Credentials &cred,
+ DataType dataType,
+ const Name &name,
+ const ClientId &owner,
+ const Password &password,
+ DB::Row &row,
+ DataType &objDataType);
+
+ Crypto::GObjUPtr decryptedRowToObj(const DB::Row& row, const Password &password);
+
int readDataHelper(
bool exportFlag,
const Credentials &cred,
DB::Row encryptOne(Token&& token, const Policy& policy) {
DB::Row row(std::move(token), m_name, m_owner, static_cast<int>(policy.extractable));
- m_handler.crypto.encryptRow(row);
- return row;
+ return m_handler.crypto.encryptRow(row);
}
void finalize(Token&& token, const Policy& policy) {
return civ;
}
-void CryptoLogic::encryptRow(DB::Row &row)
+DB::Row CryptoLogic::encryptRow(const DB::Row &row)
{
DB::Row crow = row;
RawBuffer key;
if (crow.dataSize <= 0)
ThrowErr(Exc::InternalError, "Invalid dataSize.");
- if (!haveKey(row.owner))
+ if (!haveKey(crow.owner))
ThrowErr(Exc::InternalError, "Missing application key for ",
- row.owner, " client.");
+ crow.owner, " client.");
if (crow.iv.empty())
crow.iv = generateRandIV();
- key = m_keyMap[row.owner];
+ key = m_keyMap[crow.owner];
CLEAR_FLAGS(crow.encryptionScheme);
SET_FLAG(ENCR_APPKEY, crow.encryptionScheme);
SET_ENCRYPTION_VERSION(ENCRYPTION_V2, crow.encryptionScheme);
- row = std::move(crow);
+ return crow;
}
int CryptoLogic::getSchemeVersion(int encryptionScheme)
virtual ~CryptoLogic() {}
void decryptRow(const Password &password, DB::Row &row);
- void encryptRow(DB::Row &row);
+ DB::Row encryptRow(const DB::Row &row);
static int getSchemeVersion(int encryptionScheme);
CryptoLogic logic;
- DB::Row rowCopy = row;
+ DB::Row rowCopy;
BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
- BOOST_REQUIRE_NO_THROW(logic.encryptRow(rowCopy));
+ BOOST_REQUIRE_NO_THROW(rowCopy = logic.encryptRow(row));
BOOST_REQUIRE(rowCopy.algorithmType == DBCMAlgType::AES_GCM_256);
BOOST_REQUIRE(rowCopy.dataSize == static_cast<int>(row.data.size()));
BOOST_REQUIRE(!rowCopy.iv.empty());
row.iv.clear();
// correct encryption
- BOOST_REQUIRE_NO_THROW(logic.encryptRow(row));
+ DB::Row encryptedRow;
+ BOOST_REQUIRE_NO_THROW(encryptedRow = logic.encryptRow(row));
// wrong algorithm
- row.algorithmType = DBCMAlgType::NONE;
- BOOST_REQUIRE_THROW(logic.decryptRow("", row), Exc::AuthenticationFailed);
- row.algorithmType = DBCMAlgType::AES_GCM_256;
+ encryptedRow.algorithmType = DBCMAlgType::NONE;
+ BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
+ encryptedRow.algorithmType = DBCMAlgType::AES_GCM_256;
// unnecessary password
- BOOST_REQUIRE_THROW(logic.decryptRow("unnecessary password", row),
+ BOOST_REQUIRE_THROW(logic.decryptRow("unnecessary password", encryptedRow),
Exc::AuthenticationFailed);
// no key
BOOST_REQUIRE_NO_THROW(logic.removeKey(TEST_CLIENT));
- BOOST_REQUIRE_THROW(logic.decryptRow("", row), Exc::AuthenticationFailed);
+ BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
BOOST_REQUIRE_NO_THROW(logic.pushKey(TEST_CLIENT, TEST_KEY));
// wrong owner
- ++row.owner[0];
- BOOST_REQUIRE_THROW(logic.decryptRow("", row), Exc::AuthenticationFailed);
- --row.owner[0];
+ ++encryptedRow.owner[0];
+ BOOST_REQUIRE_THROW(logic.decryptRow("", encryptedRow), Exc::AuthenticationFailed);
+ --encryptedRow.owner[0];
// no iv
- auto rowCopy = row;
+ auto rowCopy = encryptedRow;
rowCopy.iv.clear();
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
// wrong iv (not base64)
- rowCopy = row;
+ rowCopy = encryptedRow;
rowCopy.iv[0] = 64;
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
// wrong iv
- rowCopy = row;
+ rowCopy = encryptedRow;
changeBase64(rowCopy.iv);
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
// no ciphertext
- rowCopy = row;
+ rowCopy = encryptedRow;
rowCopy.data.clear();
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy),Exc::InternalError);
// wrong ciphertext (not base64)
- rowCopy = row;
+ rowCopy = encryptedRow;
rowCopy.data[0] = 64;
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::InternalError);
// wrong ciphertext
- rowCopy = row;
+ rowCopy = encryptedRow;
changeBase64(rowCopy.data);
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
// wrong tag
- rowCopy = row;
+ rowCopy = encryptedRow;
++rowCopy.tag[0];
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
// wrong dataSize
- rowCopy = row;
+ rowCopy = encryptedRow;
++rowCopy.dataSize;
BOOST_REQUIRE_THROW(logic.decryptRow("", rowCopy), Exc::AuthenticationFailed);
}