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>
31 #include <generic-key.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 LogError("Datatype: " << (int) row.dataType);
269 return KEY_MANAGER_API_SUCCESS;
272 RawBuffer CKMLogic::getData(
277 const std::string &password)
279 int retCode = KEY_MANAGER_API_SUCCESS;
283 retCode = getDataHelper(cred, dataType, alias, password, row);
284 } catch (const KeyProvider::Exception::Base &e) {
285 LogError("KeyProvider failed with error: " << e.GetMessage());
286 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
287 } catch (const DBCryptoModule::Exception::Base &e) {
288 LogError("DBCryptoModule failed with message: " << e.GetMessage());
289 retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
292 if (KEY_MANAGER_API_SUCCESS != retCode) {
294 row.dataType = dataType;
297 LogError("Sending dataType: " << (int)row.dataType);
299 MessageBuffer response;
300 Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
301 Serialization::Serialize(response, commandId);
302 Serialization::Serialize(response, retCode);
303 Serialization::Serialize(response, static_cast<int>(row.dataType));
304 Serialization::Serialize(response, row.data);
305 return response.Pop();
308 RawBuffer CKMLogic::getDataList(
313 int retCode = KEY_MANAGER_API_SUCCESS;
314 AliasVector aliasVector;
316 if (0 < m_userDataMap.count(cred.uid)) {
317 auto &handler = m_userDataMap[cred.uid];
318 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
319 retCode = handler.database.getAliases(dataType, cred.smackLabel, aliasVector);
321 retCode = handler.database.getKeyAliases(cred.smackLabel, aliasVector);
324 retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
327 MessageBuffer response;
328 Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_LIST));
329 Serialization::Serialize(response, commandId);
330 Serialization::Serialize(response, retCode);
331 Serialization::Serialize(response, static_cast<int>(dataType));
332 Serialization::Serialize(response, aliasVector);
333 return response.Pop();
336 int CKMLogic::createKeyPairRSAHelper(
339 const Alias &aliasPrivate,
340 const Alias &aliasPublic,
341 const PolicySerializable &policyPrivate,
342 const PolicySerializable &policyPublic)
344 if (0 >= m_userDataMap.count(cred.uid))
345 return KEY_MANAGER_API_ERROR_DB_LOCKED;
347 auto &handler = m_userDataMap[cred.uid];
352 if (CKM_CRYPTO_CREATEKEY_SUCCESS != (retCode = cr.createKeyPairRSA(size, prv, pub))) {
353 LogError("CryptoService failed with code: " << retCode);
354 return KEY_MANAGER_API_ERROR_SERVER_ERROR; // TODO error code
357 retCode = saveDataHelper(cred,
358 toDBDataType(prv.getType()),
363 if (KEY_MANAGER_API_SUCCESS != retCode)
366 retCode = saveDataHelper(cred,
367 toDBDataType(pub.getType()),
372 if (KEY_MANAGER_API_SUCCESS != retCode) {
373 handler.database.deleteDBRow(aliasPrivate, cred.smackLabel);
379 RawBuffer CKMLogic::createKeyPairRSA(
383 const Alias &aliasPrivate,
384 const Alias &aliasPublic,
385 const PolicySerializable &policyPrivate,
386 const PolicySerializable &policyPublic)
388 int retCode = createKeyPairRSAHelper(
396 MessageBuffer response;
397 Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
398 Serialization::Serialize(response, commandId);
399 Serialization::Serialize(response, retCode);
401 return response.Pop();
404 int CKMLogic::createKeyPairECDSAHelper(
407 const Alias &aliasPrivate,
408 const Alias &aliasPublic,
409 const PolicySerializable &policyPrivate,
410 const PolicySerializable &policyPublic)
412 if (0 >= m_userDataMap.count(cred.uid))
413 return KEY_MANAGER_API_ERROR_DB_LOCKED;
415 auto &handler = m_userDataMap[cred.uid];
420 if (CKM_CRYPTO_CREATEKEY_SUCCESS != (retCode = cr.createKeyPairECDSA(
421 static_cast<ElipticCurve>(type), prv, pub)))
423 LogError("CryptoService failed with code: " << retCode);
424 return KEY_MANAGER_API_ERROR_SERVER_ERROR; // TODO error code
427 retCode = saveDataHelper(cred,
428 toDBDataType(prv.getType()),
433 if (KEY_MANAGER_API_SUCCESS != retCode)
436 retCode = saveDataHelper(cred,
437 toDBDataType(pub.getType()),
442 if (KEY_MANAGER_API_SUCCESS != retCode) {
443 handler.database.deleteDBRow(aliasPrivate, cred.smackLabel);
449 RawBuffer CKMLogic::createKeyPairECDSA(
453 const Alias &aliasPrivate,
454 const Alias &aliasPublic,
455 const PolicySerializable &policyPrivate,
456 const PolicySerializable &policyPublic)
458 int retCode = createKeyPairECDSAHelper(
466 MessageBuffer response;
467 Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
468 Serialization::Serialize(response, commandId);
469 Serialization::Serialize(response, retCode);
471 return response.Pop();