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