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