Add access API to the control service.
[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     int cc_mode_status;
111     uid_t user;
112     ControlCommand cc;
113     Password newPass, oldPass;
114     std::string smackLabel;
115
116     Deserialization::Deserialize(buffer, command);
117
118     LogDebug("Process control. Command: " << command);
119
120     cc = static_cast<ControlCommand>(command);
121
122     switch(cc) {
123     case ControlCommand::UNLOCK_USER_KEY:
124         Deserialization::Deserialize(buffer, user);
125         Deserialization::Deserialize(buffer, newPass);
126         return m_logic->unlockUserKey(user, newPass);
127     case ControlCommand::LOCK_USER_KEY:
128         Deserialization::Deserialize(buffer, user);
129         return m_logic->lockUserKey(user);
130     case ControlCommand::REMOVE_USER_DATA:
131         Deserialization::Deserialize(buffer, user);
132         return m_logic->removeUserData(user);
133     case ControlCommand::CHANGE_USER_PASSWORD:
134         Deserialization::Deserialize(buffer, user);
135         Deserialization::Deserialize(buffer, oldPass);
136         Deserialization::Deserialize(buffer, newPass);
137         return m_logic->changeUserPassword(user, oldPass, newPass);
138     case ControlCommand::RESET_USER_PASSWORD:
139         Deserialization::Deserialize(buffer, user);
140         Deserialization::Deserialize(buffer, newPass);
141         return m_logic->resetUserPassword(user, newPass);
142     case ControlCommand::REMOVE_APP_DATA:
143         Deserialization::Deserialize(buffer, smackLabel);
144         return m_logic->removeApplicationData(smackLabel);
145     case ControlCommand::SET_CC_MODE:
146         Deserialization::Deserialize(buffer, cc_mode_status);
147         return m_logic->setCCModeStatus(static_cast<CCModeState>(cc_mode_status));
148     case ControlCommand::ALLOW_ACCESS:
149     {
150         std::string owner;
151         std::string item_alias;
152         std::string accessor_label;
153         int req_rights;
154
155         Deserialization::Deserialize(buffer, user);
156         Deserialization::Deserialize(buffer, owner);
157         Deserialization::Deserialize(buffer, item_alias);
158         Deserialization::Deserialize(buffer, accessor_label);
159         Deserialization::Deserialize(buffer, req_rights);
160         Credentials cred =
161             {
162                 user,
163                 owner
164             };
165         return m_logic->allowAccess(
166             cred,
167             command,
168             0, // dummy
169             item_alias,
170             accessor_label,
171             static_cast<AccessRight>(req_rights));
172     }
173     case ControlCommand::DENY_ACCESS:
174     {
175         std::string owner;
176         std::string item_alias;
177         std::string accessor_label;
178
179         Deserialization::Deserialize(buffer, user);
180         Deserialization::Deserialize(buffer, owner);
181         Deserialization::Deserialize(buffer, item_alias);
182         Deserialization::Deserialize(buffer, accessor_label);
183         Credentials cred =
184             {
185                 user,
186                 owner
187             };
188         return m_logic->denyAccess(
189             cred,
190             command,
191             0, // dummy
192             item_alias,
193             accessor_label);
194     }
195     default:
196         Throw(Exception::BrokenProtocol);
197     }
198 }
199
200 RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer)
201 {
202     int command;
203     int msgID;
204     int tmpDataType;
205     Alias alias;
206     std::string user;
207
208     Deserialization::Deserialize(buffer, command);
209     Deserialization::Deserialize(buffer, msgID);
210
211     // This is a workaround solution for locktype=None in Tizen 2.2.1
212     // When locktype is None, lockscreen app doesn't interfere with unlocking process.
213     // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None.
214     // So, to unlock user data when lock type is None, key-manager always try to unlock user data with null password.
215     // Even if the result is fail, it will be ignored.
216     Password nullPassword("");
217     m_logic->unlockUserKey(cred.uid, nullPassword);
218
219     LogDebug("Process storage. Command: " << command);
220
221     switch(static_cast<LogicCommand>(command)) {
222         case LogicCommand::SAVE:
223         {
224             RawBuffer rawData;
225             PolicySerializable policy;
226             Deserialization::Deserialize(buffer, tmpDataType);
227             Deserialization::Deserialize(buffer, alias);
228             Deserialization::Deserialize(buffer, rawData);
229             Deserialization::Deserialize(buffer, policy);
230             return m_logic->saveData(
231                 cred,
232                 msgID,
233                 static_cast<DBDataType>(tmpDataType),
234                 alias,
235                 rawData,
236                 policy);
237         }
238         case LogicCommand::REMOVE:
239         {
240             Deserialization::Deserialize(buffer, tmpDataType);
241             Deserialization::Deserialize(buffer, alias);
242             return m_logic->removeData(
243                 cred,
244                 msgID,
245                 static_cast<DBDataType>(tmpDataType),
246                 alias);
247         }
248         case LogicCommand::GET:
249         {
250             Password password;
251             Deserialization::Deserialize(buffer, tmpDataType);
252             Deserialization::Deserialize(buffer, alias);
253             Deserialization::Deserialize(buffer, password);
254             return m_logic->getData(
255                 cred,
256                 msgID,
257                 static_cast<DBDataType>(tmpDataType),
258                 alias,
259                 password);
260         }
261         case LogicCommand::GET_LIST:
262         {
263             Deserialization::Deserialize(buffer, tmpDataType);
264             return m_logic->getDataList(
265                 cred,
266                 msgID,
267                 static_cast<DBDataType>(tmpDataType));
268         }
269         case LogicCommand::CREATE_KEY_PAIR_RSA:
270         case LogicCommand::CREATE_KEY_PAIR_DSA:
271         case LogicCommand::CREATE_KEY_PAIR_ECDSA:
272         {
273             int additional_param;
274             Alias privateKeyAlias;
275             Alias publicKeyAlias;
276             PolicySerializable policyPrivateKey;
277             PolicySerializable policyPublicKey;
278             Deserialization::Deserialize(buffer, additional_param);
279             Deserialization::Deserialize(buffer, policyPrivateKey);
280             Deserialization::Deserialize(buffer, policyPublicKey);
281             Deserialization::Deserialize(buffer, privateKeyAlias);
282             Deserialization::Deserialize(buffer, publicKeyAlias);
283             return m_logic->createKeyPair(
284                 cred,
285                 static_cast<LogicCommand>(command),
286                 msgID,
287                 additional_param,
288                 privateKeyAlias,
289                 publicKeyAlias,
290                 policyPrivateKey,
291                 policyPublicKey);
292         }
293         case LogicCommand::GET_CHAIN_CERT:
294         {
295             RawBuffer certificate;
296             RawBufferVector rawBufferVector;
297             Deserialization::Deserialize(buffer, certificate);
298             Deserialization::Deserialize(buffer, rawBufferVector);
299             return m_logic->getCertificateChain(
300                 cred,
301                 msgID,
302                 certificate,
303                 rawBufferVector);
304         }
305         case LogicCommand::GET_CHAIN_ALIAS:
306         {
307             RawBuffer certificate;
308             AliasVector aliasVector;
309             Deserialization::Deserialize(buffer, certificate);
310             Deserialization::Deserialize(buffer, aliasVector);
311             return m_logic->getCertificateChain(
312                 cred,
313                 msgID,
314                 certificate,
315                 aliasVector);
316         }
317         case LogicCommand::CREATE_SIGNATURE:
318         {
319             Alias privateKeyAlias;
320             Password password;        // password for private_key
321             RawBuffer message;
322             int padding, hash;
323             Deserialization::Deserialize(buffer, privateKeyAlias);
324             Deserialization::Deserialize(buffer, password);
325             Deserialization::Deserialize(buffer, message);
326             Deserialization::Deserialize(buffer, hash);
327             Deserialization::Deserialize(buffer, padding);
328
329             return m_logic->createSignature(
330                   cred,
331                   msgID,
332                   privateKeyAlias,
333                   password,           // password for private_key
334                   message,
335                   static_cast<HashAlgorithm>(hash),
336                   static_cast<RSAPaddingAlgorithm>(padding));
337         }
338         case LogicCommand::VERIFY_SIGNATURE:
339         {
340             Alias publicKeyOrCertAlias;
341             Password password;           // password for public_key (optional)
342             RawBuffer message;
343             RawBuffer signature;
344             //HashAlgorithm hash;
345             //RSAPaddingAlgorithm padding;
346             int padding, hash;
347             Deserialization::Deserialize(buffer, publicKeyOrCertAlias);
348             Deserialization::Deserialize(buffer, password);
349             Deserialization::Deserialize(buffer, message);
350             Deserialization::Deserialize(buffer, signature);
351             Deserialization::Deserialize(buffer, hash);
352             Deserialization::Deserialize(buffer, padding);
353             return m_logic->verifySignature(
354                 cred,
355                 msgID,
356                 publicKeyOrCertAlias,
357                 password,           // password for public_key (optional)
358                 message,
359                 signature,
360                 static_cast<const HashAlgorithm>(hash),
361                 static_cast<const RSAPaddingAlgorithm>(padding));
362         }
363         case LogicCommand::ALLOW_ACCESS:
364         {
365             Alias item_alias;
366             std::string accessor_label;
367             int req_rights;
368             Deserialization::Deserialize(buffer, item_alias);
369             Deserialization::Deserialize(buffer, accessor_label);
370             Deserialization::Deserialize(buffer, req_rights);
371             return m_logic->allowAccess(
372                 cred,
373                 command,
374                 msgID,
375                 item_alias,
376                 accessor_label,
377                 static_cast<AccessRight>(req_rights));
378         }
379         case LogicCommand::DENY_ACCESS:
380         {
381             Alias item_alias;
382             std::string accessor_label;
383             Deserialization::Deserialize(buffer, item_alias);
384             Deserialization::Deserialize(buffer, accessor_label);
385             return m_logic->denyAccess(
386                 cred,
387                 command,
388                 msgID,
389                 item_alias,
390                 accessor_label);
391         }
392         default:
393             Throw(Exception::BrokenProtocol);
394     }
395 }
396
397
398 void CKMService::close(const CloseEvent &event) {
399     LogDebug("Close event");
400     m_connectionInfoMap.erase(event.connectionID.counter);
401 }
402
403 } // namespace CKM
404