Typedef password type
[platform/core/security/key-manager.git] / src / manager / service / ckm-logic.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  *
16  *
17  * @file        ckm-logic.cpp
18  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version     1.0
20  * @brief       Sample service implementation.
21  */
22 #include <dpl/serialization.h>
23 #include <dpl/log/log.h>
24 #include <ckm/ckm-error.h>
25 #include <ckm/ckm-type.h>
26 #include <key-provider.h>
27 #include <file-system.h>
28 #include <CryptoService.h>
29 #include <ckm-logic.h>
30 #include <generic-key.h>
31
32 namespace {
33 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
34 } // anonymous namespace
35
36 namespace CKM {
37
38 CKMLogic::CKMLogic()
39 {
40     int retCode = FileSystem::init();
41     // TODO what can I do when init went wrong? exit(-1) ??
42     if (retCode) {
43         LogError("Fatal error in FileSystem::init()");
44     }
45
46     if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
47         LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
48     }
49 }
50
51 CKMLogic::~CKMLogic(){}
52
53 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
54     // TODO try catch for all errors that should be supported by error code
55     int retCode = CKM_API_SUCCESS;
56
57     try {
58         if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
59             auto &handle = m_userDataMap[user];
60             FileSystem fs(user);
61             auto wrappedDomainKEK = fs.getDomainKEK();
62
63             if (wrappedDomainKEK.empty()) {
64                 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
65                 fs.saveDomainKEK(wrappedDomainKEK);
66             }
67
68             handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
69
70             RawBuffer key = handle.keyProvider.getPureDomainKEK();
71             handle.database = DBCrypto(fs.getDBPath(), key);
72             handle.crypto = CryptoLogic();
73             // TODO wipe key
74         }
75     } catch (const KeyProvider::Exception::PassWordError &e) {
76         LogError("Incorrect Password " << e.GetMessage());
77         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
78     } catch (const KeyProvider::Exception::Base &e) {
79         LogError("Error in KeyProvider " << e.GetMessage());
80         retCode = CKM_API_ERROR_SERVER_ERROR;
81     } catch (const CryptoLogic::Exception::Base &e) {
82         LogError("CryptoLogic error: " << e.GetMessage());
83         retCode = CKM_API_ERROR_SERVER_ERROR;
84     } catch (const CKM::Exception &e) {
85         LogError("CKM::Exception: " << e.GetMessage());
86         retCode = CKM_API_ERROR_SERVER_ERROR;
87     }
88
89     MessageBuffer response;
90     Serialization::Serialize(response, retCode);
91     return response.Pop();
92 }
93
94 RawBuffer CKMLogic::lockUserKey(uid_t user) {
95     int retCode = CKM_API_SUCCESS;
96     // TODO try catch for all errors that should be supported by error code
97     m_userDataMap.erase(user);
98
99     MessageBuffer response;
100     Serialization::Serialize(response, retCode);
101     return response.Pop();
102 }
103
104 RawBuffer CKMLogic::removeUserData(uid_t user) {
105     int retCode = CKM_API_SUCCESS;
106     // TODO try catch for all errors that should be supported by error code
107     m_userDataMap.erase(user);
108
109     FileSystem fs(user);
110     fs.removeUserData();
111
112     MessageBuffer response;
113     Serialization::Serialize(response, retCode);
114     return response.Pop();
115 }
116
117 RawBuffer CKMLogic::changeUserPassword(
118     uid_t user,
119     const Password &oldPassword,
120     const Password &newPassword)
121 {
122     int retCode = CKM_API_SUCCESS;
123     try {
124         FileSystem fs(user);
125         auto wrappedDomainKEK = fs.getDomainKEK();
126         if (wrappedDomainKEK.empty()) {
127             retCode = CKM_API_ERROR_BAD_REQUEST;
128         } else {
129             wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
130             fs.saveDomainKEK(wrappedDomainKEK);
131         }
132     } catch (const KeyProvider::Exception::PassWordError &e) {
133         LogError("Incorrect Password " << e.GetMessage());
134         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
135     } catch (const KeyProvider::Exception::Base &e) {
136         LogError("Error in KeyProvider " << e.GetMessage());
137         retCode = CKM_API_ERROR_SERVER_ERROR;
138     } catch (const CKM::Exception &e) {
139         LogError("CKM::Exception: " << e.GetMessage());
140         retCode = CKM_API_ERROR_SERVER_ERROR;
141     }
142
143     MessageBuffer response;
144     Serialization::Serialize(response, retCode);
145     return response.Pop();
146 }
147
148 RawBuffer CKMLogic::resetUserPassword(
149     uid_t user,
150     const Password &newPassword)
151 {
152     int retCode = CKM_API_SUCCESS;
153     // TODO try-catch
154     if (0 == m_userDataMap.count(user)) {
155         retCode = CKM_API_ERROR_BAD_REQUEST;
156     } else {
157         auto &handler = m_userDataMap[user];
158         FileSystem fs(user);
159         fs.saveDomainKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
160     }
161
162     MessageBuffer response;
163     Serialization::Serialize(response, retCode);
164     return response.Pop();
165 }
166
167 int CKMLogic::saveDataHelper(
168     Credentials &cred,
169     DBDataType dataType,
170     const Alias &alias,
171     const RawBuffer &key,
172     const PolicySerializable &policy)
173 {
174     if (0 == m_userDataMap.count(cred.uid))
175         return CKM_API_ERROR_DB_LOCKED;
176
177     DBRow row = { alias, cred.smackLabel, policy.restricted,
178          policy.extractable, dataType, DBCMAlgType::NONE,
179          0, RawBuffer(), static_cast<int>(key.size()), key };
180
181     auto &handler = m_userDataMap[cred.uid];
182     DBCrypto::Transaction transaction(&handler.database);
183     if (!handler.crypto.haveKey(cred.smackLabel)) {
184         RawBuffer key;
185         auto key_optional = handler.database.getKey(cred.smackLabel);
186         if(!key_optional) {
187             LogDebug("No Key in database found. Generating new one for label: "
188                     << cred.smackLabel);
189             key = handler.keyProvider.generateDEK(cred.smackLabel);
190             handler.database.saveKey(cred.smackLabel, key);
191         } else {
192             LogDebug("Key from DB");
193             key = *key_optional;
194         }
195
196         key = handler.keyProvider.getPureDEK(key);
197         handler.crypto.pushKey(cred.smackLabel, key);
198     }
199     handler.crypto.encryptRow(policy.password, row);
200     handler.database.saveDBRow(row);
201     transaction.commit();
202     return CKM_API_SUCCESS;
203 }
204
205 RawBuffer CKMLogic::saveData(
206     Credentials &cred,
207     int commandId,
208     DBDataType dataType,
209     const Alias &alias,
210     const RawBuffer &key,
211     const PolicySerializable &policy)
212 {
213     int retCode = CKM_API_SUCCESS;
214     try {
215         retCode = saveDataHelper(cred, dataType, alias, key, policy);
216         LogDebug("SaveDataHelper returned: " << retCode);
217     } catch (const KeyProvider::Exception::Base &e) {
218         LogError("KeyProvider failed with message: " << e.GetMessage());
219         retCode = CKM_API_ERROR_SERVER_ERROR;
220     } catch (const CryptoLogic::Exception::Base &e) {
221         LogError("CryptoLogic failed with message: " << e.GetMessage());
222         retCode = CKM_API_ERROR_SERVER_ERROR;
223     } catch (const DBCrypto::Exception::InternalError &e) {
224         LogError("DBCrypto failed with message: " << e.GetMessage());
225         retCode = CKM_API_ERROR_DB_ERROR;
226     } catch (const DBCrypto::Exception::AliasExists &e) {
227         LogError("DBCrypto couldn't save duplicate alias");
228         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
229     } catch (const DBCrypto::Exception::TransactionError &e) {
230         LogError("DBCrypto transaction failed with message " << e.GetMessage());
231         retCode = CKM_API_ERROR_DB_ERROR;
232     }
233
234     MessageBuffer response;
235     Serialization::Serialize(response, static_cast<int>(LogicCommand::SAVE));
236     Serialization::Serialize(response, commandId);
237     Serialization::Serialize(response, retCode);
238     Serialization::Serialize(response, static_cast<int>(dataType));
239
240     return response.Pop();
241 }
242
243 RawBuffer CKMLogic::removeData(
244     Credentials &cred,
245     int commandId,
246     DBDataType dataType,
247     const Alias &alias)
248 {
249     int retCode = CKM_API_SUCCESS;
250
251     if (0 < m_userDataMap.count(cred.uid)) {
252         Try {
253             auto erased = m_userDataMap[cred.uid].database.deleteDBRow(alias, cred.smackLabel);
254             // check if the data existed or not
255             if(!erased) {
256                 LogError("No row for given alias and label");
257                 retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
258             }
259         } Catch (CKM::Exception) {
260             LogError("Error in deleting row!");
261             retCode = CKM_API_ERROR_DB_ERROR;
262         }
263     } else {
264         retCode = CKM_API_ERROR_DB_LOCKED;
265     }
266
267     MessageBuffer response;
268     Serialization::Serialize(response, static_cast<int>(LogicCommand::REMOVE));
269     Serialization::Serialize(response, commandId);
270     Serialization::Serialize(response, retCode);
271     Serialization::Serialize(response, static_cast<int>(dataType));
272
273     return response.Pop();
274 }
275
276 int CKMLogic::getDataHelper(
277     Credentials &cred,
278     DBDataType dataType,
279     const Alias &alias,
280     const Password &password,
281     DBRow &row)
282 {
283
284     if (0 == m_userDataMap.count(cred.uid))
285         return CKM_API_ERROR_DB_LOCKED;
286
287     auto &handler = m_userDataMap[cred.uid];
288
289     DBCrypto::DBRowOptional row_optional;
290     if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
291         row_optional = handler.database.getDBRow(alias, cred.smackLabel, dataType);
292     } else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST))
293             && (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
294     {
295         row_optional = handler.database.getKeyDBRow(alias, cred.smackLabel);
296     } else {
297         LogError("Unknown type of requested data" << (int)dataType);
298         return CKM_API_ERROR_BAD_REQUEST;
299     }
300     if(!row_optional) {
301         LogError("No row for given alias, label and type");
302         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
303     } else {
304         row = *row_optional;
305     }
306
307     if (!handler.crypto.haveKey(row.smackLabel)) {
308         RawBuffer key;
309         auto key_optional = handler.database.getKey(row.smackLabel);
310         if(!key_optional) {
311             LogError("No key for given label in database");
312             return CKM_API_ERROR_DB_ERROR;
313         }
314         key = *key_optional;
315         key = handler.keyProvider.getPureDEK(key);
316         handler.crypto.pushKey(cred.smackLabel, key);
317     }
318     handler.crypto.decryptRow(password, row);
319
320     return CKM_API_SUCCESS;
321 }
322
323 RawBuffer CKMLogic::getData(
324     Credentials &cred,
325     int commandId,
326     DBDataType dataType,
327     const Alias &alias,
328     const Password &password)
329 {
330     int retCode = CKM_API_SUCCESS;
331     DBRow row;
332
333     try {
334         retCode = getDataHelper(cred, dataType, alias, password, row);
335     } catch (const KeyProvider::Exception::Base &e) {
336         LogError("KeyProvider failed with error: " << e.GetMessage());
337         retCode = CKM_API_ERROR_SERVER_ERROR;
338     } catch (const CryptoLogic::Exception::Base &e) {
339         LogError("CryptoLogic failed with message: " << e.GetMessage());
340         retCode = CKM_API_ERROR_SERVER_ERROR;
341     } catch (const DBCrypto::Exception::Base &e) {
342         LogError("DBCrypto failed with message: " << e.GetMessage());
343         retCode = CKM_API_ERROR_DB_ERROR;
344     }
345
346     if (CKM_API_SUCCESS != retCode) {
347         row.data.clear();
348         row.dataType = dataType;
349     }
350
351     MessageBuffer response;
352     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
353     Serialization::Serialize(response, commandId);
354     Serialization::Serialize(response, retCode);
355     Serialization::Serialize(response, static_cast<int>(row.dataType));
356     Serialization::Serialize(response, row.data);
357     return response.Pop();
358 }
359
360 RawBuffer CKMLogic::getDataList(
361     Credentials &cred,
362     int commandId,
363     DBDataType dataType)
364 {
365     int retCode = CKM_API_SUCCESS;
366     AliasVector aliasVector;
367
368     if (0 < m_userDataMap.count(cred.uid)) {
369         auto &handler = m_userDataMap[cred.uid];
370         Try {
371             if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
372                 handler.database.getAliases(dataType, cred.smackLabel, aliasVector);
373             } else {
374                 handler.database.getKeyAliases(cred.smackLabel, aliasVector);
375             }
376         } Catch (CKM::Exception) {
377             LogError("Failed to get aliases");
378             retCode = CKM_API_ERROR_DB_ERROR;
379         }
380     } else {
381         retCode = CKM_API_ERROR_DB_LOCKED;
382     }
383
384     MessageBuffer response;
385     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_LIST));
386     Serialization::Serialize(response, commandId);
387     Serialization::Serialize(response, retCode);
388     Serialization::Serialize(response, static_cast<int>(dataType));
389     Serialization::Serialize(response, aliasVector);
390     return response.Pop();
391 }
392
393 int CKMLogic::createKeyPairRSAHelper(
394     Credentials &cred,
395     int size,
396     const Alias &aliasPrivate,
397     const Alias &aliasPublic,
398     const PolicySerializable &policyPrivate,
399     const PolicySerializable &policyPublic)
400 {
401     if (0 >= m_userDataMap.count(cred.uid))
402         return CKM_API_ERROR_DB_LOCKED;
403
404     auto &handler = m_userDataMap[cred.uid];
405     GenericKey prv, pub;
406     int retCode;
407
408     if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
409         (retCode = CryptoService::createKeyPairRSA(size, prv, pub)))
410     {
411         LogDebug("CryptoService error with code: " << retCode);
412         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
413     }
414
415     DBCrypto::Transaction transaction(&handler.database);
416     retCode = saveDataHelper(cred,
417                             toDBDataType(prv.getType()),
418                             aliasPrivate,
419                             prv.getDER(),
420                             policyPrivate);
421
422     if (CKM_API_SUCCESS != retCode)
423         return retCode;
424
425     retCode = saveDataHelper(cred,
426                             toDBDataType(pub.getType()),
427                             aliasPublic,
428                             pub.getDER(),
429                             policyPublic);
430
431     if (CKM_API_SUCCESS != retCode)
432         return retCode;
433
434     transaction.commit();
435
436     return retCode;
437 }
438
439 RawBuffer CKMLogic::createKeyPairRSA(
440     Credentials &cred,
441     int commandId,
442     int size,
443     const Alias &aliasPrivate,
444     const Alias &aliasPublic,
445     const PolicySerializable &policyPrivate,
446     const PolicySerializable &policyPublic)
447 {
448     int retCode = CKM_API_SUCCESS;
449
450     try {
451         retCode = createKeyPairRSAHelper(
452                         cred,
453                         size,
454                         aliasPrivate,
455                         aliasPublic,
456                         policyPrivate,
457                         policyPublic);
458
459     } catch (DBCrypto::Exception::AliasExists &e) {
460         LogDebug("DBCrypto error: alias exists: " << e.GetMessage());
461         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
462     } catch (DBCrypto::Exception::TransactionError &e) {
463         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
464         retCode = CKM_API_ERROR_DB_ERROR;
465     } catch (CKM::CryptoLogic::Exception::Base &e) {
466         LogDebug("CryptoLogic error: " << e.GetMessage());
467         retCode = CKM_API_ERROR_SERVER_ERROR;
468     } catch (DBCrypto::Exception::InternalError &e) {
469         LogDebug("DBCrypto internal error: " << e.GetMessage());
470         retCode = CKM_API_ERROR_DB_ERROR;
471     }
472
473     MessageBuffer response;
474     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
475     Serialization::Serialize(response, commandId);
476     Serialization::Serialize(response, retCode);
477
478     return response.Pop();
479 }
480
481 int CKMLogic::createKeyPairECDSAHelper(
482     Credentials &cred,
483     int type,
484     const Alias &aliasPrivate,
485     const Alias &aliasPublic,
486     const PolicySerializable &policyPrivate,
487     const PolicySerializable &policyPublic)
488 {
489     if (0 >= m_userDataMap.count(cred.uid))
490         return CKM_API_ERROR_DB_LOCKED;
491
492     auto &handler = m_userDataMap[cred.uid];
493     GenericKey prv, pub;
494     int retCode;
495
496     if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
497         (retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(type), prv, pub)))
498     {
499         LogError("CryptoService failed with code: " << retCode);
500         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
501     }
502
503     DBCrypto::Transaction transaction(&handler.database);
504
505     retCode = saveDataHelper(cred,
506                             toDBDataType(prv.getType()),
507                             aliasPrivate,
508                             prv.getDER(),
509                             policyPrivate);
510
511     if (CKM_API_SUCCESS != retCode)
512         return retCode;
513
514     retCode = saveDataHelper(cred,
515                             toDBDataType(pub.getType()),
516                             aliasPublic,
517                             pub.getDER(),
518                             policyPublic);
519
520     if (CKM_API_SUCCESS != retCode)
521         return retCode;
522
523     transaction.commit();
524
525     return retCode;
526 }
527
528 RawBuffer CKMLogic::createKeyPairECDSA(
529     Credentials &cred,
530     int commandId,
531     int type,
532     const Alias &aliasPrivate,
533     const Alias &aliasPublic,
534     const PolicySerializable &policyPrivate,
535     const PolicySerializable &policyPublic)
536 {
537     int retCode = CKM_API_SUCCESS;
538
539     try {
540         retCode = createKeyPairECDSAHelper(
541                         cred,
542                         type,
543                         aliasPrivate,
544                         aliasPublic,
545                         policyPrivate,
546                         policyPublic);
547     } catch (const DBCrypto::Exception::AliasExists &e) {
548         LogDebug("DBCrypto error: alias exists: " << e.GetMessage());
549         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
550     } catch (const DBCrypto::Exception::TransactionError &e) {
551         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
552         retCode = CKM_API_ERROR_DB_ERROR;
553     } catch (const CKM::CryptoLogic::Exception::Base &e) {
554         LogDebug("CryptoLogic error: " << e.GetMessage());
555         retCode = CKM_API_ERROR_SERVER_ERROR;
556     } catch (const DBCrypto::Exception::InternalError &e) {
557         LogDebug("DBCrypto internal error: " << e.GetMessage());
558         retCode = CKM_API_ERROR_DB_ERROR;
559     }
560
561     MessageBuffer response;
562     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
563     Serialization::Serialize(response, commandId);
564     Serialization::Serialize(response, retCode);
565
566     return response.Pop();
567 }
568
569 RawBuffer CKMLogic::getCertificateChain(
570     Credentials &cred,
571     int commandId,
572     const RawBuffer &certificate,
573     const RawBufferVector &untrustedRawCertVector)
574 {
575     (void)cred;
576
577     CertificateImpl cert(certificate, DataFormat::FORM_DER);
578     CertificateImplVector untrustedCertVector;
579     CertificateImplVector chainVector;
580     RawBufferVector chainRawVector;
581
582     for (auto &e: untrustedRawCertVector)
583         untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
584
585     LogDebug("Cert is empty: " << cert.empty());
586
587     int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
588
589     if (retCode == CKM_API_SUCCESS) {
590         for (auto &e : chainVector)
591             chainRawVector.push_back(e.getDER());
592     }
593
594     MessageBuffer response;
595     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_CERT));
596     Serialization::Serialize(response, commandId);
597     Serialization::Serialize(response, retCode);
598     Serialization::Serialize(response, chainRawVector);
599     return response.Pop();
600 }
601
602 RawBuffer CKMLogic::getCertificateChain(
603     Credentials &cred,
604     int commandId,
605     const RawBuffer &certificate,
606     const AliasVector &aliasVector)
607 {
608     int retCode = CKM_API_SUCCESS;
609     RawBufferVector chainRawVector;
610     try {
611         CertificateImpl cert(certificate, DataFormat::FORM_DER);
612         CertificateImplVector untrustedCertVector;
613         CertificateImplVector chainVector;
614         DBRow row;
615
616         if (cert.empty()) {
617             retCode = CKM_API_ERROR_SERVER_ERROR;
618             goto senderror;
619         }
620
621         for (auto &i: aliasVector) {
622             retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i, Password(), row);
623
624             if (retCode != CKM_API_SUCCESS)
625                 goto senderror;
626
627             untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
628         }
629
630         retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
631
632         if (retCode != CKM_API_SUCCESS)
633             goto senderror;
634
635         for (auto &i: chainVector)
636             chainRawVector.push_back(i.getDER());
637
638     } catch (const CryptoLogic::Exception::Base &e) {
639         LogError("DBCyptorModule failed with message: " << e.GetMessage());
640         retCode = CKM_API_ERROR_SERVER_ERROR;
641     } catch (const DBCrypto::Exception::Base &e) {
642         LogError("DBCrypto failed with message: " << e.GetMessage());
643         retCode = CKM_API_ERROR_DB_ERROR;
644     } catch (...) {
645         LogError("Unknown error.");
646     }
647
648 senderror:
649     MessageBuffer response;
650     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_ALIAS));
651     Serialization::Serialize(response, commandId);
652     Serialization::Serialize(response, retCode);
653     Serialization::Serialize(response, chainRawVector);
654     return response.Pop();
655 }
656
657 RawBuffer CKMLogic::createSignature(
658         Credentials &cred,
659         int commandId,
660         const Alias &privateKeyAlias,
661         const Password &password,           // password for private_key
662         const RawBuffer &message,
663         const HashAlgorithm hash,
664         const RSAPaddingAlgorithm padding)
665 {
666     DBRow row;
667     CryptoService cs;
668     RawBuffer signature;
669
670     int retCode = CKM_API_SUCCESS;
671
672     try {
673         do {
674             retCode = getDataHelper(cred, DBDataType::KEY_RSA_PUBLIC, privateKeyAlias, password, row);
675             if (CKM_API_SUCCESS != retCode) {
676                 LogError("getDataHelper return error");
677                 break;
678             }
679
680             GenericKey keyParsed(row.data, Password());
681             if (keyParsed.empty())
682                 retCode = CKM_API_ERROR_SERVER_ERROR;
683             else
684                 cs.createSignature(keyParsed, message, hash, padding, signature);
685         } while(0);
686     } catch (const KeyProvider::Exception::Base &e) {
687         LogError("KeyProvider failed with message: " << e.GetMessage());
688         retCode = CKM_API_ERROR_SERVER_ERROR;
689     } catch (const CryptoLogic::Exception::Base &e) {
690         LogError("CryptoLogic failed with message: " << e.GetMessage());
691         retCode = CKM_API_ERROR_SERVER_ERROR;
692     } catch (const DBCrypto::Exception::Base &e) {
693         LogError("DBCrypto failed with message: " << e.GetMessage());
694         retCode = CKM_API_ERROR_DB_ERROR;
695     } catch (const CKM::Exception &e) {
696         LogError("Unknown CKM::Exception: " << e.GetMessage());
697         retCode = CKM_API_ERROR_SERVER_ERROR;
698     }
699
700     MessageBuffer response;
701     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_SIGNATURE));
702     Serialization::Serialize(response, commandId);
703     Serialization::Serialize(response, retCode);
704     Serialization::Serialize(response, signature);
705     return response.Pop();
706 }
707
708 RawBuffer CKMLogic::verifySignature(
709         Credentials &cred,
710         int commandId,
711         const Alias &publicKeyOrCertAlias,
712         const Password &password,           // password for public_key (optional)
713         const RawBuffer &message,
714         const RawBuffer &signature,
715         const HashAlgorithm hash,
716         const RSAPaddingAlgorithm padding)
717 {
718     int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
719
720     try {
721         do {
722             CryptoService cs;
723             DBRow row;
724             GenericKey key;
725
726             retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertAlias, password, row);
727
728             if (retCode == CKM_API_SUCCESS) {
729                 key = GenericKey(row.data);
730             } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
731                 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertAlias, password, row);
732                 if (retCode != CKM_API_SUCCESS)
733                     break;
734                 CertificateImpl cert(row.data, DataFormat::FORM_DER);
735                 key = cert.getGenericKey();
736             } else {
737                 break;
738             }
739
740             if (key.empty()) {
741                 retCode = CKM_API_ERROR_SERVER_ERROR;
742                 break;
743             }
744
745             retCode = cs.verifySignature(key, message, signature, hash, padding);
746         } while(0);
747     } catch (const CryptoService::Exception::Crypto_internal &e) {
748         LogError("KeyProvider failed with message: " << e.GetMessage());
749         retCode = CKM_API_ERROR_SERVER_ERROR;
750     } catch (const CryptoService::Exception::opensslError &e) {
751         LogError("KeyProvider failed with message: " << e.GetMessage());
752         retCode = CKM_API_ERROR_SERVER_ERROR;
753     } catch (const KeyProvider::Exception::Base &e) {
754         LogError("KeyProvider failed with error: " << e.GetMessage());
755         retCode = CKM_API_ERROR_SERVER_ERROR;
756     } catch (const CryptoLogic::Exception::Base &e) {
757         LogError("CryptoLogic failed with message: " << e.GetMessage());
758         retCode = CKM_API_ERROR_SERVER_ERROR;
759     } catch (const DBCrypto::Exception::Base &e) {
760         LogError("DBCrypto failed with message: " << e.GetMessage());
761         retCode = CKM_API_ERROR_DB_ERROR;
762     } catch (const CKM::Exception &e) {
763         LogError("Unknown CKM::Exception: " << e.GetMessage());
764         retCode = CKM_API_ERROR_SERVER_ERROR;
765     }
766
767     MessageBuffer response;
768     Serialization::Serialize(response, static_cast<int>(LogicCommand::VERIFY_SIGNATURE));
769     Serialization::Serialize(response, commandId);
770     Serialization::Serialize(response, retCode);
771
772     return response.Pop();
773 }
774 } // namespace CKM
775