2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
18 * @author Mateusz Cegielka (m.cegielka@samsung.com)
29 #include <credentials.h>
30 #include <generic-backend/gobj.h>
36 int findColumnByName(const std::string &name, const CKM::Decrypt::Row &columns)
38 auto column = std::find(columns.begin(), columns.end(), name);
39 if (column == columns.end())
42 return column - columns.begin();
45 std::string fmtObject(const CKM::NameEntry &name)
47 return "'" + name.name + "'";
50 CKM::Password askObjectPassword(const std::string &displayName)
52 std::string password = CKM::UI::promptPassword(
53 "enter password for object " + displayName + ":");
54 return CKM::Password(password.begin(), password.end());
57 } // anonymous namespace
61 Decrypt::Decrypt(const Row &columns, CKMLogicExt &logic, uid_t uid)
68 m_columnData = findColumnByName("data", columns);
69 if (m_columnData == -1)
71 m_columnDataType = findColumnByName("dataType", columns);
72 m_columnIdx = findColumnByName("idx", columns);
73 if (m_columnDataType == -1 || m_columnIdx == -1)
74 UI::warning() << "unable to decrypt, missing dataType or idx columns" << std::endl;
77 bool Decrypt::canDecryptQuery() const
79 return m_columnData != -1 && m_columnDataType != -1 && m_columnIdx != -1;
82 std::pair<std::string, bool> Decrypt::tryDecrypt(const Row &row) const
84 NameEntry nameEntry = getNameEntry(row);
85 std::string name = fmtObject(nameEntry);
88 return {decrypt(row, "", nameEntry), true};
89 } catch (const Exc::AuthenticationFailed &) {
93 Password password = askObjectPassword(name);
94 if (password.empty()) {
95 UI::warning() << "skipped decrypting object " << name << std::endl;
100 return {decrypt(row, password, nameEntry), true};
101 } catch (const Exc::AuthenticationFailed &) {
102 UI::error() << "authentication failed for object " << name << std::endl;
107 int Decrypt::getDataColumnIndex() const
112 NameEntry Decrypt::getNameEntry(const Row &row) const
114 int idx = std::stoi(row[m_columnIdx]);
116 return m_logic.getNameByIdx(m_uid, idx);
119 std::string Decrypt::decrypt(const Row &row, const Password &password,
120 const NameEntry& nameEntry) const
122 DataType dataType = static_cast<DataType::Type>(std::stoi(row[m_columnDataType]));
123 Credentials credentials(m_uid, nameEntry.owner);
124 Crypto::GObjUPtr obj;
126 int ret = m_logic.readDataHelperProtected(credentials, dataType, nameEntry.name,
127 nameEntry.owner, password, obj);
128 if (ret != CKM_API_SUCCESS)
129 throw std::logic_error("reading row data failed");
131 RawBuffer decrypted = obj->getBinary();
132 UI::info() << "decrypted object " << fmtObject(nameEntry) << std::endl;
133 return std::string(decrypted.begin(), decrypted.end());