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