Use AliasSupport in SaveData
[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         auto send = MessageBuffer::Serialize(static_cast<int>(cmd_type),
385                                              my_counter,
386                                              static_cast<int>(additional_param),
387                                              PolicySerializable(policyPrivateKey),
388                                              PolicySerializable(policyPublicKey),
389                                              privateKeyAlias,
390                                              publicKeyAlias);
391
392         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
393         if (CKM_API_SUCCESS != retCode)
394             return retCode;
395
396         int command;
397         int counter;
398         recv.Deserialize(command, counter, retCode);
399         if (counter != my_counter) {
400             return CKM_API_ERROR_UNKNOWN;
401         }
402
403         return retCode;
404     });
405 }
406
407
408 template <class T>
409 int getCertChain(
410     LogicCommand command,
411     int counter,
412     const CertificateShPtr &certificate,
413     const T &sendData,
414     CertificateShPtrVector &certificateChainVector,
415     ServiceConnection & service_connection)
416 {
417     return try_catch([&] {
418
419         MessageBuffer recv;
420         auto send = MessageBuffer::Serialize(static_cast<int>(command),
421                                              counter,
422                                              certificate->getDER(),
423                                              sendData);
424
425         int retCode = service_connection.processRequest(send.Pop(), recv);
426         if (CKM_API_SUCCESS != retCode)
427             return retCode;
428
429         int retCommand;
430         int retCounter;
431         RawBufferVector rawBufferVector;
432         recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector);
433
434         if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
435             return CKM_API_ERROR_UNKNOWN;
436         }
437
438         if (retCode != CKM_API_SUCCESS) {
439             return retCode;
440         }
441
442         for (auto &e: rawBufferVector) {
443             CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER));
444             if (cert->empty())
445                 return CKM_API_ERROR_BAD_RESPONSE;
446             certificateChainVector.push_back(cert);
447         }
448
449         return retCode;
450     });
451 }
452
453
454 int ManagerImpl::getCertificateChain(
455     const CertificateShPtr &certificate,
456     const CertificateShPtrVector &untrustedCertificates,
457     CertificateShPtrVector &certificateChainVector)
458 {
459     RawBufferVector rawBufferVector;
460
461     for (auto &e: untrustedCertificates) {
462         rawBufferVector.push_back(e->getDER());
463     }
464
465     return getCertChain(
466         LogicCommand::GET_CHAIN_CERT,
467         ++m_counter,
468         certificate,
469         rawBufferVector,
470         certificateChainVector,
471         m_storageConnection);
472 }
473
474 int ManagerImpl::getCertificateChain(
475     const CertificateShPtr &certificate,
476     const AliasVector &untrustedCertificates,
477     CertificateShPtrVector &certificateChainVector)
478 {
479     LabelNameVector untrusted_certs;
480     for (auto &e: untrustedCertificates) {
481         AliasSupport helper(e);
482         untrusted_certs.push_back(std::make_pair(helper.getLabel(), helper.getName()));
483     }
484
485     return getCertChain(
486         LogicCommand::GET_CHAIN_ALIAS,
487         ++m_counter,
488         certificate,
489         untrusted_certs,
490         certificateChainVector,
491         m_storageConnection);
492 }
493
494 int ManagerImpl::createSignature(
495     const Alias &privateKeyAlias,
496     const Password &password,           // password for private_key
497     const RawBuffer &message,
498     const HashAlgorithm hash,
499     const RSAPaddingAlgorithm padding,
500     RawBuffer &signature)
501 {
502     m_counter++;
503     int my_counter = m_counter;
504     return try_catch([&] {
505
506         MessageBuffer recv;
507         AliasSupport helper(privateKeyAlias);
508         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
509                                              my_counter,
510                                              helper.getName(),
511                                              helper.getLabel(),
512                                              password,
513                                              message,
514                                              static_cast<int>(hash),
515                                              static_cast<int>(padding));
516
517         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
518         if (CKM_API_SUCCESS != retCode)
519             return retCode;
520
521         int command;
522         int counter;
523         recv.Deserialize(command, counter, retCode, signature);
524
525         if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE))
526             || (counter != my_counter))
527         {
528             return CKM_API_ERROR_UNKNOWN;
529         }
530
531         return retCode;
532     });
533 }
534
535 int ManagerImpl::verifySignature(
536     const Alias &publicKeyOrCertAlias,
537     const Password &password,           // password for public_key (optional)
538     const RawBuffer &message,
539     const RawBuffer &signature,
540     const HashAlgorithm hash,
541     const RSAPaddingAlgorithm padding)
542 {
543     m_counter++;
544     int my_counter = m_counter;
545     return try_catch([&] {
546
547         MessageBuffer recv;
548         AliasSupport helper(publicKeyOrCertAlias);
549         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
550                                              my_counter,
551                                              helper.getName(),
552                                              helper.getLabel(),
553                                              password,
554                                              message,
555                                              signature,
556                                              static_cast<int>(hash),
557                                              static_cast<int>(padding));
558
559         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
560         if (CKM_API_SUCCESS != retCode)
561             return retCode;
562
563         int command;
564         int counter;
565         recv.Deserialize(command, counter, retCode);
566
567         if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE))
568             || (counter != my_counter))
569         {
570             return CKM_API_ERROR_UNKNOWN;
571         }
572
573         return retCode;
574     });
575 }
576
577 int ManagerImpl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus)
578 {
579     return try_catch([&] {
580         int my_counter = ++m_counter;
581         MessageBuffer recv;
582
583         RawBufferVector rawCertChain;
584         for (auto &e: certChain) {
585             rawCertChain.push_back(e->getDER());
586         }
587
588         auto send = MessageBuffer::Serialize(my_counter, rawCertChain);
589
590         int retCode = m_ocspConnection.processRequest(send.Pop(), recv);
591         if (CKM_API_SUCCESS != retCode)
592             return retCode;
593
594         int counter;
595         recv.Deserialize(counter, retCode, ocspStatus);
596
597         if (my_counter != counter) {
598             return CKM_API_ERROR_UNKNOWN;
599         }
600
601         return retCode;
602     });
603 }
604
605 int ManagerImpl::setPermission(const Alias &alias,
606                                  const Label &accessor,
607                                  Permission newPermission)
608 {
609     m_counter++;
610     int my_counter = m_counter;
611     return try_catch([&] {
612         MessageBuffer recv;
613         auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION),
614                                              my_counter,
615                                              alias,
616                                              accessor,
617                                              static_cast<int>(newPermission));
618
619         int retCode = m_storageConnection.processRequest(send.Pop(), recv);
620         if (CKM_API_SUCCESS != retCode)
621             return retCode;
622
623         int command;
624         int counter;
625         recv.Deserialize(command, counter, retCode);
626
627         if (my_counter != counter) {
628             return CKM_API_ERROR_UNKNOWN;
629         }
630
631         return retCode;
632     });
633 }
634
635 ManagerShPtr Manager::create() {
636     try {
637         return std::make_shared<ManagerImpl>();
638     } catch (const std::bad_alloc &) {
639         LogDebug("Bad alloc was caught during ManagerImpl creation.");
640     } catch (...) {
641         LogError("Critical error: Unknown exception was caught during ManagerImpl creation!");
642     }
643     return ManagerShPtr();
644 }
645
646 } // namespace CKM