Add generic serialization/deserialization methods
[platform/core/security/key-manager.git] / src / manager / client / client-manager-impl.cpp
1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
2  *
3  *  Licensed under the Apache License, Version 2.0 (the "License");
4  *  you may not use this file except in compliance with the License.
5  *  You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  *  Unless required by applicable law or agreed to in writing, software
10  *  distributed under the License is distributed on an "AS IS" BASIS,
11  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  *  See the License for the specific language governing permissions and
13  *  limitations under the License
14  *
15  *
16  * @file        client-manager-impl.cpp
17  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
18  * @version     1.0
19  * @brief       Manager implementation.
20  */
21 #include <openssl/evp.h>
22
23 #include <dpl/serialization.h>
24 #include <dpl/log/log.h>
25
26 #include <client-manager-impl.h>
27 #include <client-common.h>
28 #include <message-buffer.h>
29 #include <protocols.h>
30 #include <key-impl.h>
31 #include <certificate-impl.h>
32
33 namespace {
34
35 void clientInitialize(void) {
36     OpenSSL_add_all_ciphers();
37     OpenSSL_add_all_algorithms();
38     OpenSSL_add_all_digests();
39 }
40
41 } // namespace anonymous
42
43 namespace CKM {
44
45 bool ManagerImpl::s_isInit = false;
46
47 ManagerImpl::ManagerImpl()
48   : m_counter(0)
49 {
50     // TODO secure with mutex
51     if (!s_isInit) {
52         s_isInit = true;
53         clientInitialize();
54     }
55
56 }
57
58
59 int ManagerImpl::saveBinaryData(
60     const Alias &alias,
61     DBDataType dataType,
62     const RawBuffer &rawData,
63     const Policy &policy)
64 {
65     m_counter++;
66
67     return try_catch([&] {
68         if (alias.empty() || rawData.empty())
69             return CKM_API_ERROR_INPUT_PARAM;
70
71         MessageBuffer recv;
72         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
73                                              m_counter,
74                                              static_cast<int>(dataType),
75                                              alias,
76                                              rawData,
77                                              PolicySerializable(policy));
78
79         int retCode = sendToServer(
80             SERVICE_SOCKET_CKM_STORAGE,
81             send.Pop(),
82             recv);
83
84         if (CKM_API_SUCCESS != retCode) {
85             return retCode;
86         }
87
88         int command;
89         int counter;
90         int opType;
91         recv.Deserialize(command, counter, retCode, opType);
92
93         if (counter != m_counter) {
94             return CKM_API_ERROR_UNKNOWN;
95         }
96
97         return retCode;
98     });
99 }
100
101 int ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
102     if (key.get() == NULL)
103         return CKM_API_ERROR_INPUT_PARAM;
104     return saveBinaryData(alias, toDBDataType(key->getType()), key->getDER(), policy);
105 }
106
107 int ManagerImpl::saveCertificate(
108     const Alias &alias,
109     const CertificateShPtr &cert,
110     const Policy &policy)
111 {
112     if (cert.get() == NULL)
113         return CKM_API_ERROR_INPUT_PARAM;
114     return saveBinaryData(alias, DBDataType::CERTIFICATE, cert->getDER(), policy);
115 }
116
117 int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
118     if (!policy.extractable)
119         return CKM_API_ERROR_INPUT_PARAM;
120     return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
121 }
122
123 int ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
124 {
125     return try_catch([&] {
126         if (alias.empty())
127             return CKM_API_ERROR_INPUT_PARAM;
128
129         MessageBuffer recv;
130         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
131                                              m_counter,
132                                              static_cast<int>(dataType),
133                                              alias);
134         int retCode = sendToServer(
135             SERVICE_SOCKET_CKM_STORAGE,
136             send.Pop(),
137             recv);
138
139         if (CKM_API_SUCCESS != retCode) {
140             return retCode;
141         }
142
143         int command;
144         int counter;
145         int opType;
146         recv.Deserialize(command, counter, retCode, opType);
147
148         if (counter != m_counter) {
149             return CKM_API_ERROR_UNKNOWN;
150         }
151
152         return retCode;
153     });
154 }
155
156 int ManagerImpl::removeKey(const Alias &alias) {
157     return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
158 }
159
160 int ManagerImpl::removeCertificate(const Alias &alias) {
161     return removeBinaryData(alias, DBDataType::CERTIFICATE);
162 }
163
164 int ManagerImpl::removeData(const Alias &alias) {
165     return removeBinaryData(alias, DBDataType::BINARY_DATA);
166 }
167
168 int ManagerImpl::getBinaryData(
169     const Alias &alias,
170     DBDataType sendDataType,
171     const Password &password,
172     DBDataType &recvDataType,
173     RawBuffer &rawData)
174 {
175     return try_catch([&] {
176         if (alias.empty())
177             return CKM_API_ERROR_INPUT_PARAM;
178
179         MessageBuffer recv;
180         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
181                                              m_counter,
182                                              static_cast<int>(sendDataType),
183                                              alias,
184                                              password);
185         int retCode = sendToServer(
186             SERVICE_SOCKET_CKM_STORAGE,
187             send.Pop(),
188             recv);
189
190         if (CKM_API_SUCCESS != retCode) {
191             return retCode;
192         }
193
194         int command;
195         int counter;
196         int tmpDataType;
197         recv.Deserialize(command, counter, retCode, tmpDataType,rawData);
198         recvDataType = static_cast<DBDataType>(tmpDataType);
199
200         if (counter != m_counter) {
201             return CKM_API_ERROR_UNKNOWN;
202         }
203
204         return retCode;
205     });
206 }
207
208 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
209     DBDataType recvDataType;
210     RawBuffer rawData;
211
212     int retCode = getBinaryData(
213         alias,
214         DBDataType::KEY_RSA_PUBLIC,
215         password,
216         recvDataType,
217         rawData);
218
219     if (retCode != CKM_API_SUCCESS)
220         return retCode;
221
222     KeyShPtr keyParsed(new KeyImpl(rawData));
223
224     if (keyParsed->empty()) {
225         LogDebug("Key empty - failed to parse!");
226         return CKM_API_ERROR_BAD_RESPONSE;
227     }
228
229     key = keyParsed;
230
231     return CKM_API_SUCCESS;
232 }
233
234 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
235 {
236     DBDataType recvDataType;
237     RawBuffer rawData;
238
239     int retCode = getBinaryData(
240         alias,
241         DBDataType::CERTIFICATE,
242         password,
243         recvDataType,
244         rawData);
245
246     if (retCode != CKM_API_SUCCESS)
247         return retCode;
248
249     if (recvDataType != DBDataType::CERTIFICATE)
250         return CKM_API_ERROR_BAD_RESPONSE;
251
252     CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
253
254     if (certParsed->empty())
255         return CKM_API_ERROR_BAD_RESPONSE;
256
257     cert = certParsed;
258
259     return CKM_API_SUCCESS;
260 }
261
262 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
263 {
264     DBDataType recvDataType;
265
266     int retCode = getBinaryData(
267         alias,
268         DBDataType::BINARY_DATA,
269         password,
270         recvDataType,
271         rawData);
272
273     if (retCode != CKM_API_SUCCESS)
274         return retCode;
275
276     if (recvDataType != DBDataType::BINARY_DATA)
277         return CKM_API_ERROR_BAD_RESPONSE;
278
279     return CKM_API_SUCCESS;
280 }
281
282 int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
283 {
284     return try_catch([&] {
285
286         MessageBuffer recv;
287         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
288                                              m_counter,
289                                              static_cast<int>(dataType));
290         int retCode = sendToServer(
291             SERVICE_SOCKET_CKM_STORAGE,
292             send.Pop(),
293             recv);
294
295         if (CKM_API_SUCCESS != retCode) {
296             return retCode;
297         }
298
299         int command;
300         int counter;
301         int tmpDataType;
302         recv.Deserialize(command, counter, retCode, tmpDataType, aliasVector);
303         if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
304             return CKM_API_ERROR_UNKNOWN;
305         }
306
307         return retCode;
308     });
309 }
310
311 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
312     // in fact datatype has no meaning here - if not certificate or binary data
313     // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
314     return getBinaryDataAliasVector(DBDataType::DB_KEY_LAST, aliasVector);
315 }
316
317 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
318     return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
319 }
320
321 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
322     return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
323 }
324
325 int ManagerImpl::createKeyPairRSA(
326     const int size,
327     const Alias &privateKeyAlias,
328     const Alias &publicKeyAlias,
329     const Policy &policyPrivateKey,
330     const Policy &policyPublicKey)
331 {
332     return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
333 }
334
335 int ManagerImpl::createKeyPairDSA(
336     const int size,
337     const Alias &privateKeyAlias,
338     const Alias &publicKeyAlias,
339     const Policy &policyPrivateKey,
340     const Policy &policyPublicKey)
341 {
342     return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
343 }
344
345 int ManagerImpl::createKeyPairECDSA(
346     ElipticCurve type,
347     const Alias &privateKeyAlias,
348     const Alias &publicKeyAlias,
349     const Policy &policyPrivateKey,
350     const Policy &policyPublicKey)
351 {
352     return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
353 }
354
355 int ManagerImpl::createKeyPair(
356     const KeyType key_type,
357     const int     additional_param,
358     const Alias  &privateKeyAlias,
359     const Alias  &publicKeyAlias,
360     const Policy &policyPrivateKey,
361     const Policy &policyPublicKey)
362 {
363     // input type check
364     LogicCommand cmd_type;
365     switch(key_type)
366     {
367         case KeyType::KEY_RSA_PUBLIC:
368         case KeyType::KEY_RSA_PRIVATE:
369             cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
370             break;
371
372         case KeyType::KEY_DSA_PUBLIC:
373         case KeyType::KEY_DSA_PRIVATE:
374             cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
375             break;
376
377         case KeyType::KEY_ECDSA_PUBLIC:
378         case KeyType::KEY_ECDSA_PRIVATE:
379             cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
380             break;
381
382         default:
383             return CKM_API_ERROR_INPUT_PARAM;
384     }
385
386     // proceed with sending request
387     m_counter++;
388     int my_counter = m_counter;
389     return try_catch([&] {
390
391         MessageBuffer recv;
392         auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
393                                              my_counter,
394                                              static_cast<int>(additional_param),
395                                              PolicySerializable(policyPrivateKey),
396                                              PolicySerializable(policyPublicKey),
397                                              privateKeyAlias,
398                                              publicKeyAlias);
399         int retCode = sendToServer(
400             SERVICE_SOCKET_CKM_STORAGE,
401             send.Pop(),
402             recv);
403
404         if (CKM_API_SUCCESS != retCode) {
405             return retCode;
406         }
407
408         int command;
409         int counter;
410         recv.Deserialize(command, counter, retCode);
411         if (counter != my_counter) {
412             return CKM_API_ERROR_UNKNOWN;
413         }
414
415         return retCode;
416     });
417 }
418
419
420 template <class T>
421 int getCertChain(
422     LogicCommand command,
423     int counter,
424     const CertificateShPtr &certificate,
425     const T &sendData,
426     CertificateShPtrVector &certificateChainVector)
427 {
428     return try_catch([&] {
429
430         MessageBuffer recv;
431         auto send = MessageBuffer::Serialize(static_cast<int>(command),
432                                              counter,
433                                              certificate->getDER(),
434                                              sendData);
435         int retCode = sendToServer(
436             SERVICE_SOCKET_CKM_STORAGE,
437             send.Pop(),
438             recv);
439
440         if (CKM_API_SUCCESS != retCode) {
441             return retCode;
442         }
443
444         int retCommand;
445         int retCounter;
446         RawBufferVector rawBufferVector;
447         recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
448
449         if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
450             return CKM_API_ERROR_UNKNOWN;
451         }
452
453         if (retCode != CKM_API_SUCCESS) {
454             return retCode;
455         }
456
457         for (auto &e: rawBufferVector) {
458             CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
459             if (cert->empty())
460                 return CKM_API_ERROR_BAD_RESPONSE;
461             certificateChainVector.push_back(cert);
462         }
463
464         return retCode;
465     });
466 }
467
468
469 int ManagerImpl::getCertificateChain(
470     const CertificateShPtr &certificate,
471     const CertificateShPtrVector &untrustedCertificates,
472     CertificateShPtrVector &certificateChainVector)
473 {
474     RawBufferVector rawBufferVector;
475
476     for (auto &e: untrustedCertificates) {
477         rawBufferVector.push_back(e->getDER());
478     }
479
480     return getCertChain(
481         LogicCommand::GET_CHAIN_CERT,
482         ++m_counter,
483         certificate,
484         rawBufferVector,
485         certificateChainVector);
486 }
487
488 int ManagerImpl::getCertificateChain(
489     const CertificateShPtr &certificate,
490     const AliasVector &untrustedCertificates,
491     CertificateShPtrVector &certificateChainVector)
492 {
493     return getCertChain(
494         LogicCommand::GET_CHAIN_ALIAS,
495         ++m_counter,
496         certificate,
497         untrustedCertificates,
498         certificateChainVector);
499 }
500
501 int ManagerImpl::createSignature(
502     const Alias &privateKeyAlias,
503     const Password &password,           // password for private_key
504     const RawBuffer &message,
505     const HashAlgorithm hash,
506     const RSAPaddingAlgorithm padding,
507     RawBuffer &signature)
508 {
509     m_counter++;
510     int my_counter = m_counter;
511     return try_catch([&] {
512
513         MessageBuffer recv;
514         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
515                                              my_counter,
516                                              privateKeyAlias,
517                                              password,
518                                              message,
519                                              static_cast<int>(hash),
520                                              static_cast<int>(padding));
521         int retCode = sendToServer(
522             SERVICE_SOCKET_CKM_STORAGE,
523             send.Pop(),
524             recv);
525
526         if (CKM_API_SUCCESS != retCode) {
527             return retCode;
528         }
529
530         int command;
531         int counter;
532
533         recv.Deserialize(command, counter, retCode, signature);
534
535         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
536             || (counter != my_counter))
537         {
538             return CKM_API_ERROR_UNKNOWN;
539         }
540
541         return retCode;
542     });
543 }
544
545 int ManagerImpl::verifySignature(
546     const Alias &publicKeyOrCertAlias,
547     const Password &password,           // password for public_key (optional)
548     const RawBuffer &message,
549     const RawBuffer &signature,
550     const HashAlgorithm hash,
551     const RSAPaddingAlgorithm padding)
552 {
553     m_counter++;
554     int my_counter = m_counter;
555     return try_catch([&] {
556
557         MessageBuffer recv;
558         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
559                                              my_counter,
560                                              publicKeyOrCertAlias,
561                                              password,
562                                              message,
563                                              signature,
564                                              static_cast<int>(hash),
565                                              static_cast<int>(padding));
566         int retCode = sendToServer(
567             SERVICE_SOCKET_CKM_STORAGE,
568             send.Pop(),
569             recv);
570
571         if (CKM_API_SUCCESS != retCode) {
572             return retCode;
573         }
574
575         int command;
576         int counter;
577
578         recv.Deserialize(command, counter, retCode);
579
580         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
581             || (counter != my_counter))
582         {
583             return CKM_API_ERROR_UNKNOWN;
584         }
585
586         return retCode;
587     });
588 }
589
590 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
591 {
592     return try_catch([&] {
593         int my_counter = ++m_counter;
594         MessageBuffer recv;
595
596         RawBufferVector rawCertChain;
597         for (auto &e: certChain) {
598             rawCertChain.push_back(e->getDER());
599         }
600
601         auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
602
603         int retCode = sendToServer(
604             SERVICE_SOCKET_OCSP,
605             send.Pop(),
606             recv);
607
608         if (CKM_API_SUCCESS != retCode) {
609             return retCode;
610         }
611
612         int counter;
613
614         recv.Deserialize(counter, retCode, ocspStatus);
615
616         if (my_counter != counter) {
617             return CKM_API_ERROR_UNKNOWN;
618         }
619
620         return retCode;
621     });
622 }
623
624 int ManagerImpl::allowAccess(const std::string &alias,
625                              const std::string &accessor,
626                              AccessRight granted)
627 {
628     m_counter++;
629     int my_counter = m_counter;
630     return try_catch([&] {
631         MessageBuffer recv;
632         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::ALLOW_ACCESS),
633                                              my_counter,
634                                              alias,
635                                              accessor,
636                                              static_cast<int>(granted));
637         int retCode = sendToServer(
638             SERVICE_SOCKET_CKM_STORAGE,
639             send.Pop(),
640             recv);
641
642         if (CKM_API_SUCCESS != retCode) {
643             return retCode;
644         }
645
646         int command;
647         int counter;
648         recv.Deserialize(command, counter, retCode);
649
650         if (my_counter != counter) {
651             return CKM_API_ERROR_UNKNOWN;
652         }
653
654         return retCode;
655     });
656 }
657
658 int ManagerImpl::denyAccess(const std::string &alias, const std::string &accessor)
659 {
660     m_counter++;
661     int my_counter = m_counter;
662     return try_catch([&] {
663         MessageBuffer recv;
664         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::DENY_ACCESS),
665                                              my_counter,
666                                              alias,
667                                              accessor);
668         int retCode = sendToServer(
669             SERVICE_SOCKET_CKM_STORAGE,
670             send.Pop(),
671             recv);
672
673         if (CKM_API_SUCCESS != retCode) {
674             return retCode;
675         }
676
677         int command;
678         int counter;
679         recv.Deserialize(command, counter, retCode);
680
681         if (my_counter != counter) {
682             return CKM_API_ERROR_UNKNOWN;
683         }
684
685         return retCode;
686     });
687 }
688
689 ManagerShPtr Manager::create() {
690     try {
691         return std::make_shared<ManagerImpl>();
692     } catch (const std::bad_alloc &) {
693         LogDebug("Bad alloc was caught during ManagerImpl creation.");
694     } catch (...) {
695         LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
696     }
697     return ManagerShPtr();
698 }
699
700 } // namespace CKM