Split alias at server side into pair name and label.
[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.getName(),
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.getName(),
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         LabelNameVector labelNameVector;
307         recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector);
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 : labelNameVector)
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         AliasSupport helper(privateKeyAlias);
523         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
524                                              my_counter,
525                                              helper.getName(),
526                                              helper.getLabel(),
527                                              password,
528                                              message,
529                                              static_cast<int>(hash),
530                                              static_cast<int>(padding));
531         int retCode = sendToServer(
532             SERVICE_SOCKET_CKM_STORAGE,
533             send.Pop(),
534             recv);
535
536         if (CKM_API_SUCCESS != retCode) {
537             return retCode;
538         }
539
540         int command;
541         int counter;
542
543         recv.Deserialize(command, counter, retCode, signature);
544
545         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
546             || (counter != my_counter))
547         {
548             return CKM_API_ERROR_UNKNOWN;
549         }
550
551         return retCode;
552     });
553 }
554
555 int ManagerImpl::verifySignature(
556     const Alias &publicKeyOrCertAlias,
557     const Password &password,           // password for public_key (optional)
558     const RawBuffer &message,
559     const RawBuffer &signature,
560     const HashAlgorithm hash,
561     const RSAPaddingAlgorithm padding)
562 {
563     m_counter++;
564     int my_counter = m_counter;
565     return try_catch([&] {
566
567         MessageBuffer recv;
568         AliasSupport helper(publicKeyOrCertAlias);
569         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
570                                              my_counter,
571                                              helper.getName(),
572                                              helper.getLabel(),
573                                              password,
574                                              message,
575                                              signature,
576                                              static_cast<int>(hash),
577                                              static_cast<int>(padding));
578         int retCode = sendToServer(
579             SERVICE_SOCKET_CKM_STORAGE,
580             send.Pop(),
581             recv);
582
583         if (CKM_API_SUCCESS != retCode) {
584             return retCode;
585         }
586
587         int command;
588         int counter;
589
590         recv.Deserialize(command, counter, retCode);
591
592         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
593             || (counter != my_counter))
594         {
595             return CKM_API_ERROR_UNKNOWN;
596         }
597
598         return retCode;
599     });
600 }
601
602 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
603 {
604     return try_catch([&] {
605         int my_counter = ++m_counter;
606         MessageBuffer recv;
607
608         RawBufferVector rawCertChain;
609         for (auto &e: certChain) {
610             rawCertChain.push_back(e->getDER());
611         }
612
613         auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
614
615         int retCode = sendToServer(
616             SERVICE_SOCKET_OCSP,
617             send.Pop(),
618             recv);
619
620         if (CKM_API_SUCCESS != retCode) {
621             return retCode;
622         }
623
624         int counter;
625
626         recv.Deserialize(counter, retCode, ocspStatus);
627
628         if (my_counter != counter) {
629             return CKM_API_ERROR_UNKNOWN;
630         }
631
632         return retCode;
633     });
634 }
635
636 int ManagerImpl::allowAccess(const Alias &alias,
637                              const Label &accessor,
638                              AccessRight granted)
639 {
640     m_counter++;
641     int my_counter = m_counter;
642     return try_catch([&] {
643         MessageBuffer recv;
644         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::ALLOW_ACCESS),
645                                              my_counter,
646                                              alias,
647                                              accessor,
648                                              static_cast<int>(granted));
649         int retCode = sendToServer(
650             SERVICE_SOCKET_CKM_STORAGE,
651             send.Pop(),
652             recv);
653
654         if (CKM_API_SUCCESS != retCode) {
655             return retCode;
656         }
657
658         int command;
659         int counter;
660         recv.Deserialize(command, counter, retCode);
661
662         if (my_counter != counter) {
663             return CKM_API_ERROR_UNKNOWN;
664         }
665
666         return retCode;
667     });
668 }
669
670 int ManagerImpl::denyAccess(const Alias &alias, const Label &accessor)
671 {
672     m_counter++;
673     int my_counter = m_counter;
674     return try_catch([&] {
675         MessageBuffer recv;
676         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::DENY_ACCESS),
677                                              my_counter,
678                                              alias,
679                                              accessor);
680         int retCode = sendToServer(
681             SERVICE_SOCKET_CKM_STORAGE,
682             send.Pop(),
683             recv);
684
685         if (CKM_API_SUCCESS != retCode) {
686             return retCode;
687         }
688
689         int command;
690         int counter;
691         recv.Deserialize(command, counter, retCode);
692
693         if (my_counter != counter) {
694             return CKM_API_ERROR_UNKNOWN;
695         }
696
697         return retCode;
698     });
699 }
700
701 ManagerShPtr Manager::create() {
702     try {
703         return std::make_shared<ManagerImpl>();
704     } catch (const std::bad_alloc &) {
705         LogDebug("Bad alloc was caught during ManagerImpl creation.");
706     } catch (...) {
707         LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
708     }
709     return ManagerShPtr();
710 }
711
712 } // namespace CKM