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