Alias is not unique user-wide: (alias, label) pair is unique now.
[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         AliasSupport helper(alias);
131         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
132                                              m_counter,
133                                              static_cast<int>(dataType),
134                                              helper.getAlias(),
135                                              helper.getLabel());
136         int retCode = sendToServer(
137             SERVICE_SOCKET_CKM_STORAGE,
138             send.Pop(),
139             recv);
140
141         if (CKM_API_SUCCESS != retCode) {
142             return retCode;
143         }
144
145         int command;
146         int counter;
147         int opType;
148         recv.Deserialize(command, counter, retCode, opType);
149
150         if (counter != m_counter) {
151             return CKM_API_ERROR_UNKNOWN;
152         }
153
154         return retCode;
155     });
156 }
157
158 int ManagerImpl::removeKey(const Alias &alias) {
159     return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
160 }
161
162 int ManagerImpl::removeCertificate(const Alias &alias) {
163     return removeBinaryData(alias, DBDataType::CERTIFICATE);
164 }
165
166 int ManagerImpl::removeData(const Alias &alias) {
167     return removeBinaryData(alias, DBDataType::BINARY_DATA);
168 }
169
170 int ManagerImpl::getBinaryData(
171     const Alias &alias,
172     DBDataType sendDataType,
173     const Password &password,
174     DBDataType &recvDataType,
175     RawBuffer &rawData)
176 {
177     return try_catch([&] {
178         if (alias.empty())
179             return CKM_API_ERROR_INPUT_PARAM;
180
181         MessageBuffer recv;
182         AliasSupport helper(alias);
183         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
184                                              m_counter,
185                                              static_cast<int>(sendDataType),
186                                              helper.getAlias(),
187                                              helper.getLabel(),
188                                              password);
189         int retCode = sendToServer(
190             SERVICE_SOCKET_CKM_STORAGE,
191             send.Pop(),
192             recv);
193
194         if (CKM_API_SUCCESS != retCode) {
195             return retCode;
196         }
197
198         int command;
199         int counter;
200         int tmpDataType;
201         recv.Deserialize(command, counter, retCode, tmpDataType,rawData);
202         recvDataType = static_cast<DBDataType>(tmpDataType);
203
204         if (counter != m_counter) {
205             return CKM_API_ERROR_UNKNOWN;
206         }
207
208         return retCode;
209     });
210 }
211
212 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
213     DBDataType recvDataType;
214     RawBuffer rawData;
215
216     int retCode = getBinaryData(
217         alias,
218         DBDataType::KEY_RSA_PUBLIC,
219         password,
220         recvDataType,
221         rawData);
222
223     if (retCode != CKM_API_SUCCESS)
224         return retCode;
225
226     KeyShPtr keyParsed(new KeyImpl(rawData));
227
228     if (keyParsed->empty()) {
229         LogDebug("Key empty - failed to parse!");
230         return CKM_API_ERROR_BAD_RESPONSE;
231     }
232
233     key = keyParsed;
234
235     return CKM_API_SUCCESS;
236 }
237
238 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
239 {
240     DBDataType recvDataType;
241     RawBuffer rawData;
242
243     int retCode = getBinaryData(
244         alias,
245         DBDataType::CERTIFICATE,
246         password,
247         recvDataType,
248         rawData);
249
250     if (retCode != CKM_API_SUCCESS)
251         return retCode;
252
253     if (recvDataType != DBDataType::CERTIFICATE)
254         return CKM_API_ERROR_BAD_RESPONSE;
255
256     CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
257
258     if (certParsed->empty())
259         return CKM_API_ERROR_BAD_RESPONSE;
260
261     cert = certParsed;
262
263     return CKM_API_SUCCESS;
264 }
265
266 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
267 {
268     DBDataType recvDataType;
269
270     int retCode = getBinaryData(
271         alias,
272         DBDataType::BINARY_DATA,
273         password,
274         recvDataType,
275         rawData);
276
277     if (retCode != CKM_API_SUCCESS)
278         return retCode;
279
280     if (recvDataType != DBDataType::BINARY_DATA)
281         return CKM_API_ERROR_BAD_RESPONSE;
282
283     return CKM_API_SUCCESS;
284 }
285
286 int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
287 {
288     return try_catch([&] {
289
290         MessageBuffer recv;
291         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
292                                              m_counter,
293                                              static_cast<int>(dataType));
294         int retCode = sendToServer(
295             SERVICE_SOCKET_CKM_STORAGE,
296             send.Pop(),
297             recv);
298
299         if (CKM_API_SUCCESS != retCode) {
300             return retCode;
301         }
302
303         int command;
304         int counter;
305         int tmpDataType;
306         LabelAliasVector labelAliasVector;
307         recv.Deserialize(command, counter, retCode, tmpDataType, labelAliasVector);
308         if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
309             return CKM_API_ERROR_UNKNOWN;
310         }
311
312         for(const auto it : labelAliasVector)
313             aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
314
315         return retCode;
316     });
317 }
318
319 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
320     // in fact datatype has no meaning here - if not certificate or binary data
321     // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
322     return getBinaryDataAliasVector(DBDataType::DB_KEY_LAST, aliasVector);
323 }
324
325 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
326     return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
327 }
328
329 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
330     return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
331 }
332
333 int ManagerImpl::createKeyPairRSA(
334     const int size,
335     const Alias &privateKeyAlias,
336     const Alias &publicKeyAlias,
337     const Policy &policyPrivateKey,
338     const Policy &policyPublicKey)
339 {
340     return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
341 }
342
343 int ManagerImpl::createKeyPairDSA(
344     const int size,
345     const Alias &privateKeyAlias,
346     const Alias &publicKeyAlias,
347     const Policy &policyPrivateKey,
348     const Policy &policyPublicKey)
349 {
350     return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
351 }
352
353 int ManagerImpl::createKeyPairECDSA(
354     ElipticCurve type,
355     const Alias &privateKeyAlias,
356     const Alias &publicKeyAlias,
357     const Policy &policyPrivateKey,
358     const Policy &policyPublicKey)
359 {
360     return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
361 }
362
363 int ManagerImpl::createKeyPair(
364     const KeyType key_type,
365     const int     additional_param,
366     const Alias  &privateKeyAlias,
367     const Alias  &publicKeyAlias,
368     const Policy &policyPrivateKey,
369     const Policy &policyPublicKey)
370 {
371     // input type check
372     LogicCommand cmd_type;
373     switch(key_type)
374     {
375         case KeyType::KEY_RSA_PUBLIC:
376         case KeyType::KEY_RSA_PRIVATE:
377             cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
378             break;
379
380         case KeyType::KEY_DSA_PUBLIC:
381         case KeyType::KEY_DSA_PRIVATE:
382             cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
383             break;
384
385         case KeyType::KEY_ECDSA_PUBLIC:
386         case KeyType::KEY_ECDSA_PRIVATE:
387             cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
388             break;
389
390         default:
391             return CKM_API_ERROR_INPUT_PARAM;
392     }
393
394     // proceed with sending request
395     m_counter++;
396     int my_counter = m_counter;
397     return try_catch([&] {
398
399         MessageBuffer recv;
400         auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
401                                              my_counter,
402                                              static_cast<int>(additional_param),
403                                              PolicySerializable(policyPrivateKey),
404                                              PolicySerializable(policyPublicKey),
405                                              privateKeyAlias,
406                                              publicKeyAlias);
407         int retCode = sendToServer(
408             SERVICE_SOCKET_CKM_STORAGE,
409             send.Pop(),
410             recv);
411
412         if (CKM_API_SUCCESS != retCode) {
413             return retCode;
414         }
415
416         int command;
417         int counter;
418         recv.Deserialize(command, counter, retCode);
419         if (counter != my_counter) {
420             return CKM_API_ERROR_UNKNOWN;
421         }
422
423         return retCode;
424     });
425 }
426
427
428 template <class T>
429 int getCertChain(
430     LogicCommand command,
431     int counter,
432     const CertificateShPtr &certificate,
433     const T &sendData,
434     CertificateShPtrVector &certificateChainVector)
435 {
436     return try_catch([&] {
437
438         MessageBuffer recv;
439         auto send = MessageBuffer::Serialize(static_cast<int>(command),
440                                              counter,
441                                              certificate->getDER(),
442                                              sendData);
443         int retCode = sendToServer(
444             SERVICE_SOCKET_CKM_STORAGE,
445             send.Pop(),
446             recv);
447
448         if (CKM_API_SUCCESS != retCode) {
449             return retCode;
450         }
451
452         int retCommand;
453         int retCounter;
454         RawBufferVector rawBufferVector;
455         recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
456
457         if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
458             return CKM_API_ERROR_UNKNOWN;
459         }
460
461         if (retCode != CKM_API_SUCCESS) {
462             return retCode;
463         }
464
465         for (auto &e: rawBufferVector) {
466             CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
467             if (cert->empty())
468                 return CKM_API_ERROR_BAD_RESPONSE;
469             certificateChainVector.push_back(cert);
470         }
471
472         return retCode;
473     });
474 }
475
476
477 int ManagerImpl::getCertificateChain(
478     const CertificateShPtr &certificate,
479     const CertificateShPtrVector &untrustedCertificates,
480     CertificateShPtrVector &certificateChainVector)
481 {
482     RawBufferVector rawBufferVector;
483
484     for (auto &e: untrustedCertificates) {
485         rawBufferVector.push_back(e->getDER());
486     }
487
488     return getCertChain(
489         LogicCommand::GET_CHAIN_CERT,
490         ++m_counter,
491         certificate,
492         rawBufferVector,
493         certificateChainVector);
494 }
495
496 int ManagerImpl::getCertificateChain(
497     const CertificateShPtr &certificate,
498     const AliasVector &untrustedCertificates,
499     CertificateShPtrVector &certificateChainVector)
500 {
501     return getCertChain(
502         LogicCommand::GET_CHAIN_ALIAS,
503         ++m_counter,
504         certificate,
505         untrustedCertificates,
506         certificateChainVector);
507 }
508
509 int ManagerImpl::createSignature(
510     const Alias &privateKeyAlias,
511     const Password &password,           // password for private_key
512     const RawBuffer &message,
513     const HashAlgorithm hash,
514     const RSAPaddingAlgorithm padding,
515     RawBuffer &signature)
516 {
517     m_counter++;
518     int my_counter = m_counter;
519     return try_catch([&] {
520
521         MessageBuffer recv;
522         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
523                                              my_counter,
524                                              privateKeyAlias,
525                                              password,
526                                              message,
527                                              static_cast<int>(hash),
528                                              static_cast<int>(padding));
529         int retCode = sendToServer(
530             SERVICE_SOCKET_CKM_STORAGE,
531             send.Pop(),
532             recv);
533
534         if (CKM_API_SUCCESS != retCode) {
535             return retCode;
536         }
537
538         int command;
539         int counter;
540
541         recv.Deserialize(command, counter, retCode, signature);
542
543         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
544             || (counter != my_counter))
545         {
546             return CKM_API_ERROR_UNKNOWN;
547         }
548
549         return retCode;
550     });
551 }
552
553 int ManagerImpl::verifySignature(
554     const Alias &publicKeyOrCertAlias,
555     const Password &password,           // password for public_key (optional)
556     const RawBuffer &message,
557     const RawBuffer &signature,
558     const HashAlgorithm hash,
559     const RSAPaddingAlgorithm padding)
560 {
561     m_counter++;
562     int my_counter = m_counter;
563     return try_catch([&] {
564
565         MessageBuffer recv;
566         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
567                                              my_counter,
568                                              publicKeyOrCertAlias,
569                                              password,
570                                              message,
571                                              signature,
572                                              static_cast<int>(hash),
573                                              static_cast<int>(padding));
574         int retCode = sendToServer(
575             SERVICE_SOCKET_CKM_STORAGE,
576             send.Pop(),
577             recv);
578
579         if (CKM_API_SUCCESS != retCode) {
580             return retCode;
581         }
582
583         int command;
584         int counter;
585
586         recv.Deserialize(command, counter, retCode);
587
588         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
589             || (counter != my_counter))
590         {
591             return CKM_API_ERROR_UNKNOWN;
592         }
593
594         return retCode;
595     });
596 }
597
598 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
599 {
600     return try_catch([&] {
601         int my_counter = ++m_counter;
602         MessageBuffer recv;
603
604         RawBufferVector rawCertChain;
605         for (auto &e: certChain) {
606             rawCertChain.push_back(e->getDER());
607         }
608
609         auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
610
611         int retCode = sendToServer(
612             SERVICE_SOCKET_OCSP,
613             send.Pop(),
614             recv);
615
616         if (CKM_API_SUCCESS != retCode) {
617             return retCode;
618         }
619
620         int counter;
621
622         recv.Deserialize(counter, retCode, ocspStatus);
623
624         if (my_counter != counter) {
625             return CKM_API_ERROR_UNKNOWN;
626         }
627
628         return retCode;
629     });
630 }
631
632 int ManagerImpl::allowAccess(const std::string &alias,
633                              const std::string &accessor,
634                              AccessRight granted)
635 {
636     m_counter++;
637     int my_counter = m_counter;
638     return try_catch([&] {
639         MessageBuffer recv;
640         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::ALLOW_ACCESS),
641                                              my_counter,
642                                              alias,
643                                              accessor,
644                                              static_cast<int>(granted));
645         int retCode = sendToServer(
646             SERVICE_SOCKET_CKM_STORAGE,
647             send.Pop(),
648             recv);
649
650         if (CKM_API_SUCCESS != retCode) {
651             return retCode;
652         }
653
654         int command;
655         int counter;
656         recv.Deserialize(command, counter, retCode);
657
658         if (my_counter != counter) {
659             return CKM_API_ERROR_UNKNOWN;
660         }
661
662         return retCode;
663     });
664 }
665
666 int ManagerImpl::denyAccess(const std::string &alias, const std::string &accessor)
667 {
668     m_counter++;
669     int my_counter = m_counter;
670     return try_catch([&] {
671         MessageBuffer recv;
672         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::DENY_ACCESS),
673                                              my_counter,
674                                              alias,
675                                              accessor);
676         int retCode = sendToServer(
677             SERVICE_SOCKET_CKM_STORAGE,
678             send.Pop(),
679             recv);
680
681         if (CKM_API_SUCCESS != retCode) {
682             return retCode;
683         }
684
685         int command;
686         int counter;
687         recv.Deserialize(command, counter, retCode);
688
689         if (my_counter != counter) {
690             return CKM_API_ERROR_UNKNOWN;
691         }
692
693         return retCode;
694     });
695 }
696
697 ManagerShPtr Manager::create() {
698     try {
699         return std::make_shared<ManagerImpl>();
700     } catch (const std::bad_alloc &) {
701         LogDebug("Bad alloc was caught during ManagerImpl creation.");
702     } catch (...) {
703         LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
704     }
705     return ManagerShPtr();
706 }
707
708 } // namespace CKM