Change code formatting in import/export wrapped key
[platform/core/security/key-manager.git] / src / manager / service / ckm-service.cpp
1 /*
2  *  Copyright (c) 2014 - 2020 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
23 #include <protocols.h>
24
25 #include <dpl/serialization.h>
26 #include <dpl/log/log.h>
27
28 #include <ckm-service.h>
29 #include <ckm-logic.h>
30 #include <initial-value-loader.h>
31
32 namespace {
33 const CKM::InterfaceID SOCKET_ID_CONTROL = 0;
34 const CKM::InterfaceID SOCKET_ID_STORAGE = 1;
35 } // namespace anonymous
36
37 namespace CKM {
38
39 CKMService::CKMService() :
40         m_logic(new CKMLogic)
41 {
42         InitialValues::LoadFiles(*m_logic);
43 }
44
45 CKMService::~CKMService()
46 {
47         delete m_logic;
48 }
49
50 void CKMService::Start()
51 {
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();
56
57         Create();
58 }
59
60 void CKMService::Stop()
61 {
62         Join();
63 }
64
65 GenericSocketService::ServiceDescriptionVector
66 CKMService::GetServiceDescription()
67 {
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}
72         };
73 }
74
75 void CKMService::SetCommManager(CommMgr *manager)
76 {
77         ThreadService::SetCommManager(manager);
78         Register(*manager);
79 }
80
81 bool CKMService::ProcessOne(
82         const ConnectionID &conn,
83         ConnectionInfo &info,
84         bool allowed)
85 {
86         LogDebug("process One");
87         RawBuffer response;
88
89         try {
90                 if (!info.buffer.Ready())
91                         return false;
92
93                 if (info.interfaceID == SOCKET_ID_CONTROL)
94                         response = ProcessControl(info.buffer, allowed);
95                 else
96                         response = ProcessStorage(info.credentials, info.buffer);
97
98                 m_serviceManager->Write(conn, response);
99
100                 return true;
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());
109         } catch (...) {
110                 LogError("Unknown exception. Closing socket.");
111         }
112
113         m_serviceManager->Close(conn);
114         return false;
115 }
116
117 RawBuffer CKMService::ProcessControl(MessageBuffer &buffer, bool allowed)
118 {
119         int command = 0;
120         uid_t user = 0;
121         ControlCommand cc;
122         Password newPass, oldPass;
123         ClientId explicitOwner;
124
125         buffer.Deserialize(command);
126
127         LogDebug("Process control. Command: " << command);
128
129         std::function<RawBuffer(void)> logicFunc;
130
131         cc = static_cast<ControlCommand>(command);
132
133         switch (cc) {
134         case ControlCommand::UNLOCK_USER_KEY:
135                 buffer.Deserialize(user, newPass);
136                 logicFunc = [&]() {
137                         return m_logic->unlockUserKey(user, newPass);
138                 };
139                 break;
140
141         case ControlCommand::LOCK_USER_KEY:
142                 buffer.Deserialize(user);
143                 logicFunc = [&]() {
144                         return m_logic->lockUserKey(user);
145                 };
146                 break;
147
148         case ControlCommand::REMOVE_USER_DATA:
149                 buffer.Deserialize(user);
150                 logicFunc = [&]() {
151                         return m_logic->removeUserData(user);
152                 };
153                 break;
154
155         case ControlCommand::CHANGE_USER_PASSWORD:
156                 buffer.Deserialize(user, oldPass, newPass);
157                 logicFunc = [&]() {
158                         return m_logic->changeUserPassword(user, oldPass, newPass);
159                 };
160                 break;
161
162         case ControlCommand::RESET_USER_PASSWORD:
163                 buffer.Deserialize(user, newPass);
164                 logicFunc = [&]() {
165                         return m_logic->resetUserPassword(user, newPass);
166                 };
167                 break;
168
169         case ControlCommand::REMOVE_APP_DATA:
170                 buffer.Deserialize(explicitOwner);
171                 logicFunc = [&]() {
172                         return m_logic->removeApplicationData(explicitOwner);
173                 };
174                 break;
175
176         case ControlCommand::UPDATE_CC_MODE:
177                 logicFunc = [&]() {
178                         return m_logic->updateCCMode();
179                 };
180                 break;
181
182         case ControlCommand::SET_PERMISSION: {
183                 Name name;
184                 ClientId accessor;
185                 PermissionMask permissionMask = 0;
186
187                 buffer.Deserialize(user, name, explicitOwner, accessor, permissionMask);
188
189                 Credentials cred(user, explicitOwner);
190                 logicFunc = [&, name, explicitOwner, accessor, permissionMask, cred]() {
191                         return m_logic->setPermission(
192                                            cred,
193                                            0, // dummy
194                                            name,
195                                            cred.effectiveOwner(explicitOwner),
196                                            accessor,
197                                            permissionMask);
198                 };
199                 break;
200         }
201
202         default:
203                 Throw(Exception::BrokenProtocol);
204         }
205
206         if (!allowed) {
207                 LogError("Access denied!");
208                 return SerializeMessage(CKM_API_ERROR_ACCESS_DENIED);
209         }
210
211         return logicFunc();
212 }
213
214 RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer)
215 {
216         int command = 0;
217         int msgId = 0;
218         DataType tmpDataType;
219         Name name;
220         ClientId explicitOwner, accessor;
221
222         buffer.Deserialize(command);
223         buffer.Deserialize(msgId);
224
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);
232
233         LogDebug("Process storage. Command: " << command);
234
235         switch (static_cast<LogicCommand>(command)) {
236         case LogicCommand::SAVE: {
237                 RawBuffer rawData;
238                 PolicySerializable policy;
239                 buffer.Deserialize(tmpDataType, name, explicitOwner, rawData, policy);
240                 return m_logic->saveData(
241                                    cred,
242                                    msgId,
243                                    name,
244                                    cred.effectiveOwner(explicitOwner),
245                                    Crypto::Data(tmpDataType, std::move(rawData)),
246                                    policy);
247         }
248
249         case LogicCommand::SAVE_PKCS12: {
250                 RawBuffer rawData;
251                 PKCS12Serializable pkcs;
252                 PolicySerializable keyPolicy, certPolicy;
253                 buffer.Deserialize(name, explicitOwner, pkcs, keyPolicy, certPolicy);
254                 return m_logic->savePKCS12(
255                                    cred,
256                                    msgId,
257                                    name,
258                                    cred.effectiveOwner(explicitOwner),
259                                    pkcs,
260                                    keyPolicy,
261                                    certPolicy);
262         }
263
264         case LogicCommand::REMOVE: {
265                 buffer.Deserialize(name, explicitOwner);
266                 return m_logic->removeData(
267                                    cred,
268                                    msgId,
269                                    name,
270                                    cred.effectiveOwner(explicitOwner));
271         }
272
273         case LogicCommand::GET: {
274                 Password password;
275                 buffer.Deserialize(tmpDataType, name, explicitOwner, password);
276                 return m_logic->getData(
277                                    cred,
278                                    msgId,
279                                    tmpDataType,
280                                    name,
281                                    cred.effectiveOwner(explicitOwner),
282                                    password);
283         }
284
285         case LogicCommand::GET_PKCS12: {
286                 Password passKey;
287                 Password passCert;
288                 buffer.Deserialize(name, explicitOwner, passKey, passCert);
289                 return m_logic->getPKCS12(
290                                    cred,
291                                    msgId,
292                                    name,
293                                    cred.effectiveOwner(explicitOwner),
294                                    passKey,
295                                    passCert);
296         }
297
298         case LogicCommand::GET_PROTECTION_STATUS: {
299                 buffer.Deserialize(tmpDataType, name, explicitOwner);
300                 return m_logic->getDataProtectionStatus(
301                                         cred,
302                                         msgId,
303                                         tmpDataType,
304                                         name,
305                                         cred.effectiveOwner(explicitOwner));
306         }
307
308         case LogicCommand::GET_LIST: {
309                 buffer.Deserialize(tmpDataType);
310                 return m_logic->getDataList(
311                                    cred,
312                                    msgId,
313                                    tmpDataType);
314         }
315
316         case LogicCommand::CREATE_KEY_AES: {
317                 int size = 0;
318                 PolicySerializable policyKey;
319                 buffer.Deserialize(size, policyKey, name, explicitOwner);
320                 return m_logic->createKeyAES(
321                                    cred,
322                                    msgId,
323                                    size,
324                                    name,
325                                    cred.effectiveOwner(explicitOwner),
326                                    policyKey);
327         }
328
329         case LogicCommand::CREATE_KEY_PAIR: {
330                 CryptoAlgorithmSerializable keyGenAlgorithm;
331                 Name privateKeyName;
332                 ClientId explicitOwnerPrivate;
333                 Name publicKeyName;
334                 ClientId explicitOwnerPublic;
335                 PolicySerializable policyPrivateKey;
336                 PolicySerializable policyPublicKey;
337                 buffer.Deserialize(keyGenAlgorithm,
338                                                    policyPrivateKey,
339                                                    policyPublicKey,
340                                                    privateKeyName,
341                                                    explicitOwnerPrivate,
342                                                    publicKeyName,
343                                                    explicitOwnerPublic);
344                 return m_logic->createKeyPair(
345                                    cred,
346                                    msgId,
347                                    keyGenAlgorithm,
348                                    privateKeyName,
349                                    cred.effectiveOwner(explicitOwnerPrivate),
350                                    publicKeyName,
351                                    cred.effectiveOwner(explicitOwnerPublic),
352                                    policyPrivateKey,
353                                    policyPublicKey);
354         }
355
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(
363                                    cred,
364                                    msgId,
365                                    certificate,
366                                    untrustedVector,
367                                    trustedVector,
368                                    systemCerts);
369         }
370
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(
378                                    cred,
379                                    msgId,
380                                    certificate,
381                                    untrustedVector,
382                                    trustedVector,
383                                    systemCerts);
384         }
385
386         case LogicCommand::CREATE_SIGNATURE: {
387                 Password password;        // password for private_key
388                 RawBuffer message;
389
390                 CryptoAlgorithmSerializable cAlgorithm;
391                 buffer.Deserialize(name, explicitOwner, password, message, cAlgorithm);
392
393                 return m_logic->createSignature(
394                                    cred,
395                                    msgId,
396                                    name,
397                                    cred.effectiveOwner(explicitOwner),
398                                    password,           // password for private_key
399                                    message,
400                                    cAlgorithm);
401         }
402
403         case LogicCommand::VERIFY_SIGNATURE: {
404                 Password password;           // password for public_key (optional)
405                 RawBuffer message;
406                 RawBuffer signature;
407                 CryptoAlgorithmSerializable cAlg;
408
409                 buffer.Deserialize(name, explicitOwner, password, message, signature, cAlg);
410
411                 return m_logic->verifySignature(
412                                    cred,
413                                    msgId,
414                                    name,
415                                    cred.effectiveOwner(explicitOwner),
416                                    password,           // password for public_key (optional)
417                                    message,
418                                    signature,
419                                    cAlg);
420         }
421
422         case LogicCommand::SET_PERMISSION: {
423                 PermissionMask permissionMask = 0;
424                 buffer.Deserialize(name, explicitOwner, accessor, permissionMask);
425                 return m_logic->setPermission(
426                                    cred,
427                                    msgId,
428                                    name,
429                                    cred.effectiveOwner(explicitOwner),
430                                    accessor,
431                                    permissionMask);
432         }
433
434         case LogicCommand::DERIVE: {
435                 CryptoAlgorithmSerializable keyDerivationAlgorithm;
436                 Name secretName;
437                 ClientId secretExplicitOwner;
438                 Password secretPassword;
439                 Name newKeyName;
440                 ClientId newKeyExplicitOwner;
441                 PolicySerializable newKeyPolicy;
442                 buffer.Deserialize(keyDerivationAlgorithm,
443                                                    secretName,
444                                                    secretExplicitOwner,
445                                                    secretPassword,
446                                                    newKeyName,
447                                                    newKeyExplicitOwner,
448                                                    newKeyPolicy);
449                 return m_logic->deriveKey(
450                         cred,
451                         msgId,
452                         keyDerivationAlgorithm,
453                         secretName,
454                         cred.effectiveOwner(secretExplicitOwner),
455                         secretPassword,
456                         newKeyName,
457                         cred.effectiveOwner(newKeyExplicitOwner),
458                         newKeyPolicy);
459         }
460
461         case LogicCommand::IMPORT_WRAPPED_KEY: {
462                 CryptoAlgorithmSerializable params;
463                 Name wrappingKeyName;
464                 ClientId wrappingKeyOwner;
465                 Password wrappingKeyPassword;
466                 Name keyName;
467                 RawBuffer wrappedKey;
468                 CKM::DataType keyType;
469                 PolicySerializable policy;
470
471                 buffer.Deserialize(params,
472                                                    wrappingKeyName,
473                                                    wrappingKeyOwner,
474                                                    wrappingKeyPassword,
475                                                    keyName,
476                                                    explicitOwner,
477                                                    wrappedKey,
478                                                    keyType,
479                                                    policy);
480
481                 return m_logic->importWrappedKey(
482                                         cred,
483                                         msgId,
484                                         params,
485                                         wrappingKeyName,
486                                         cred.effectiveOwner(wrappingKeyOwner),
487                                         wrappingKeyPassword,
488                                         keyName,
489                                         cred.effectiveOwner(explicitOwner),
490                                         wrappedKey,
491                                         keyType,
492                                         policy);
493         }
494
495         case LogicCommand::EXPORT_WRAPPED_KEY: {
496                 CryptoAlgorithmSerializable params;
497                 Name wrappingKeyName;
498                 ClientId wrappingKeyOwner;
499                 Password wrappingKeyPassword;
500                 Name wrappedKeyName;
501                 ClientId wrappedKeyOwner;
502                 Password wrappedKeyPassword;
503
504                 buffer.Deserialize(params,
505                                                    wrappingKeyName,
506                                                    wrappingKeyOwner,
507                                                    wrappingKeyPassword,
508                                                    wrappedKeyName,
509                                                    wrappedKeyOwner,
510                                                    wrappedKeyPassword);
511
512                 return m_logic->exportWrappedKey(
513                                         cred,
514                                         msgId,
515                                         params,
516                                         wrappingKeyName,
517                                         cred.effectiveOwner(wrappingKeyOwner),
518                                         wrappingKeyPassword,
519                                         wrappedKeyName,
520                                         cred.effectiveOwner(wrappedKeyOwner),
521                                         wrappedKeyPassword);
522         }
523
524         default:
525                 Throw(Exception::BrokenProtocol);
526         }
527 }
528
529 void CKMService::ProcessMessage(MsgKeyRequest msg)
530 {
531         Crypto::GObjShPtr key;
532         int ret = m_logic->getKeyForService(msg.cred,
533                                                                                 msg.name,
534                                                                                 msg.cred.effectiveOwner(msg.explicitOwner),
535                                                                                 msg.password,
536                                                                                 key);
537         MsgKeyResponse kResp(msg.id, key, ret);
538
539         try {
540                 if (!m_commMgr->SendMessage(kResp))
541                         LogError("No listener found"); // can't do much more
542         } catch (...) {
543                 LogError("Uncaught exception in SendMessage. Check listeners.");
544         }
545 }
546
547 void CKMService::ProcessMessage(MsgRemoveAppData msg)
548 {
549         LogDebug("Call removeApplicationData. pkgId: " << msg.pkgId);
550         m_logic->removeApplicationData(msg.pkgId);
551 }
552
553 } // namespace CKM