2 * Copyright (c) 2000 - 2015 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>
32 const CKM::InterfaceID SOCKET_ID_CONTROL = 0;
33 const CKM::InterfaceID SOCKET_ID_STORAGE = 1;
35 template <typename ...Args>
36 CKM::RawBuffer disallowed(int command, int msgID, Args&&... args) {
37 LogError("Disallowed command: " << command);
38 return CKM::MessageBuffer::Serialize(command,
40 CKM_API_ERROR_ACCESS_DENIED,
41 std::move(args)...).Pop();
43 } // namespace anonymous
47 CKMService::CKMService()
48 : m_logic(new CKMLogic)
51 CKMService::~CKMService() {
55 void CKMService::Start() {
59 void CKMService::Stop() {
63 GenericSocketService::ServiceDescriptionVector CKMService::GetServiceDescription()
65 return ServiceDescriptionVector {
66 {SERVICE_SOCKET_CKM_CONTROL, "http://tizen.org/privilege/keymanager.admin", SOCKET_ID_CONTROL},
67 {SERVICE_SOCKET_CKM_STORAGE, "http://tizen.org/privilege/keymanager", SOCKET_ID_STORAGE}
71 void CKMService::SetCommManager(CommMgr *manager)
73 ThreadService::SetCommManager(manager);
77 bool CKMService::ProcessOne(
78 const ConnectionID &conn,
82 LogDebug ("process One");
86 if (!info.buffer.Ready())
89 if (info.interfaceID == SOCKET_ID_CONTROL)
90 response = ProcessControl(info.buffer);
92 response = ProcessStorage(info.credentials, info.buffer, allowed);
94 m_serviceManager->Write(conn, response);
97 } Catch (MessageBuffer::Exception::Base) {
98 LogError("Broken protocol. Closing socket.");
99 } Catch (Exception::BrokenProtocol) {
100 LogError("Broken protocol. Closing socket.");
101 } catch (const DataType::Exception::Base &e) {
102 LogError("Closing socket. DBDataType::Exception: " << e.DumpToString());
103 } catch (const std::string &e) {
104 LogError("String exception(" << e << "). Closing socket");
105 } catch (const std::exception &e) {
106 LogError("Std exception:: " << e.what());
108 LogError("Unknown exception. Closing socket.");
111 m_serviceManager->Close(conn);
115 RawBuffer CKMService::ProcessControl(MessageBuffer &buffer) {
119 Password newPass, oldPass;
122 buffer.Deserialize(command);
124 LogDebug("Process control. Command: " << command);
126 cc = static_cast<ControlCommand>(command);
129 case ControlCommand::UNLOCK_USER_KEY:
130 buffer.Deserialize(user, newPass);
131 return m_logic->unlockUserKey(user, newPass);
132 case ControlCommand::LOCK_USER_KEY:
133 buffer.Deserialize(user);
134 return m_logic->lockUserKey(user);
135 case ControlCommand::REMOVE_USER_DATA:
136 buffer.Deserialize(user);
137 return m_logic->removeUserData(user);
138 case ControlCommand::CHANGE_USER_PASSWORD:
139 buffer.Deserialize(user, oldPass, newPass);
140 return m_logic->changeUserPassword(user, oldPass, newPass);
141 case ControlCommand::RESET_USER_PASSWORD:
142 buffer.Deserialize(user, newPass);
143 return m_logic->resetUserPassword(user, newPass);
144 case ControlCommand::REMOVE_APP_DATA:
145 buffer.Deserialize(smackLabel);
146 return m_logic->removeApplicationData(smackLabel);
147 case ControlCommand::UPDATE_CC_MODE:
148 return m_logic->updateCCMode();
149 case ControlCommand::SET_PERMISSION:
154 PermissionMask permissionMask = 0;
156 buffer.Deserialize(user, name, label, accessorLabel, permissionMask);
158 Credentials cred(user, label);
159 return m_logic->setPermission(
169 Throw(Exception::BrokenProtocol);
173 RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer, bool allowed)
179 Label label, accessorLabel;
182 buffer.Deserialize(command);
183 buffer.Deserialize(msgID);
185 // This is a workaround solution for locktype=None in Tizen 2.2.1
186 // When locktype is None, lockscreen app doesn't interfere with unlocking process.
187 // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None.
188 // So, to unlock user data when lock type is None, key-manager always try to unlock user data with null password.
189 // Even if the result is fail, it will be ignored.
190 Password nullPassword("");
191 m_logic->unlockUserKey(cred.clientUid, nullPassword);
193 LogDebug("Process storage. Command: " << command);
195 switch(static_cast<LogicCommand>(command)) {
196 case LogicCommand::SAVE:
199 PolicySerializable policy;
200 buffer.Deserialize(tmpDataType, name, label, rawData, policy);
203 return disallowed(command, msgID, static_cast<int>(DataType(tmpDataType)));
205 return m_logic->saveData(
211 DataType(tmpDataType),
214 case LogicCommand::SAVE_PKCS12:
217 PKCS12Serializable pkcs;
218 PolicySerializable keyPolicy, certPolicy;
219 buffer.Deserialize(name, label, pkcs, keyPolicy, certPolicy);
222 return disallowed(command, msgID);
224 return m_logic->savePKCS12(
233 case LogicCommand::REMOVE:
235 buffer.Deserialize(name, label);
238 return disallowed(command, msgID);
240 return m_logic->removeData(
246 case LogicCommand::GET:
249 buffer.Deserialize(tmpDataType, name, label, password);
252 return disallowed(command,
254 static_cast<int>(DataType(tmpDataType)),
257 return m_logic->getData(
260 DataType(tmpDataType),
265 case LogicCommand::GET_PKCS12:
269 buffer.Deserialize(name,
275 return disallowed(command, msgID, PKCS12Serializable());
277 return m_logic->getPKCS12(
285 case LogicCommand::GET_LIST:
287 buffer.Deserialize(tmpDataType);
290 return disallowed(command,
292 static_cast<int>(DataType(tmpDataType)),
295 return m_logic->getDataList(
298 DataType(tmpDataType));
300 case LogicCommand::CREATE_KEY_AES:
305 PolicySerializable policyKey;
306 buffer.Deserialize(size,
312 return disallowed(command, msgID);
314 return m_logic->createKeyAES(
322 case LogicCommand::CREATE_KEY_PAIR:
324 CryptoAlgorithmSerializable keyGenAlgorithm;
326 Label privateKeyLabel;
328 Label publicKeyLabel;
329 PolicySerializable policyPrivateKey;
330 PolicySerializable policyPublicKey;
331 buffer.Deserialize(keyGenAlgorithm,
340 return disallowed(command, msgID);
342 return m_logic->createKeyPair(
353 case LogicCommand::GET_CHAIN_CERT:
355 RawBuffer certificate;
356 RawBufferVector untrustedVector;
357 RawBufferVector trustedVector;
358 bool systemCerts = false;
359 buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts);
362 return disallowed(command, msgID, RawBufferVector());
364 return m_logic->getCertificateChain(
372 case LogicCommand::GET_CHAIN_ALIAS:
374 RawBuffer certificate;
375 LabelNameVector untrustedVector;
376 LabelNameVector trustedVector;
377 bool systemCerts = false;
378 buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts);
381 return disallowed(command, msgID, LabelNameVector());
383 return m_logic->getCertificateChain(
391 case LogicCommand::CREATE_SIGNATURE:
393 Password password; // password for private_key
395 int padding = 0, hash = 0;
396 buffer.Deserialize(name, label, password, message, hash, padding);
399 return disallowed(command, msgID, RawBuffer());
401 return m_logic->createSignature(
406 password, // password for private_key
408 static_cast<HashAlgorithm>(hash),
409 static_cast<RSAPaddingAlgorithm>(padding));
411 case LogicCommand::VERIFY_SIGNATURE:
413 Password password; // password for public_key (optional)
416 //HashAlgorithm hash;
417 //RSAPaddingAlgorithm padding;
418 int padding = 0, hash = 0;
419 buffer.Deserialize(name,
428 return disallowed(command, msgID);
430 return m_logic->verifySignature(
435 password, // password for public_key (optional)
438 static_cast<const HashAlgorithm>(hash),
439 static_cast<const RSAPaddingAlgorithm>(padding));
441 case LogicCommand::SET_PERMISSION:
443 PermissionMask permissionMask = 0;
444 buffer.Deserialize(name, label, accessorLabel, permissionMask);
447 return disallowed(command, msgID);
449 return m_logic->setPermission(
459 Throw(Exception::BrokenProtocol);
463 void CKMService::ProcessMessage(MsgKeyRequest msg)
465 Crypto::GKeyShPtr key;
466 int ret = m_logic->getKeyForService(msg.cred,
471 MsgKeyResponse kResp(msg.id, key, ret);
473 if (!m_commMgr->SendMessage(kResp))
474 LogError("No listener found"); // can't do much more
476 LogError("Uncaught exception in SendMessage. Check listeners.");