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