2 * Copyright (c) 2000 - 2014 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 Bartlomiej Grzelewski (b.grzelewski@samsung.com)
20 * @brief Sample service implementation.
22 #include <dpl/serialization.h>
23 #include <dpl/log/log.h>
25 #include <ckm/ckm-error.h>
26 #include <ckm/ckm-type.h>
27 #include <key-provider.h>
28 #include <file-system.h>
30 #include <ckm-logic.h>
35 int retCode = FileSystem::init();
36 // TODO what can I do when init went wrong? exit(-1) ??
38 LogError("Fatal error in FileSystem::init()");
42 CKMLogic::~CKMLogic(){}
44 RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
45 // TODO try catch for all errors that should be supported by error code
46 int retCode = KEY_MANAGER_API_SUCCESS;
49 if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
50 auto &handle = m_userDataMap[user];
52 auto wrappedDomainKEK = fs.getDomainKEK();
54 if (wrappedDomainKEK.empty()) {
55 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
56 fs.saveDomainKEK(wrappedDomainKEK);
59 handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
61 RawBuffer key = handle.keyProvider.getPureDomainKEK();
62 handle.database = DBCrypto(fs.getDBPath(), key);
63 handle.crypto = DBCryptoModule(key);
66 } catch (const KeyProvider::Exception::Base &e) {
67 LogError("Error in KeyProvider " << e.GetMessage());
68 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
71 MessageBuffer response;
72 Serialization::Serialize(response, retCode);
73 return response.Pop();
76 RawBuffer CKMLogic::lockUserKey(uid_t user) {
77 int retCode = KEY_MANAGER_API_SUCCESS;
78 // TODO try catch for all errors that should be supported by error code
79 m_userDataMap.erase(user);
81 MessageBuffer response;
82 Serialization::Serialize(response, retCode);
83 return response.Pop();
86 RawBuffer CKMLogic::removeUserData(uid_t user) {
87 int retCode = KEY_MANAGER_API_SUCCESS;
88 // TODO try catch for all errors that should be supported by error code
89 m_userDataMap.erase(user);
94 MessageBuffer response;
95 Serialization::Serialize(response, retCode);
96 return response.Pop();
99 RawBuffer CKMLogic::changeUserPassword(
101 const std::string &oldPassword,
102 const std::string &newPassword)
104 int retCode = KEY_MANAGER_API_SUCCESS;
107 auto wrappedDomainKEK = fs.getDomainKEK();
108 if (wrappedDomainKEK.empty()) {
109 retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
111 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
112 fs.saveDomainKEK(wrappedDomainKEK);
114 MessageBuffer response;
115 Serialization::Serialize(response, retCode);
116 return response.Pop();
119 RawBuffer CKMLogic::resetUserPassword(
121 const std::string &newPassword)
123 int retCode = KEY_MANAGER_API_SUCCESS;
125 if (0 == m_userDataMap.count(user)) {
126 retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
128 auto &handler = m_userDataMap[user];
130 fs.saveDomainKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
133 MessageBuffer response;
134 Serialization::Serialize(response, retCode);
135 return response.Pop();
138 int CKMLogic::saveDataHelper(
142 const RawBuffer &key,
143 const PolicySerializable &policy)
145 if (0 == m_userDataMap.count(cred.uid))
146 return KEY_MANAGER_API_ERROR_DB_LOCKED;
148 DBRow row = { alias, cred.smackLabel, policy.restricted,
149 policy.extractable, dataType, DBCMAlgType::NONE,
150 0, RawBuffer(10, 'c'), key.size(), key };
152 auto &handler = m_userDataMap[cred.uid];
153 if (!handler.crypto.haveKey(cred.smackLabel)) {
155 int status = handler.database.getKey(cred.smackLabel, key);
156 if (KEY_MANAGER_API_ERROR_DB_BAD_REQUEST == status) {
157 key = handler.keyProvider.generateDEK(cred.smackLabel);
158 if (KEY_MANAGER_API_SUCCESS != handler.database.saveKey(cred.smackLabel, key))
159 return KEY_MANAGER_API_ERROR_DB_ERROR;
161 key = handler.keyProvider.getPureDEK(key);
162 handler.crypto.pushKey(cred.smackLabel, key);
164 handler.crypto.encryptRow(policy.password, row);
165 return handler.database.saveDBRow(row);
168 RawBuffer CKMLogic::saveData(
173 const RawBuffer &key,
174 const PolicySerializable &policy)
176 int retCode = KEY_MANAGER_API_SUCCESS;
179 retCode = saveDataHelper(cred, dataType, alias, key, policy);
180 } catch (const KeyProvider::Exception::Base &e) {
181 LogError("KeyProvider failed with message: " << e.GetMessage());
182 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
183 } catch (const DBCryptoModule::Exception::Base &e) {
184 LogError("DBCryptoModule failed with message: " << e.GetMessage());
185 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
188 MessageBuffer response;
189 Serialization::Serialize(response, static_cast<int>(LogicCommand::SAVE));
190 Serialization::Serialize(response, commandId);
191 Serialization::Serialize(response, retCode);
192 Serialization::Serialize(response, static_cast<int>(dataType));
194 return response.Pop();
197 RawBuffer CKMLogic::removeData(
206 int retCode = KEY_MANAGER_API_SUCCESS;
208 if (0 == m_userDataMap.count(cred.uid)) {
209 retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
212 auto &handler = m_userDataMap[cred.uid];
216 MessageBuffer response;
217 Serialization::Serialize(response, static_cast<int>(LogicCommand::REMOVE));
218 Serialization::Serialize(response, commandId);
219 Serialization::Serialize(response, retCode);
220 Serialization::Serialize(response, static_cast<int>(dataType));
222 return response.Pop();
225 int CKMLogic::getDataHelper(
229 const std::string &password,
234 if (0 == m_userDataMap.count(cred.uid))
235 return KEY_MANAGER_API_ERROR_DB_LOCKED;
237 auto &handler = m_userDataMap[cred.uid];
238 int retCode = handler.database.getDBRow(alias, cred.smackLabel, row);
240 if (KEY_MANAGER_API_SUCCESS != retCode){
241 LogDebug("DBCrypto::getDBRow failed with code: " << retCode);
245 if (!handler.crypto.haveKey(row.smackLabel)) {
247 retCode = handler.database.getKey(row.smackLabel, key);
248 if (KEY_MANAGER_API_SUCCESS != retCode) {
249 LogDebug("DBCrypto::getKey failed with: " << retCode);
252 key = handler.keyProvider.getPureDEK(key);
253 handler.crypto.pushKey(cred.smackLabel, key);
255 handler.crypto.decryptRow(password, row);
257 return KEY_MANAGER_API_SUCCESS;
260 RawBuffer CKMLogic::getData(
265 const std::string &password)
267 int retCode = KEY_MANAGER_API_SUCCESS;
271 retCode = getDataHelper(cred, dataType, alias, password, row);
272 } catch (const KeyProvider::Exception::Base &e) {
273 LogError("KeyProvider failed with error: " << e.GetMessage());
274 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
275 } catch (const DBCryptoModule::Exception::Base &e) {
276 LogError("DBCryptoModule failed with message: " << e.GetMessage());
277 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
280 MessageBuffer response;
281 Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
282 Serialization::Serialize(response, commandId);
283 Serialization::Serialize(response, retCode);
284 Serialization::Serialize(response, static_cast<int>(row.dataType));
285 Serialization::Serialize(response, row.data);
286 return response.Pop();
289 RawBuffer CKMLogic::getDataList(
294 int retCode = KEY_MANAGER_API_SUCCESS;
296 if (0 == m_userDataMap.count(cred.uid)) {
297 retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
299 auto &handler = m_userDataMap[cred.uid];
304 MessageBuffer response;
305 Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_LIST));
306 Serialization::Serialize(response, commandId);
307 Serialization::Serialize(response, retCode);
308 Serialization::Serialize(response, static_cast<int>(dataType));
309 Serialization::Serialize(response, AliasVector());
310 return response.Pop();
313 RawBuffer CKMLogic::createKeyPairRSA(
317 const Alias &privateKeyAlias,
318 const Alias &publicKeyAlias,
319 PolicySerializable policyPrivateKey,
320 PolicySerializable policyPublicKey)
324 (void)privateKeyAlias;
325 (void)publicKeyAlias,
326 (void)policyPrivateKey;
327 (void)policyPublicKey;
328 MessageBuffer response;
329 Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
330 Serialization::Serialize(response, commandId);
331 Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
333 return response.Pop();
336 RawBuffer CKMLogic::createKeyPairECDSA(
340 const Alias &privateKeyAlias,
341 const Alias &publicKeyAlias,
342 PolicySerializable policyPrivateKey,
343 PolicySerializable policyPublicKey)
347 (void)privateKeyAlias;
348 (void)publicKeyAlias,
349 (void)policyPrivateKey;
350 (void)policyPublicKey;
352 MessageBuffer response;
353 Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
354 Serialization::Serialize(response, commandId);
355 Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
357 return response.Pop();