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