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>
29 #include <CryptoService.h>
30 #include <ckm-logic.h>
36 int retCode = FileSystem::init();
37 // TODO what can I do when init went wrong? exit(-1) ??
39 LogError("Fatal error in FileSystem::init()");
43 CKMLogic::~CKMLogic(){}
45 RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
46 // TODO try catch for all errors that should be supported by error code
47 int retCode = KEY_MANAGER_API_SUCCESS;
50 if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
51 auto &handle = m_userDataMap[user];
53 auto wrappedDomainKEK = fs.getDomainKEK();
55 if (wrappedDomainKEK.empty()) {
56 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
57 fs.saveDomainKEK(wrappedDomainKEK);
60 handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
62 RawBuffer key = handle.keyProvider.getPureDomainKEK();
63 handle.database = DBCrypto(fs.getDBPath(), key);
64 handle.crypto = DBCryptoModule(key);
67 } catch (const KeyProvider::Exception::Base &e) {
68 LogError("Error in KeyProvider " << e.GetMessage());
69 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
72 MessageBuffer response;
73 Serialization::Serialize(response, retCode);
74 return response.Pop();
77 RawBuffer CKMLogic::lockUserKey(uid_t user) {
78 int retCode = KEY_MANAGER_API_SUCCESS;
79 // TODO try catch for all errors that should be supported by error code
80 m_userDataMap.erase(user);
82 MessageBuffer response;
83 Serialization::Serialize(response, retCode);
84 return response.Pop();
87 RawBuffer CKMLogic::removeUserData(uid_t user) {
88 int retCode = KEY_MANAGER_API_SUCCESS;
89 // TODO try catch for all errors that should be supported by error code
90 m_userDataMap.erase(user);
95 MessageBuffer response;
96 Serialization::Serialize(response, retCode);
97 return response.Pop();
100 RawBuffer CKMLogic::changeUserPassword(
102 const std::string &oldPassword,
103 const std::string &newPassword)
105 int retCode = KEY_MANAGER_API_SUCCESS;
108 auto wrappedDomainKEK = fs.getDomainKEK();
109 if (wrappedDomainKEK.empty()) {
110 retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
112 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
113 fs.saveDomainKEK(wrappedDomainKEK);
115 MessageBuffer response;
116 Serialization::Serialize(response, retCode);
117 return response.Pop();
120 RawBuffer CKMLogic::resetUserPassword(
122 const std::string &newPassword)
124 int retCode = KEY_MANAGER_API_SUCCESS;
126 if (0 == m_userDataMap.count(user)) {
127 retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
129 auto &handler = m_userDataMap[user];
131 fs.saveDomainKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
134 MessageBuffer response;
135 Serialization::Serialize(response, retCode);
136 return response.Pop();
139 int CKMLogic::saveDataHelper(
143 const RawBuffer &key,
144 const PolicySerializable &policy)
146 if (0 == m_userDataMap.count(cred.uid))
147 return KEY_MANAGER_API_ERROR_DB_LOCKED;
149 DBRow row = { alias, cred.smackLabel, policy.restricted,
150 policy.extractable, dataType, DBCMAlgType::NONE,
151 0, RawBuffer(10, 'c'), key.size(), key };
153 auto &handler = m_userDataMap[cred.uid];
154 if (!handler.crypto.haveKey(cred.smackLabel)) {
156 int status = handler.database.getKey(cred.smackLabel, key);
157 if (KEY_MANAGER_API_ERROR_DB_BAD_REQUEST == status) {
158 LogDebug("No Key in database found. Generating new one for label: " << cred.smackLabel);
159 key = handler.keyProvider.generateDEK(cred.smackLabel);
160 if (KEY_MANAGER_API_SUCCESS != handler.database.saveKey(cred.smackLabel, key)) {
161 LogError("Failed to save key for smack label: " << cred.smackLabel);
162 return KEY_MANAGER_API_ERROR_DB_ERROR;
165 key = handler.keyProvider.getPureDEK(key);
166 handler.crypto.pushKey(cred.smackLabel, key);
168 handler.crypto.encryptRow(policy.password, row);
169 return handler.database.saveDBRow(row);
172 RawBuffer CKMLogic::saveData(
177 const RawBuffer &key,
178 const PolicySerializable &policy)
180 int retCode = KEY_MANAGER_API_SUCCESS;
183 retCode = saveDataHelper(cred, dataType, alias, key, policy);
184 LogDebug("SaveDataHelper returned: " << retCode);
185 } catch (const KeyProvider::Exception::Base &e) {
186 LogError("KeyProvider failed with message: " << e.GetMessage());
187 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
188 } catch (const DBCryptoModule::Exception::Base &e) {
189 LogError("DBCryptoModule failed with message: " << e.GetMessage());
190 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
193 MessageBuffer response;
194 Serialization::Serialize(response, static_cast<int>(LogicCommand::SAVE));
195 Serialization::Serialize(response, commandId);
196 Serialization::Serialize(response, retCode);
197 Serialization::Serialize(response, static_cast<int>(dataType));
199 return response.Pop();
202 RawBuffer CKMLogic::removeData(
208 int retCode = KEY_MANAGER_API_SUCCESS;
210 if (0 < m_userDataMap.count(cred.uid)) {
211 retCode = m_userDataMap[cred.uid].database.deleteDBRow(alias, cred.smackLabel);
213 retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
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,
232 int retCode = KEY_MANAGER_API_SUCCESS;
234 if (0 == m_userDataMap.count(cred.uid))
235 return KEY_MANAGER_API_ERROR_DB_LOCKED;
237 auto &handler = m_userDataMap[cred.uid];
239 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
240 retCode = handler.database.getDBRow(alias, cred.smackLabel, dataType, row);
241 } else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST))
242 && (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
244 retCode = handler.database.getKeyDBRow(alias, cred.smackLabel, row);
246 LogError("Unknown type of requested data" << (int)dataType);
247 return KEY_MANAGER_API_ERROR_BAD_REQUEST;
250 if (KEY_MANAGER_API_SUCCESS != retCode){
251 LogDebug("DBCrypto::getDBRow failed with code: " << retCode);
255 if (!handler.crypto.haveKey(row.smackLabel)) {
257 retCode = handler.database.getKey(row.smackLabel, key);
258 if (KEY_MANAGER_API_SUCCESS != retCode) {
259 LogDebug("DBCrypto::getKey failed with: " << retCode);
262 key = handler.keyProvider.getPureDEK(key);
263 handler.crypto.pushKey(cred.smackLabel, key);
265 handler.crypto.decryptRow(password, row);
267 return KEY_MANAGER_API_SUCCESS;
270 RawBuffer CKMLogic::getData(
275 const std::string &password)
277 int retCode = KEY_MANAGER_API_SUCCESS;
281 retCode = getDataHelper(cred, dataType, alias, password, row);
282 } catch (const KeyProvider::Exception::Base &e) {
283 LogError("KeyProvider failed with error: " << e.GetMessage());
284 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
285 } catch (const DBCryptoModule::Exception::Base &e) {
286 LogError("DBCryptoModule failed with message: " << e.GetMessage());
287 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
290 if (KEY_MANAGER_API_SUCCESS != retCode) {
292 row.dataType = dataType;
295 MessageBuffer response;
296 Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
297 Serialization::Serialize(response, commandId);
298 Serialization::Serialize(response, retCode);
299 Serialization::Serialize(response, static_cast<int>(row.dataType));
300 Serialization::Serialize(response, row.data);
301 return response.Pop();
304 RawBuffer CKMLogic::getDataList(
309 int retCode = KEY_MANAGER_API_SUCCESS;
310 AliasVector aliasVector;
312 if (0 < m_userDataMap.count(cred.uid)) {
313 auto &handler = m_userDataMap[cred.uid];
314 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
315 retCode = handler.database.getAliases(dataType, cred.smackLabel, aliasVector);
317 retCode = handler.database.getKeyAliases(cred.smackLabel, aliasVector);
320 retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
323 MessageBuffer response;
324 Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_LIST));
325 Serialization::Serialize(response, commandId);
326 Serialization::Serialize(response, retCode);
327 Serialization::Serialize(response, static_cast<int>(dataType));
328 Serialization::Serialize(response, aliasVector);
329 return response.Pop();
332 int CKMLogic::createKeyPairRSAHelper(
335 const Alias &aliasPrivate,
336 const Alias &aliasPublic,
337 const PolicySerializable &policyPrivate,
338 const PolicySerializable &policyPublic)
340 if (0 >= m_userDataMap.count(cred.uid))
341 return KEY_MANAGER_API_ERROR_DB_LOCKED;
343 auto &handler = m_userDataMap[cred.uid];
349 if (CKM_CRYPTO_CREATEKEY_SUCCESS != (retCode = cr.createKeyPairRSA(size, prv, pub))) {
350 LogError("CryptoService failed with code: " << retCode);
351 return KEY_MANAGER_API_ERROR_SERVER_ERROR; // TODO error code
354 retCode = saveDataHelper(cred,
355 toDBDataType(prv.getType()),
360 if (KEY_MANAGER_API_SUCCESS != retCode)
363 retCode = saveDataHelper(cred,
364 toDBDataType(pub.getType()),
369 if (KEY_MANAGER_API_SUCCESS != retCode) {
370 handler.database.deleteDBRow(aliasPrivate, cred.smackLabel);
376 RawBuffer CKMLogic::createKeyPairRSA(
380 const Alias &aliasPrivate,
381 const Alias &aliasPublic,
382 const PolicySerializable &policyPrivate,
383 const PolicySerializable &policyPublic)
385 int retCode = createKeyPairRSAHelper(
393 MessageBuffer response;
394 Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
395 Serialization::Serialize(response, commandId);
396 Serialization::Serialize(response, retCode);
398 return response.Pop();
401 RawBuffer CKMLogic::createKeyPairECDSA(
405 const Alias &aliasPrivate,
406 const Alias &aliasPublic,
407 const PolicySerializable &policyPrivate,
408 const PolicySerializable &policyPublic)
417 MessageBuffer response;
418 Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
419 Serialization::Serialize(response, commandId);
420 Serialization::Serialize(response, static_cast<int>(KEY_MANAGER_API_SUCCESS));
422 return response.Pop();