b27e18033867828c315221e1c63df880bd57271c
[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 <crypto-init.h>
27 #include <client-manager-impl.h>
28 #include <client-common.h>
29 #include <message-buffer.h>
30 #include <protocols.h>
31 #include <key-impl.h>
32 #include <certificate-impl.h>
33
34 namespace CKM {
35
36 namespace {
37 template <class T>
38 int getCertChain(
39     ServiceConnection & serviceConnection,
40     LogicCommand command,
41     int counter,
42     const CertificateShPtr &certificate,
43     const T &untrustedVector,
44     const T &trustedVector,
45     bool useTrustedSystemCertificates,
46     CertificateShPtrVector &certificateChainVector)
47 {
48     return try_catch([&] {
49
50         MessageBuffer recv;
51         auto send = MessageBuffer::Serialize(static_cast<int>(command),
52                                              counter,
53                                              certificate->getDER(),
54                                              untrustedVector,
55                                              trustedVector,
56                                              useTrustedSystemCertificates);
57
58         int retCode = serviceConnection.processRequest(send.Pop(), recv);
59         if (CKM_API_SUCCESS != retCode)
60             return retCode;
61
62         int retCommand;
63         int retCounter;
64         RawBufferVector rawBufferVector;
65         recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
66
67         if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
68             return CKM_API_ERROR_UNKNOWN;
69         }
70
71         if (retCode != CKM_API_SUCCESS) {
72             return retCode;
73         }
74
75         for (auto &e: rawBufferVector) {
76             CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
77             if (cert->empty())
78                 return CKM_API_ERROR_BAD_RESPONSE;
79             certificateChainVector.push_back(cert);
80         }
81
82         return retCode;
83     });
84 }
85
86 } // namespace anonymous
87
88 ManagerImpl::ManagerImpl()
89   : m_counter(0), m_storageConnection(SERVICE_SOCKET_CKM_STORAGE), m_ocspConnection(SERVICE_SOCKET_OCSP)
90 {
91     initCryptoLib();
92 }
93
94
95 int ManagerImpl::saveBinaryData(
96     const Alias &alias,
97     DataType dataType,
98     const RawBuffer &rawData,
99     const Policy &policy)
100 {
101     int my_counter = ++m_counter;
102
103     return try_catch([&] {
104         if (alias.empty() || rawData.empty())
105             return CKM_API_ERROR_INPUT_PARAM;
106
107         MessageBuffer recv;
108         AliasSupport helper(alias);
109         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
110                                              my_counter,
111                                              static_cast<int>(dataType),
112                                              helper.getName(),
113                                              helper.getLabel(),
114                                              rawData,
115                                              PolicySerializable(policy));
116
117         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
118         if (CKM_API_SUCCESS != retCode)
119             return retCode;
120
121         int command;
122         int counter;
123         int opType;
124         recv.Deserialize(command, counter, retCode, opType);
125
126         if (counter != my_counter)
127             return CKM_API_ERROR_UNKNOWN;
128
129         return retCode;
130     });
131 }
132
133 int ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
134     if (key.get() == NULL)
135         return CKM_API_ERROR_INPUT_PARAM;
136     Try {
137         return saveBinaryData(alias, DataType(key->getType()), key->getDER(), policy);
138     } Catch (DataType::Exception::Base) {
139         LogError("Error in key conversion. Could not convert KeyType::NONE to DBDataType!");
140     }
141     return CKM_API_ERROR_INPUT_PARAM;
142 }
143
144 int ManagerImpl::saveCertificate(
145     const Alias &alias,
146     const CertificateShPtr &cert,
147     const Policy &policy)
148 {
149     if (cert.get() == NULL)
150         return CKM_API_ERROR_INPUT_PARAM;
151     return saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy);
152 }
153
154 int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
155     if (!policy.extractable)
156         return CKM_API_ERROR_INPUT_PARAM;
157     return saveBinaryData(alias, DataType::BINARY_DATA, rawData, policy);
158 }
159
160
161 int ManagerImpl::savePKCS12(
162     const Alias & alias,
163     const PKCS12ShPtr &pkcs,
164     const Policy &keyPolicy,
165     const Policy &certPolicy)
166 {
167     if (alias.empty() || pkcs.get()==NULL)
168         return CKM_API_ERROR_INPUT_PARAM;
169
170     int my_counter = ++m_counter;
171
172     return try_catch([&] {
173         MessageBuffer recv;
174         AliasSupport helper(alias);
175         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
176                                              my_counter,
177                                              helper.getName(),
178                                              helper.getLabel(),
179                                              PKCS12Serializable(*pkcs.get()),
180                                              PolicySerializable(keyPolicy),
181                                              PolicySerializable(certPolicy));
182
183         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
184         if (CKM_API_SUCCESS != retCode)
185             return retCode;
186
187         int command;
188         int counter;
189         recv.Deserialize(command, counter, retCode);
190
191         if (counter != my_counter)
192             return CKM_API_ERROR_UNKNOWN;
193
194         return retCode;
195     });
196 }
197
198 int ManagerImpl::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs)
199 {
200     return getPKCS12(alias, Password(), Password(), pkcs);
201 }
202
203 int ManagerImpl::getPKCS12(const Alias &alias, const Password &keyPass, const Password &certPass, PKCS12ShPtr &pkcs)
204 {
205     if (alias.empty())
206         return CKM_API_ERROR_INPUT_PARAM;
207
208     int my_counter = ++m_counter;
209
210     return try_catch([&] {
211         MessageBuffer recv;
212         AliasSupport helper(alias);
213         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
214                                              my_counter,
215                                              helper.getName(),
216                                              helper.getLabel(),
217                                              keyPass,
218                                              certPass);
219
220         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
221         if (CKM_API_SUCCESS != retCode)
222             return retCode;
223
224         int command;
225         int counter;
226         PKCS12Serializable gotPkcs;
227         recv.Deserialize(command, counter, retCode, gotPkcs);
228
229         if (counter != my_counter)
230             return CKM_API_ERROR_UNKNOWN;
231
232         pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs));
233
234         return retCode;
235     });
236 }
237
238
239 int ManagerImpl::removeAlias(const Alias &alias)
240 {
241     if (alias.empty())
242         return CKM_API_ERROR_INPUT_PARAM;
243
244     int my_counter = ++m_counter;
245
246     return try_catch([&] {
247         MessageBuffer recv;
248         AliasSupport helper(alias);
249         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
250                                              my_counter,
251                                              helper.getName(),
252                                              helper.getLabel());
253
254         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
255         if (CKM_API_SUCCESS != retCode)
256             return retCode;
257
258         int command;
259         int counter;
260         recv.Deserialize(command, counter, retCode);
261
262         if (counter != my_counter)
263             return CKM_API_ERROR_UNKNOWN;
264
265         return retCode;
266     });
267 }
268
269 int ManagerImpl::getBinaryData(
270     const Alias &alias,
271     DataType sendDataType,
272     const Password &password,
273     DataType &recvDataType,
274     RawBuffer &rawData)
275 {
276     if (alias.empty())
277         return CKM_API_ERROR_INPUT_PARAM;
278
279     int my_counter = ++m_counter;
280
281     return try_catch([&] {
282         MessageBuffer recv;
283         AliasSupport helper(alias);
284         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
285                                              my_counter,
286                                              static_cast<int>(sendDataType),
287                                              helper.getName(),
288                                              helper.getLabel(),
289                                              password);
290
291         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
292         if (CKM_API_SUCCESS != retCode)
293             return retCode;
294
295         int command;
296         int counter;
297         int tmpDataType;
298         recv.Deserialize(command, counter, retCode, tmpDataType, rawData);
299         recvDataType = DataType(tmpDataType);
300
301         if (counter != my_counter)
302             return CKM_API_ERROR_UNKNOWN;
303
304         return retCode;
305     });
306 }
307
308 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
309     DataType recvDataType;
310     RawBuffer rawData;
311
312     int retCode = getBinaryData(
313         alias,
314         DataType::KEY_RSA_PUBLIC,
315         password,
316         recvDataType,
317         rawData);
318
319     if (retCode != CKM_API_SUCCESS)
320         return retCode;
321
322     KeyShPtr keyParsed(new KeyImpl(rawData));
323
324     if (keyParsed->empty()) {
325         LogDebug("Key empty - failed to parse!");
326         return CKM_API_ERROR_BAD_RESPONSE;
327     }
328
329     key = keyParsed;
330
331     return CKM_API_SUCCESS;
332 }
333
334 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
335 {
336     DataType recvDataType;
337     RawBuffer rawData;
338
339     int retCode = getBinaryData(
340         alias,
341         DataType::CERTIFICATE,
342         password,
343         recvDataType,
344         rawData);
345
346     if (retCode != CKM_API_SUCCESS)
347         return retCode;
348
349     if (recvDataType != DataType::CERTIFICATE)
350         return CKM_API_ERROR_BAD_RESPONSE;
351
352     CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
353
354     if (certParsed->empty())
355         return CKM_API_ERROR_BAD_RESPONSE;
356
357     cert = certParsed;
358
359     return CKM_API_SUCCESS;
360 }
361
362 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
363 {
364     DataType recvDataType = DataType::BINARY_DATA;
365
366     int retCode = getBinaryData(
367         alias,
368         DataType::BINARY_DATA,
369         password,
370         recvDataType,
371         rawData);
372
373     if (retCode != CKM_API_SUCCESS)
374         return retCode;
375
376     if (recvDataType != DataType::BINARY_DATA)
377         return CKM_API_ERROR_BAD_RESPONSE;
378
379     return CKM_API_SUCCESS;
380 }
381
382 int ManagerImpl::getBinaryDataAliasVector(DataType dataType, AliasVector &aliasVector)
383 {
384     int my_counter = ++m_counter;
385
386     return try_catch([&] {
387         MessageBuffer recv;
388         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
389                                              my_counter,
390                                              static_cast<int>(dataType));
391
392         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
393         if (CKM_API_SUCCESS != retCode)
394             return retCode;
395
396         int command;
397         int counter;
398         int tmpDataType;
399         LabelNameVector labelNameVector;
400         recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector);
401         if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != my_counter)) {
402             return CKM_API_ERROR_UNKNOWN;
403         }
404
405         for(const auto &it : labelNameVector)
406             aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
407
408         return retCode;
409     });
410 }
411
412 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
413     // in fact datatype has no meaning here - if not certificate or binary data
414     // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
415     return getBinaryDataAliasVector(DataType::DB_KEY_LAST, aliasVector);
416 }
417
418 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
419     return getBinaryDataAliasVector(DataType::CERTIFICATE, aliasVector);
420 }
421
422 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
423     return getBinaryDataAliasVector(DataType::BINARY_DATA, aliasVector);
424 }
425
426 int ManagerImpl::createKeyPairRSA(
427     const int size,
428     const Alias &privateKeyAlias,
429     const Alias &publicKeyAlias,
430     const Policy &policyPrivateKey,
431     const Policy &policyPublicKey)
432 {
433     return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
434 }
435
436 int ManagerImpl::createKeyPairDSA(
437     const int size,
438     const Alias &privateKeyAlias,
439     const Alias &publicKeyAlias,
440     const Policy &policyPrivateKey,
441     const Policy &policyPublicKey)
442 {
443     return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
444 }
445
446 int ManagerImpl::createKeyPairECDSA(
447     ElipticCurve type,
448     const Alias &privateKeyAlias,
449     const Alias &publicKeyAlias,
450     const Policy &policyPrivateKey,
451     const Policy &policyPublicKey)
452 {
453     return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
454 }
455
456 int ManagerImpl::createKeyPair(
457     const KeyType key_type,
458     const int     additional_param,
459     const Alias  &privateKeyAlias,
460     const Alias  &publicKeyAlias,
461     const Policy &policyPrivateKey,
462     const Policy &policyPublicKey)
463 {
464     // input type check
465     LogicCommand cmd_type;
466     switch(key_type)
467     {
468         case KeyType::KEY_RSA_PUBLIC:
469         case KeyType::KEY_RSA_PRIVATE:
470             cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
471             break;
472
473         case KeyType::KEY_DSA_PUBLIC:
474         case KeyType::KEY_DSA_PRIVATE:
475             cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
476             break;
477
478         case KeyType::KEY_ECDSA_PUBLIC:
479         case KeyType::KEY_ECDSA_PRIVATE:
480             cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
481             break;
482
483         default:
484             return CKM_API_ERROR_INPUT_PARAM;
485     }
486
487     // proceed with sending request
488     int my_counter = ++m_counter;
489
490     return try_catch([&] {
491
492         MessageBuffer recv;
493         AliasSupport privateHelper(privateKeyAlias);
494         AliasSupport publicHelper(publicKeyAlias);
495         auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
496                                              my_counter,
497                                              static_cast<int>(additional_param),
498                                              PolicySerializable(policyPrivateKey),
499                                              PolicySerializable(policyPublicKey),
500                                              privateHelper.getName(),
501                                              privateHelper.getLabel(),
502                                              publicHelper.getName(),
503                                              publicHelper.getLabel());
504
505         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
506         if (CKM_API_SUCCESS != retCode)
507             return retCode;
508
509         int command;
510         int counter;
511         recv.Deserialize(command, counter, retCode);
512         if (counter != my_counter) {
513             return CKM_API_ERROR_UNKNOWN;
514         }
515
516         return retCode;
517     });
518 }
519
520 int ManagerImpl::getCertificateChain(
521     const CertificateShPtr &certificate,
522     const CertificateShPtrVector &untrustedCertificates,
523     const CertificateShPtrVector &trustedCertificates,
524     bool useTrustedSystemCertificates,
525     CertificateShPtrVector &certificateChainVector)
526 {
527     RawBufferVector untrustedVector;
528     RawBufferVector trustedVector;
529
530     for (auto &e: untrustedCertificates) {
531         untrustedVector.push_back(e->getDER());
532     }
533     for (auto &e: trustedCertificates) {
534         trustedVector.push_back(e->getDER());
535     }
536
537     return getCertChain(
538             m_storageConnection,
539             LogicCommand::GET_CHAIN_CERT,
540             ++m_counter,
541             certificate,
542             untrustedVector,
543             trustedVector,
544             useTrustedSystemCertificates,
545             certificateChainVector);
546 }
547
548 int ManagerImpl::getCertificateChain(
549     const CertificateShPtr &certificate,
550     const AliasVector &untrustedCertificates,
551     const AliasVector &trustedCertificates,
552     bool useTrustedSystemCertificates,
553     CertificateShPtrVector &certificateChainVector)
554 {
555     LabelNameVector untrustedVector;
556     LabelNameVector trustedVector;
557
558     for (auto &e: untrustedCertificates) {
559         AliasSupport helper(e);
560         untrustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName()));
561     }
562     for (auto &e: trustedCertificates) {
563         AliasSupport helper(e);
564         trustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName()));
565     }
566
567     return getCertChain(
568             m_storageConnection,
569             LogicCommand::GET_CHAIN_ALIAS,
570             ++m_counter,
571             certificate,
572             untrustedVector,
573             trustedVector,
574             useTrustedSystemCertificates,
575             certificateChainVector);
576 }
577
578 int ManagerImpl::createSignature(
579     const Alias &privateKeyAlias,
580     const Password &password,           // password for private_key
581     const RawBuffer &message,
582     const HashAlgorithm hash,
583     const RSAPaddingAlgorithm padding,
584     RawBuffer &signature)
585 {
586     int my_counter = ++m_counter;
587
588     return try_catch([&] {
589
590         MessageBuffer recv;
591         AliasSupport helper(privateKeyAlias);
592         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
593                                              my_counter,
594                                              helper.getName(),
595                                              helper.getLabel(),
596                                              password,
597                                              message,
598                                              static_cast<int>(hash),
599                                              static_cast<int>(padding));
600
601         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
602         if (CKM_API_SUCCESS != retCode)
603             return retCode;
604
605         int command;
606         int counter;
607         recv.Deserialize(command, counter, retCode, signature);
608
609         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
610             || (counter != my_counter))
611         {
612             return CKM_API_ERROR_UNKNOWN;
613         }
614
615         return retCode;
616     });
617 }
618
619 int ManagerImpl::verifySignature(
620     const Alias &publicKeyOrCertAlias,
621     const Password &password,           // password for public_key (optional)
622     const RawBuffer &message,
623     const RawBuffer &signature,
624     const HashAlgorithm hash,
625     const RSAPaddingAlgorithm padding)
626 {
627     int my_counter = ++m_counter;
628
629     return try_catch([&] {
630         MessageBuffer recv;
631         AliasSupport helper(publicKeyOrCertAlias);
632         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
633                                              my_counter,
634                                              helper.getName(),
635                                              helper.getLabel(),
636                                              password,
637                                              message,
638                                              signature,
639                                              static_cast<int>(hash),
640                                              static_cast<int>(padding));
641
642         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
643         if (CKM_API_SUCCESS != retCode)
644             return retCode;
645
646         int command;
647         int counter;
648         recv.Deserialize(command, counter, retCode);
649
650         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
651             || (counter != my_counter))
652         {
653             return CKM_API_ERROR_UNKNOWN;
654         }
655
656         return retCode;
657     });
658 }
659
660 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
661 {
662     return try_catch([&] {
663         int my_counter = ++m_counter;
664         MessageBuffer recv;
665
666         RawBufferVector rawCertChain;
667         for (auto &e: certChain) {
668             rawCertChain.push_back(e->getDER());
669         }
670
671         auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
672
673         int retCode = m_ocspConnection.processRequest(send.Pop(), recv);
674         if (CKM_API_SUCCESS != retCode)
675             return retCode;
676
677         int counter;
678         recv.Deserialize(counter, retCode, ocspStatus);
679
680         if (my_counter != counter) {
681             return CKM_API_ERROR_UNKNOWN;
682         }
683
684         return retCode;
685     });
686 }
687
688 int ManagerImpl::setPermission(const Alias &alias,
689                                const Label &accessor,
690                                PermissionMask permissionMask)
691 {
692     int my_counter = ++m_counter;
693
694     return try_catch([&] {
695         MessageBuffer recv;
696         AliasSupport helper(alias);
697         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
698                                              my_counter,
699                                              helper.getName(),
700                                              helper.getLabel(),
701                                              accessor,
702                                              permissionMask);
703
704         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
705         if (CKM_API_SUCCESS != retCode)
706             return retCode;
707
708         int command;
709         int counter;
710         recv.Deserialize(command, counter, retCode);
711
712         if (my_counter != counter) {
713             return CKM_API_ERROR_UNKNOWN;
714         }
715
716         return retCode;
717     });
718 }
719
720 ManagerShPtr Manager::create() {
721     try {
722         return std::make_shared<ManagerImpl>();
723     } catch (const std::bad_alloc &) {
724         LogDebug("Bad alloc was caught during ManagerImpl creation.");
725     } catch (...) {
726         LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
727     }
728     return ManagerShPtr();
729 }
730
731 } // namespace CKM