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