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