CC mode logic updated
[platform/core/security/key-manager.git] / src / manager / service / ckm-service.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  *
16  *
17  * @file        ckm-service.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version     1.0
20  * @brief       CKM service implementation.
21  */
22 #include <service-thread.h>
23 #include <generic-socket-manager.h>
24 #include <connection-info.h>
25 #include <message-buffer.h>
26 #include <protocols.h>
27
28 #include <dpl/serialization.h>
29 #include <dpl/log/log.h>
30
31 #include <ckm-service.h>
32 #include <ckm-logic.h>
33
34 namespace {
35 const CKM::InterfaceID SOCKET_ID_CONTROL = 0;
36 const CKM::InterfaceID SOCKET_ID_STORAGE = 1;
37 } // namespace anonymous
38
39 namespace CKM {
40
41 CKMService::CKMService()
42   : m_logic(new CKMLogic)
43 {}
44
45 CKMService::~CKMService() {
46     delete m_logic;
47 }
48
49 GenericSocketService::ServiceDescriptionVector CKMService::GetServiceDescription()
50 {
51     return ServiceDescriptionVector {
52         {SERVICE_SOCKET_CKM_CONTROL, "key-manager::api-control", SOCKET_ID_CONTROL},
53         {SERVICE_SOCKET_CKM_STORAGE, "key-manager::api-storage", SOCKET_ID_STORAGE}
54     };
55 }
56
57 void CKMService::accept(const AcceptEvent &event) {
58     LogDebug("Accept event");
59     auto &info = m_connectionInfoMap[event.connectionID.counter];
60     info.interfaceID = event.interfaceID;
61     info.credentials = event.credentials;
62 }
63
64 void CKMService::write(const WriteEvent &event) {
65     LogDebug("Write event (" << event.size << " bytes)");
66 }
67
68 void CKMService::process(const ReadEvent &event) {
69     LogDebug("Read event");
70     auto &info = m_connectionInfoMap[event.connectionID.counter];
71     info.buffer.Push(event.rawBuffer);
72     while(processOne(event.connectionID, info));
73 }
74
75 bool CKMService::processOne(
76     const ConnectionID &conn,
77     ConnectionInfo &info)
78 {
79     LogDebug ("process One");
80     RawBuffer response;
81
82     Try {
83         if (!info.buffer.Ready())
84             return false;
85
86         if (info.interfaceID == SOCKET_ID_CONTROL)
87             response = processControl(info.buffer);
88         else
89             response = processStorage(info.credentials, info.buffer);
90
91         m_serviceManager->Write(conn, response);
92
93         return true;
94     } Catch (MessageBuffer::Exception::Base) {
95         LogError("Broken protocol. Closing socket.");
96     } Catch (Exception::BrokenProtocol) {
97         LogError("Broken protocol. Closing socket.");
98     } catch (const std::string &e) {
99         LogError("String exception(" << e << "). Closing socket");
100     } catch (...) {
101         LogError("Unknown exception. Closing socket.");
102     }
103
104     m_serviceManager->Close(conn);
105     return false;
106 }
107
108 RawBuffer CKMService::processControl(MessageBuffer &buffer) {
109     int command;
110     uid_t user;
111     ControlCommand cc;
112     Password newPass, oldPass;
113     std::string smackLabel;
114
115     buffer.Deserialize(command);
116
117     LogDebug("Process control. Command: " << command);
118
119     cc = static_cast<ControlCommand>(command);
120
121     switch(cc) {
122     case ControlCommand::UNLOCK_USER_KEY:
123         buffer.Deserialize(user, newPass);
124         return m_logic->unlockUserKey(user, newPass);
125     case ControlCommand::LOCK_USER_KEY:
126         buffer.Deserialize(user);
127         return m_logic->lockUserKey(user);
128     case ControlCommand::REMOVE_USER_DATA:
129         buffer.Deserialize(user);
130         return m_logic->removeUserData(user);
131     case ControlCommand::CHANGE_USER_PASSWORD:
132         buffer.Deserialize(user, oldPass, newPass);
133         return m_logic->changeUserPassword(user, oldPass, newPass);
134     case ControlCommand::RESET_USER_PASSWORD:
135         buffer.Deserialize(user, newPass);
136         return m_logic->resetUserPassword(user, newPass);
137     case ControlCommand::REMOVE_APP_DATA:
138         buffer.Deserialize(smackLabel);
139         return m_logic->removeApplicationData(smackLabel);
140     case ControlCommand::UPDATE_CC_MODE:
141         return m_logic->updateCCMode();
142     case ControlCommand::ALLOW_ACCESS:
143     {
144         std::string owner;
145         std::string item_alias;
146         std::string accessor_label;
147         int req_rights;
148
149         buffer.Deserialize(user, owner, item_alias, accessor_label, req_rights);
150         Credentials cred =
151             {
152                 user,
153                 owner
154             };
155         return m_logic->allowAccess(
156             cred,
157             command,
158             0, // dummy
159             item_alias,
160             accessor_label,
161             static_cast<AccessRight>(req_rights));
162     }
163     case ControlCommand::DENY_ACCESS:
164     {
165         std::string owner;
166         std::string item_alias;
167         std::string accessor_label;
168
169         buffer.Deserialize(user, owner, item_alias, accessor_label);
170         Credentials cred =
171             {
172                 user,
173                 owner
174             };
175         return m_logic->denyAccess(
176             cred,
177             command,
178             0, // dummy
179             item_alias,
180             accessor_label);
181     }
182     default:
183         Throw(Exception::BrokenProtocol);
184     }
185 }
186
187 RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
188 {
189     int command;
190     int msgID;
191     int tmpDataType;
192     Alias alias;
193     std::string user;
194
195     buffer.Deserialize(command);
196     buffer.Deserialize(msgID);
197
198     // This is a workaround solution for locktype=None in Tizen 2.2.1
199     // When locktype is None, lockscreen app doesn't interfere with unlocking process.
200     // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None.
201     // So, to unlock user data when lock type is None, key-manager always try to unlock user data with null password.
202     // Even if the result is fail, it will be ignored.
203     Password nullPassword("");
204     m_logic->unlockUserKey(cred.uid, nullPassword);
205
206     LogDebug("Process storage. Command: " << command);
207
208     switch(static_cast<LogicCommand>(command)) {
209         case LogicCommand::SAVE:
210         {
211             RawBuffer rawData;
212             PolicySerializable policy;
213             buffer.Deserialize(tmpDataType, alias, rawData, policy);
214             return m_logic->saveData(
215                 cred,
216                 msgID,
217                 static_cast<DBDataType>(tmpDataType),
218                 alias,
219                 rawData,
220                 policy);
221         }
222         case LogicCommand::REMOVE:
223         {
224             buffer.Deserialize(tmpDataType, alias);
225             return m_logic->removeData(
226                 cred,
227                 msgID,
228                 static_cast<DBDataType>(tmpDataType),
229                 alias);
230         }
231         case LogicCommand::GET:
232         {
233             Password password;
234             buffer.Deserialize(tmpDataType, alias, password);
235             return m_logic->getData(
236                 cred,
237                 msgID,
238                 static_cast<DBDataType>(tmpDataType),
239                 alias,
240                 password);
241         }
242         case LogicCommand::GET_LIST:
243         {
244             buffer.Deserialize(tmpDataType);
245             return m_logic->getDataList(
246                 cred,
247                 msgID,
248                 static_cast<DBDataType>(tmpDataType));
249         }
250         case LogicCommand::CREATE_KEY_PAIR_RSA:
251         case LogicCommand::CREATE_KEY_PAIR_DSA:
252         case LogicCommand::CREATE_KEY_PAIR_ECDSA:
253         {
254             int additional_param;
255             Alias privateKeyAlias;
256             Alias publicKeyAlias;
257             PolicySerializable policyPrivateKey;
258             PolicySerializable policyPublicKey;
259             buffer.Deserialize(additional_param,
260                                policyPrivateKey,
261                                policyPublicKey,
262                                privateKeyAlias,
263                                publicKeyAlias);
264             return m_logic->createKeyPair(
265                 cred,
266                 static_cast<LogicCommand>(command),
267                 msgID,
268                 additional_param,
269                 privateKeyAlias,
270                 publicKeyAlias,
271                 policyPrivateKey,
272                 policyPublicKey);
273         }
274         case LogicCommand::GET_CHAIN_CERT:
275         {
276             RawBuffer certificate;
277             RawBufferVector rawBufferVector;
278             buffer.Deserialize(certificate, rawBufferVector);
279             return m_logic->getCertificateChain(
280                 cred,
281                 msgID,
282                 certificate,
283                 rawBufferVector);
284         }
285         case LogicCommand::GET_CHAIN_ALIAS:
286         {
287             RawBuffer certificate;
288             AliasVector aliasVector;
289             buffer.Deserialize(certificate, aliasVector);
290             return m_logic->getCertificateChain(
291                 cred,
292                 msgID,
293                 certificate,
294                 aliasVector);
295         }
296         case LogicCommand::CREATE_SIGNATURE:
297         {
298             Alias privateKeyAlias;
299             Password password;        // password for private_key
300             RawBuffer message;
301             int padding, hash;
302             buffer.Deserialize(privateKeyAlias, password, message, hash, padding);
303             return m_logic->createSignature(
304                   cred,
305                   msgID,
306                   privateKeyAlias,
307                   password,           // password for private_key
308                   message,
309                   static_cast<HashAlgorithm>(hash),
310                   static_cast<RSAPaddingAlgorithm>(padding));
311         }
312         case LogicCommand::VERIFY_SIGNATURE:
313         {
314             Alias publicKeyOrCertAlias;
315             Password password;           // password for public_key (optional)
316             RawBuffer message;
317             RawBuffer signature;
318             //HashAlgorithm hash;
319             //RSAPaddingAlgorithm padding;
320             int padding, hash;
321             buffer.Deserialize(publicKeyOrCertAlias,
322                                password,
323                                message,
324                                signature,
325                                hash,
326                                padding);
327             return m_logic->verifySignature(
328                 cred,
329                 msgID,
330                 publicKeyOrCertAlias,
331                 password,           // password for public_key (optional)
332                 message,
333                 signature,
334                 static_cast<const HashAlgorithm>(hash),
335                 static_cast<const RSAPaddingAlgorithm>(padding));
336         }
337         case LogicCommand::ALLOW_ACCESS:
338         {
339             Alias item_alias;
340             std::string accessor_label;
341             int req_rights;
342             buffer.Deserialize(item_alias, accessor_label, req_rights);
343             return m_logic->allowAccess(
344                 cred,
345                 command,
346                 msgID,
347                 item_alias,
348                 accessor_label,
349                 static_cast<AccessRight>(req_rights));
350         }
351         case LogicCommand::DENY_ACCESS:
352         {
353             Alias item_alias;
354             std::string accessor_label;
355             buffer.Deserialize(item_alias, accessor_label);
356             return m_logic->denyAccess(
357                 cred,
358                 command,
359                 msgID,
360                 item_alias,
361                 accessor_label);
362         }
363         default:
364             Throw(Exception::BrokenProtocol);
365     }
366 }
367
368
369 void CKMService::close(const CloseEvent &event) {
370     LogDebug("Close event");
371     m_connectionInfoMap.erase(event.connectionID.counter);
372 }
373
374 } // namespace CKM
375