Service denies attempt to add data using different label.
[platform/core/security/key-manager.git] / src / manager / client / client-manager-impl.cpp
1 /* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
2  *
3  *  Licensed under the Apache License, Version 2.0 (the "License");
4  *  you may not use this file except in compliance with the License.
5  *  You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  *  Unless required by applicable law or agreed to in writing, software
10  *  distributed under the License is distributed on an "AS IS" BASIS,
11  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  *  See the License for the specific language governing permissions and
13  *  limitations under the License
14  *
15  *
16  * @file        client-manager-impl.cpp
17  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
18  * @version     1.0
19  * @brief       Manager implementation.
20  */
21 #include <openssl/evp.h>
22
23 #include <dpl/serialization.h>
24 #include <dpl/log/log.h>
25
26 #include <client-manager-impl.h>
27 #include <client-common.h>
28 #include <message-buffer.h>
29 #include <protocols.h>
30 #include <key-impl.h>
31 #include <certificate-impl.h>
32
33 namespace {
34
35 void clientInitialize(void) {
36     OpenSSL_add_all_ciphers();
37     OpenSSL_add_all_algorithms();
38     OpenSSL_add_all_digests();
39 }
40
41 } // namespace anonymous
42
43 namespace CKM {
44
45 bool ManagerImpl::s_isInit = false;
46
47 ManagerImpl::ManagerImpl()
48   : m_counter(0), 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         AliasSupport helper(alias);
72         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
73                                              m_counter,
74                                              static_cast<int>(dataType),
75                                              helper.getName(),
76                                              helper.getLabel(),
77                                              rawData,
78                                              PolicySerializable(policy));
79
80         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
81         if (CKM_API_SUCCESS != retCode)
82             return retCode;
83
84         int command;
85         int counter;
86         int opType;
87         recv.Deserialize(command, counter, retCode, opType);
88
89         if (counter != m_counter) {
90             return CKM_API_ERROR_UNKNOWN;
91         }
92
93         return retCode;
94     });
95 }
96
97 int ManagerImpl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) {
98     if (key.get() == NULL)
99         return CKM_API_ERROR_INPUT_PARAM;
100     return saveBinaryData(alias, toDBDataType(key->getType()), key->getDER(), policy);
101 }
102
103 int ManagerImpl::saveCertificate(
104     const Alias &alias,
105     const CertificateShPtr &cert,
106     const Policy &policy)
107 {
108     if (cert.get() == NULL)
109         return CKM_API_ERROR_INPUT_PARAM;
110     return saveBinaryData(alias, DBDataType::CERTIFICATE, cert->getDER(), policy);
111 }
112
113 int ManagerImpl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) {
114     if (!policy.extractable)
115         return CKM_API_ERROR_INPUT_PARAM;
116     return saveBinaryData(alias, DBDataType::BINARY_DATA, rawData, policy);
117 }
118
119 int ManagerImpl::removeBinaryData(const Alias &alias, DBDataType dataType)
120 {
121     return try_catch([&] {
122         if (alias.empty())
123             return CKM_API_ERROR_INPUT_PARAM;
124
125         MessageBuffer recv;
126         AliasSupport helper(alias);
127         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
128                                              m_counter,
129                                              static_cast<int>(dataType),
130                                              helper.getName(),
131                                              helper.getLabel());
132
133         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
134         if (CKM_API_SUCCESS != retCode)
135             return retCode;
136
137         int command;
138         int counter;
139         int opType;
140         recv.Deserialize(command, counter, retCode, opType);
141
142         if (counter != m_counter) {
143             return CKM_API_ERROR_UNKNOWN;
144         }
145
146         return retCode;
147     });
148 }
149
150 int ManagerImpl::removeKey(const Alias &alias) {
151     return removeBinaryData(alias, DBDataType::KEY_RSA_PUBLIC);
152 }
153
154 int ManagerImpl::removeCertificate(const Alias &alias) {
155     return removeBinaryData(alias, DBDataType::CERTIFICATE);
156 }
157
158 int ManagerImpl::removeData(const Alias &alias) {
159     return removeBinaryData(alias, DBDataType::BINARY_DATA);
160 }
161
162 int ManagerImpl::getBinaryData(
163     const Alias &alias,
164     DBDataType sendDataType,
165     const Password &password,
166     DBDataType &recvDataType,
167     RawBuffer &rawData)
168 {
169     return try_catch([&] {
170         if (alias.empty())
171             return CKM_API_ERROR_INPUT_PARAM;
172
173         MessageBuffer recv;
174         AliasSupport helper(alias);
175         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
176                                              m_counter,
177                                              static_cast<int>(sendDataType),
178                                              helper.getName(),
179                                              helper.getLabel(),
180                                              password);
181
182         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
183         if (CKM_API_SUCCESS != retCode)
184             return retCode;
185
186         int command;
187         int counter;
188         int tmpDataType;
189         recv.Deserialize(command, counter, retCode, tmpDataType, rawData);
190         recvDataType = static_cast<DBDataType>(tmpDataType);
191
192         if (counter != m_counter) {
193             return CKM_API_ERROR_UNKNOWN;
194         }
195
196         return retCode;
197     });
198 }
199
200 int ManagerImpl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) {
201     DBDataType recvDataType;
202     RawBuffer rawData;
203
204     int retCode = getBinaryData(
205         alias,
206         DBDataType::KEY_RSA_PUBLIC,
207         password,
208         recvDataType,
209         rawData);
210
211     if (retCode != CKM_API_SUCCESS)
212         return retCode;
213
214     KeyShPtr keyParsed(new KeyImpl(rawData));
215
216     if (keyParsed->empty()) {
217         LogDebug("Key empty - failed to parse!");
218         return CKM_API_ERROR_BAD_RESPONSE;
219     }
220
221     key = keyParsed;
222
223     return CKM_API_SUCCESS;
224 }
225
226 int ManagerImpl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert)
227 {
228     DBDataType recvDataType = DBDataType::CERTIFICATE;
229     RawBuffer rawData;
230
231     int retCode = getBinaryData(
232         alias,
233         DBDataType::CERTIFICATE,
234         password,
235         recvDataType,
236         rawData);
237
238     if (retCode != CKM_API_SUCCESS)
239         return retCode;
240
241     if (recvDataType != DBDataType::CERTIFICATE)
242         return CKM_API_ERROR_BAD_RESPONSE;
243
244     CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER));
245
246     if (certParsed->empty())
247         return CKM_API_ERROR_BAD_RESPONSE;
248
249     cert = certParsed;
250
251     return CKM_API_SUCCESS;
252 }
253
254 int ManagerImpl::getData(const Alias &alias, const Password &password, RawBuffer &rawData)
255 {
256     DBDataType recvDataType = DBDataType::BINARY_DATA;
257
258     int retCode = getBinaryData(
259         alias,
260         DBDataType::BINARY_DATA,
261         password,
262         recvDataType,
263         rawData);
264
265     if (retCode != CKM_API_SUCCESS)
266         return retCode;
267
268     if (recvDataType != DBDataType::BINARY_DATA)
269         return CKM_API_ERROR_BAD_RESPONSE;
270
271     return CKM_API_SUCCESS;
272 }
273
274 int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &aliasVector)
275 {
276     return try_catch([&] {
277
278         MessageBuffer recv;
279         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
280                                              m_counter,
281                                              static_cast<int>(dataType));
282
283         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
284         if (CKM_API_SUCCESS != retCode)
285             return retCode;
286
287         int command;
288         int counter;
289         int tmpDataType;
290         LabelNameVector labelNameVector;
291         recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector);
292         if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != m_counter)) {
293             return CKM_API_ERROR_UNKNOWN;
294         }
295
296         for(const auto &it : labelNameVector)
297             aliasVector.push_back( AliasSupport::merge(it.first, it.second) );
298
299         return retCode;
300     });
301 }
302
303 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
304     // in fact datatype has no meaning here - if not certificate or binary data
305     // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST
306     return getBinaryDataAliasVector(DBDataType::DB_KEY_LAST, aliasVector);
307 }
308
309 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
310     return getBinaryDataAliasVector(DBDataType::CERTIFICATE, aliasVector);
311 }
312
313 int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
314     return getBinaryDataAliasVector(DBDataType::BINARY_DATA, aliasVector);
315 }
316
317 int ManagerImpl::createKeyPairRSA(
318     const int size,
319     const Alias &privateKeyAlias,
320     const Alias &publicKeyAlias,
321     const Policy &policyPrivateKey,
322     const Policy &policyPublicKey)
323 {
324     return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
325 }
326
327 int ManagerImpl::createKeyPairDSA(
328     const int size,
329     const Alias &privateKeyAlias,
330     const Alias &publicKeyAlias,
331     const Policy &policyPrivateKey,
332     const Policy &policyPublicKey)
333 {
334     return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
335 }
336
337 int ManagerImpl::createKeyPairECDSA(
338     ElipticCurve type,
339     const Alias &privateKeyAlias,
340     const Alias &publicKeyAlias,
341     const Policy &policyPrivateKey,
342     const Policy &policyPublicKey)
343 {
344     return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
345 }
346
347 int ManagerImpl::createKeyPair(
348     const KeyType key_type,
349     const int     additional_param,
350     const Alias  &privateKeyAlias,
351     const Alias  &publicKeyAlias,
352     const Policy &policyPrivateKey,
353     const Policy &policyPublicKey)
354 {
355     // input type check
356     LogicCommand cmd_type;
357     switch(key_type)
358     {
359         case KeyType::KEY_RSA_PUBLIC:
360         case KeyType::KEY_RSA_PRIVATE:
361             cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
362             break;
363
364         case KeyType::KEY_DSA_PUBLIC:
365         case KeyType::KEY_DSA_PRIVATE:
366             cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
367             break;
368
369         case KeyType::KEY_ECDSA_PUBLIC:
370         case KeyType::KEY_ECDSA_PRIVATE:
371             cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
372             break;
373
374         default:
375             return CKM_API_ERROR_INPUT_PARAM;
376     }
377
378     // proceed with sending request
379     m_counter++;
380     int my_counter = m_counter;
381     return try_catch([&] {
382
383         MessageBuffer recv;
384         AliasSupport privateHelper(privateKeyAlias);
385         AliasSupport publicHelper(publicKeyAlias);
386         auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
387                                              my_counter,
388                                              static_cast<int>(additional_param),
389                                              PolicySerializable(policyPrivateKey),
390                                              PolicySerializable(policyPublicKey),
391                                              privateHelper.getName(),
392                                              privateHelper.getLabel(),
393                                              publicHelper.getName(),
394                                              publicHelper.getLabel());
395
396         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
397         if (CKM_API_SUCCESS != retCode)
398             return retCode;
399
400         int command;
401         int counter;
402         recv.Deserialize(command, counter, retCode);
403         if (counter != my_counter) {
404             return CKM_API_ERROR_UNKNOWN;
405         }
406
407         return retCode;
408     });
409 }
410
411
412 template <class T>
413 int getCertChain(
414     LogicCommand command,
415     int counter,
416     const CertificateShPtr &certificate,
417     const T &sendData,
418     CertificateShPtrVector &certificateChainVector,
419     ServiceConnection & service_connection)
420 {
421     return try_catch([&] {
422
423         MessageBuffer recv;
424         auto send = MessageBuffer::Serialize(static_cast<int>(command),
425                                              counter,
426                                              certificate->getDER(),
427                                              sendData);
428
429         int retCode = service_connection.processRequest(send.Pop(), recv);
430         if (CKM_API_SUCCESS != retCode)
431             return retCode;
432
433         int retCommand;
434         int retCounter;
435         RawBufferVector rawBufferVector;
436         recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
437
438         if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
439             return CKM_API_ERROR_UNKNOWN;
440         }
441
442         if (retCode != CKM_API_SUCCESS) {
443             return retCode;
444         }
445
446         for (auto &e: rawBufferVector) {
447             CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
448             if (cert->empty())
449                 return CKM_API_ERROR_BAD_RESPONSE;
450             certificateChainVector.push_back(cert);
451         }
452
453         return retCode;
454     });
455 }
456
457
458 int ManagerImpl::getCertificateChain(
459     const CertificateShPtr &certificate,
460     const CertificateShPtrVector &untrustedCertificates,
461     CertificateShPtrVector &certificateChainVector)
462 {
463     RawBufferVector rawBufferVector;
464
465     for (auto &e: untrustedCertificates) {
466         rawBufferVector.push_back(e->getDER());
467     }
468
469     return getCertChain(
470         LogicCommand::GET_CHAIN_CERT,
471         ++m_counter,
472         certificate,
473         rawBufferVector,
474         certificateChainVector,
475         m_storageConnection);
476 }
477
478 int ManagerImpl::getCertificateChain(
479     const CertificateShPtr &certificate,
480     const AliasVector &untrustedCertificates,
481     CertificateShPtrVector &certificateChainVector)
482 {
483     LabelNameVector untrusted_certs;
484     for (auto &e: untrustedCertificates) {
485         AliasSupport helper(e);
486         untrusted_certs.push_back(std::make_pair(helper.getLabel(), helper.getName()));
487     }
488
489     return getCertChain(
490         LogicCommand::GET_CHAIN_ALIAS,
491         ++m_counter,
492         certificate,
493         untrusted_certs,
494         certificateChainVector,
495         m_storageConnection);
496 }
497
498 int ManagerImpl::createSignature(
499     const Alias &privateKeyAlias,
500     const Password &password,           // password for private_key
501     const RawBuffer &message,
502     const HashAlgorithm hash,
503     const RSAPaddingAlgorithm padding,
504     RawBuffer &signature)
505 {
506     m_counter++;
507     int my_counter = m_counter;
508     return try_catch([&] {
509
510         MessageBuffer recv;
511         AliasSupport helper(privateKeyAlias);
512         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
513                                              my_counter,
514                                              helper.getName(),
515                                              helper.getLabel(),
516                                              password,
517                                              message,
518                                              static_cast<int>(hash),
519                                              static_cast<int>(padding));
520
521         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
522         if (CKM_API_SUCCESS != retCode)
523             return retCode;
524
525         int command;
526         int counter;
527         recv.Deserialize(command, counter, retCode, signature);
528
529         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
530             || (counter != my_counter))
531         {
532             return CKM_API_ERROR_UNKNOWN;
533         }
534
535         return retCode;
536     });
537 }
538
539 int ManagerImpl::verifySignature(
540     const Alias &publicKeyOrCertAlias,
541     const Password &password,           // password for public_key (optional)
542     const RawBuffer &message,
543     const RawBuffer &signature,
544     const HashAlgorithm hash,
545     const RSAPaddingAlgorithm padding)
546 {
547     m_counter++;
548     int my_counter = m_counter;
549     return try_catch([&] {
550
551         MessageBuffer recv;
552         AliasSupport helper(publicKeyOrCertAlias);
553         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
554                                              my_counter,
555                                              helper.getName(),
556                                              helper.getLabel(),
557                                              password,
558                                              message,
559                                              signature,
560                                              static_cast<int>(hash),
561                                              static_cast<int>(padding));
562
563         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
564         if (CKM_API_SUCCESS != retCode)
565             return retCode;
566
567         int command;
568         int counter;
569         recv.Deserialize(command, counter, retCode);
570
571         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
572             || (counter != my_counter))
573         {
574             return CKM_API_ERROR_UNKNOWN;
575         }
576
577         return retCode;
578     });
579 }
580
581 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
582 {
583     return try_catch([&] {
584         int my_counter = ++m_counter;
585         MessageBuffer recv;
586
587         RawBufferVector rawCertChain;
588         for (auto &e: certChain) {
589             rawCertChain.push_back(e->getDER());
590         }
591
592         auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
593
594         int retCode = m_ocspConnection.processRequest(send.Pop(), recv);
595         if (CKM_API_SUCCESS != retCode)
596             return retCode;
597
598         int counter;
599         recv.Deserialize(counter, retCode, ocspStatus);
600
601         if (my_counter != counter) {
602             return CKM_API_ERROR_UNKNOWN;
603         }
604
605         return retCode;
606     });
607 }
608
609 int ManagerImpl::setPermission(const Alias &alias,
610                                  const Label &accessor,
611                                  Permission newPermission)
612 {
613     m_counter++;
614     int my_counter = m_counter;
615     return try_catch([&] {
616         MessageBuffer recv;
617         AliasSupport helper(alias);
618         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
619                                              my_counter,
620                                              helper.getName(),
621                                              helper.getLabel(),
622                                              accessor,
623                                              static_cast<int>(newPermission));
624
625         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
626         if (CKM_API_SUCCESS != retCode)
627             return retCode;
628
629         int command;
630         int counter;
631         recv.Deserialize(command, counter, retCode);
632
633         if (my_counter != counter) {
634             return CKM_API_ERROR_UNKNOWN;
635         }
636
637         return retCode;
638     });
639 }
640
641 ManagerShPtr Manager::create() {
642     try {
643         return std::make_shared<ManagerImpl>();
644     } catch (const std::bad_alloc &) {
645         LogDebug("Bad alloc was caught during ManagerImpl creation.");
646     } catch (...) {
647         LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
648     }
649     return ManagerShPtr();
650 }
651
652 } // namespace CKM