2 * Copyright (c) 2014 - 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
17 * @file ckm-service.cpp
18 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
20 * @brief CKM service implementation.
23 #include <protocols.h>
25 #include <dpl/serialization.h>
26 #include <dpl/log/log.h>
28 #include <ckm-service.h>
29 #include <ckm-logic.h>
30 #include <initial-value-loader.h>
33 const CKM::InterfaceID SOCKET_ID_CONTROL = 0;
34 const CKM::InterfaceID SOCKET_ID_STORAGE = 1;
35 } // namespace anonymous
39 CKMService::CKMService() :
42 InitialValues::LoadFiles(*m_logic);
45 CKMService::~CKMService()
50 void CKMService::Start()
52 // unlock system db at first to migrate old ss data earlier than user db unlocked.
53 // Because data should be migrated to both of system db and user(default owner) db
54 // and old data resource will be removed after migrated to user db
55 m_logic->unlockSystemDB();
60 void CKMService::Stop()
65 GenericSocketService::ServiceDescriptionVector
66 CKMService::GetServiceDescription()
68 // empty string on privilege field means non-privileged
69 return ServiceDescriptionVector {
70 {SERVICE_SOCKET_CKM_CONTROL, "http://tizen.org/privilege/internal/service", SOCKET_ID_CONTROL},
71 {SERVICE_SOCKET_CKM_STORAGE, "", SOCKET_ID_STORAGE}
75 void CKMService::SetCommManager(CommMgr *manager)
77 ThreadService::SetCommManager(manager);
81 bool CKMService::ProcessOne(
82 const ConnectionID &conn,
86 LogDebug("process One");
90 if (!info.buffer.Ready())
93 if (info.interfaceID == SOCKET_ID_CONTROL)
94 response = ProcessControl(info.buffer, allowed);
96 response = ProcessStorage(info.credentials, info.buffer);
98 m_serviceManager->Write(conn, response);
101 } catch (const MessageBuffer::Exception::Base &e) {
102 LogError("Broken protocol. Closing socket: " << e.DumpToString());
103 } catch (const Exception::BrokenProtocol &e) {
104 LogError("Broken protocol. Closing socket: " << e.DumpToString());
105 } catch (const std::string &e) {
106 LogError("String exception(" << e << "). Closing socket");
107 } catch (const std::exception &e) {
108 LogError("Std exception:: " << e.what());
110 LogError("Unknown exception. Closing socket.");
113 m_serviceManager->Close(conn);
117 RawBuffer CKMService::ProcessControl(MessageBuffer &buffer, bool allowed)
122 Password newPass, oldPass;
123 ClientId explicitOwner;
125 buffer.Deserialize(command);
127 LogDebug("Process control. Command: " << command);
129 std::function<RawBuffer(void)> logicFunc;
131 cc = static_cast<ControlCommand>(command);
134 case ControlCommand::UNLOCK_USER_KEY:
135 buffer.Deserialize(user, newPass);
137 return m_logic->unlockUserKey(user, newPass);
141 case ControlCommand::LOCK_USER_KEY:
142 buffer.Deserialize(user);
144 return m_logic->lockUserKey(user);
148 case ControlCommand::REMOVE_USER_DATA:
149 buffer.Deserialize(user);
151 return m_logic->removeUserData(user);
155 case ControlCommand::CHANGE_USER_PASSWORD:
156 buffer.Deserialize(user, oldPass, newPass);
158 return m_logic->changeUserPassword(user, oldPass, newPass);
162 case ControlCommand::RESET_USER_PASSWORD:
163 buffer.Deserialize(user, newPass);
165 return m_logic->resetUserPassword(user, newPass);
169 case ControlCommand::REMOVE_APP_DATA:
170 buffer.Deserialize(explicitOwner);
172 return m_logic->removeApplicationData(explicitOwner);
176 case ControlCommand::UPDATE_CC_MODE:
178 return m_logic->updateCCMode();
182 case ControlCommand::SET_PERMISSION: {
185 PermissionMask permissionMask = 0;
187 buffer.Deserialize(user, name, explicitOwner, accessor, permissionMask);
189 Credentials cred(user, explicitOwner);
190 logicFunc = [&, name, explicitOwner, accessor, permissionMask, cred]() {
191 return m_logic->setPermission(
195 cred.effectiveOwner(explicitOwner),
203 Throw(Exception::BrokenProtocol);
207 LogError("Access denied!");
208 return SerializeMessage(CKM_API_ERROR_ACCESS_DENIED);
214 RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
218 DataType tmpDataType;
220 ClientId explicitOwner, accessor;
222 buffer.Deserialize(command);
223 buffer.Deserialize(msgId);
225 // This is a workaround solution for locktype=None in Tizen 2.2.1
226 // When locktype is None, lockscreen app doesn't interfere with unlocking process.
227 // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None.
228 // So, to unlock user data when lock type is None, key-manager always try to unlock user data with null password.
229 // Even if the result is fail, it will be ignored.
230 Password nullPassword("");
231 m_logic->unlockUserKey(cred.clientUid, nullPassword);
233 LogDebug("Process storage. Command: " << command);
235 switch (static_cast<LogicCommand>(command)) {
236 case LogicCommand::SAVE: {
238 PolicySerializable policy;
239 buffer.Deserialize(tmpDataType, name, explicitOwner, rawData, policy);
240 return m_logic->saveData(
244 cred.effectiveOwner(explicitOwner),
245 Crypto::Data(tmpDataType, std::move(rawData)),
249 case LogicCommand::SAVE_PKCS12: {
251 PKCS12Serializable pkcs;
252 PolicySerializable keyPolicy, certPolicy;
253 buffer.Deserialize(name, explicitOwner, pkcs, keyPolicy, certPolicy);
254 return m_logic->savePKCS12(
258 cred.effectiveOwner(explicitOwner),
264 case LogicCommand::REMOVE: {
265 buffer.Deserialize(name, explicitOwner);
266 return m_logic->removeData(
270 cred.effectiveOwner(explicitOwner));
273 case LogicCommand::GET: {
275 buffer.Deserialize(tmpDataType, name, explicitOwner, password);
276 return m_logic->getData(
281 cred.effectiveOwner(explicitOwner),
285 case LogicCommand::GET_PKCS12: {
288 buffer.Deserialize(name, explicitOwner, passKey, passCert);
289 return m_logic->getPKCS12(
293 cred.effectiveOwner(explicitOwner),
298 case LogicCommand::GET_PROTECTION_STATUS: {
299 buffer.Deserialize(tmpDataType, name, explicitOwner);
300 return m_logic->getDataProtectionStatus(
305 cred.effectiveOwner(explicitOwner));
308 case LogicCommand::GET_LIST: {
309 buffer.Deserialize(tmpDataType);
310 return m_logic->getDataList(
316 case LogicCommand::CREATE_KEY_AES: {
318 PolicySerializable policyKey;
319 buffer.Deserialize(size, policyKey, name, explicitOwner);
320 return m_logic->createKeyAES(
325 cred.effectiveOwner(explicitOwner),
329 case LogicCommand::CREATE_KEY_PAIR: {
330 CryptoAlgorithmSerializable keyGenAlgorithm;
332 ClientId explicitOwnerPrivate;
334 ClientId explicitOwnerPublic;
335 PolicySerializable policyPrivateKey;
336 PolicySerializable policyPublicKey;
337 buffer.Deserialize(keyGenAlgorithm,
341 explicitOwnerPrivate,
343 explicitOwnerPublic);
344 return m_logic->createKeyPair(
349 cred.effectiveOwner(explicitOwnerPrivate),
351 cred.effectiveOwner(explicitOwnerPublic),
356 case LogicCommand::GET_CHAIN_CERT: {
357 RawBuffer certificate;
358 RawBufferVector untrustedVector;
359 RawBufferVector trustedVector;
360 bool systemCerts = false;
361 buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts);
362 return m_logic->getCertificateChain(
371 case LogicCommand::GET_CHAIN_ALIAS: {
372 RawBuffer certificate;
373 OwnerNameVector untrustedVector;
374 OwnerNameVector trustedVector;
375 bool systemCerts = false;
376 buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts);
377 return m_logic->getCertificateChain(
386 case LogicCommand::CREATE_SIGNATURE: {
387 Password password; // password for private_key
390 CryptoAlgorithmSerializable cAlgorithm;
391 buffer.Deserialize(name, explicitOwner, password, message, cAlgorithm);
393 return m_logic->createSignature(
397 cred.effectiveOwner(explicitOwner),
398 password, // password for private_key
403 case LogicCommand::VERIFY_SIGNATURE: {
404 Password password; // password for public_key (optional)
407 CryptoAlgorithmSerializable cAlg;
409 buffer.Deserialize(name, explicitOwner, password, message, signature, cAlg);
411 return m_logic->verifySignature(
415 cred.effectiveOwner(explicitOwner),
416 password, // password for public_key (optional)
422 case LogicCommand::SET_PERMISSION: {
423 PermissionMask permissionMask = 0;
424 buffer.Deserialize(name, explicitOwner, accessor, permissionMask);
425 return m_logic->setPermission(
429 cred.effectiveOwner(explicitOwner),
434 case LogicCommand::DERIVE: {
435 CryptoAlgorithmSerializable keyDerivationAlgorithm;
437 ClientId secretExplicitOwner;
438 Password secretPassword;
440 ClientId newKeyExplicitOwner;
441 PolicySerializable newKeyPolicy;
442 buffer.Deserialize(keyDerivationAlgorithm,
449 return m_logic->deriveKey(
452 keyDerivationAlgorithm,
454 cred.effectiveOwner(secretExplicitOwner),
457 cred.effectiveOwner(newKeyExplicitOwner),
461 case LogicCommand::IMPORT_WRAPPED_KEY: {
462 CryptoAlgorithmSerializable params;
463 Name wrappingKeyName;
464 ClientId wrappingKeyOwner;
465 Password wrappingKeyPassword;
467 RawBuffer wrappedKey;
468 CKM::DataType keyType;
469 PolicySerializable policy;
471 buffer.Deserialize(params,
481 return m_logic->importWrappedKey(
486 cred.effectiveOwner(wrappingKeyOwner),
489 cred.effectiveOwner(explicitOwner),
495 case LogicCommand::EXPORT_WRAPPED_KEY: {
496 CryptoAlgorithmSerializable params;
497 Name wrappingKeyName;
498 ClientId wrappingKeyOwner;
499 Password wrappingKeyPassword;
501 ClientId wrappedKeyOwner;
502 Password wrappedKeyPassword;
504 buffer.Deserialize(params,
512 return m_logic->exportWrappedKey(
517 cred.effectiveOwner(wrappingKeyOwner),
520 cred.effectiveOwner(wrappedKeyOwner),
525 Throw(Exception::BrokenProtocol);
529 void CKMService::ProcessMessage(MsgKeyRequest msg)
531 Crypto::GObjShPtr key;
532 int ret = m_logic->getKeyForService(msg.cred,
534 msg.cred.effectiveOwner(msg.explicitOwner),
537 MsgKeyResponse kResp(msg.id, key, ret);
540 if (!m_commMgr->SendMessage(kResp))
541 LogError("No listener found"); // can't do much more
543 LogError("Uncaught exception in SendMessage. Check listeners.");
547 void CKMService::ProcessMessage(MsgRemoveAppData msg)
549 LogDebug("Call removeApplicationData. pkgId: " << msg.pkgId);
550 m_logic->removeApplicationData(msg.pkgId);