Function verifySignature may take certificate alias now.
[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/key-manager.h>
25 #include <ckm/key-manager-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'), 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         } else {
173             key = *key_optional;
174         }
175
176         key = handler.keyProvider.getPureDEK(key);
177         handler.crypto.pushKey(cred.smackLabel, key);
178         handler.database.saveKey(cred.smackLabel, key);
179     }
180     handler.crypto.encryptRow(policy.password, row);
181     handler.database.saveDBRow(row);
182     transaction.commit();
183     return CKM_API_SUCCESS;
184 }
185
186 RawBuffer CKMLogic::saveData(
187     Credentials &cred,
188     int commandId,
189     DBDataType dataType,
190     const Alias &alias,
191     const RawBuffer &key,
192     const PolicySerializable &policy)
193 {
194     int retCode = CKM_API_SUCCESS;
195     try {
196         retCode = saveDataHelper(cred, dataType, alias, key, policy);
197         LogDebug("SaveDataHelper returned: " << retCode);
198     } catch (const KeyProvider::Exception::Base &e) {
199         LogError("KeyProvider failed with message: " << e.GetMessage());
200         retCode = CKM_API_ERROR_SERVER_ERROR;
201     } catch (const DBCryptoModule::Exception::Base &e) {
202         LogError("DBCryptoModule failed with message: " << e.GetMessage());
203         retCode = CKM_API_ERROR_SERVER_ERROR;
204     } catch (const DBCrypto::Exception::InternalError &e) {
205         LogError("DBCrypto failed with message: " << e.GetMessage());
206         retCode = CKM_API_ERROR_DB_ERROR;
207     } catch (const DBCrypto::Exception::AliasExists &e) {
208         LogError("DBCrypto couldn't save duplicate alias");
209         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
210     } catch (const DBCrypto::Exception::TransactionError &e) {
211         LogError("DBCrypto transaction failed with message " << e.GetMessage());
212         retCode = CKM_API_ERROR_DB_ERROR;
213     }
214
215     MessageBuffer response;
216     Serialization::Serialize(response, static_cast<int>(LogicCommand::SAVE));
217     Serialization::Serialize(response, commandId);
218     Serialization::Serialize(response, retCode);
219     Serialization::Serialize(response, static_cast<int>(dataType));
220
221     return response.Pop();
222 }
223
224 RawBuffer CKMLogic::removeData(
225     Credentials &cred,
226     int commandId,
227     DBDataType dataType,
228     const Alias &alias)
229 {
230     int retCode = CKM_API_SUCCESS;
231
232     if (0 < m_userDataMap.count(cred.uid)) {
233         Try {
234             m_userDataMap[cred.uid].database.deleteDBRow(alias, cred.smackLabel);
235         } Catch (CKM::Exception) {
236             LogError("Error in deleting row!");
237             retCode = CKM_API_ERROR_DB_ERROR;
238         }
239     } else {
240         retCode = CKM_API_ERROR_DB_LOCKED;
241     }
242
243     MessageBuffer response;
244     Serialization::Serialize(response, static_cast<int>(LogicCommand::REMOVE));
245     Serialization::Serialize(response, commandId);
246     Serialization::Serialize(response, retCode);
247     Serialization::Serialize(response, static_cast<int>(dataType));
248
249     return response.Pop();
250 }
251
252 int CKMLogic::getDataHelper(
253     Credentials &cred,
254     DBDataType dataType,
255     const Alias &alias,
256     const std::string &password,
257     DBRow &row)
258 {
259
260     if (0 == m_userDataMap.count(cred.uid))
261         return CKM_API_ERROR_DB_LOCKED;
262
263     auto &handler = m_userDataMap[cred.uid];
264
265     DBCrypto::DBRowOptional row_optional;
266     if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
267         row_optional = handler.database.getDBRow(alias, cred.smackLabel, dataType);
268     } else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST))
269             && (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
270     {
271         row_optional = handler.database.getKeyDBRow(alias, cred.smackLabel);
272     } else {
273         LogError("Unknown type of requested data" << (int)dataType);
274         return CKM_API_ERROR_BAD_REQUEST;
275     }
276     if(!row_optional) {
277         LogError("No row for given alias, label and type");
278         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
279     } else {
280         row = *row_optional;
281     }
282
283     if (!handler.crypto.haveKey(row.smackLabel)) {
284         RawBuffer key;
285         auto key_optional = handler.database.getKey(row.smackLabel);
286         if(!key_optional) {
287             LogError("No key for given label in database");
288             return CKM_API_ERROR_DB_ERROR;
289         }
290         key = *key_optional;
291         key = handler.keyProvider.getPureDEK(key);
292         handler.crypto.pushKey(cred.smackLabel, key);
293     }
294     handler.crypto.decryptRow(password, row);
295
296     return CKM_API_SUCCESS;
297 }
298
299 RawBuffer CKMLogic::getData(
300     Credentials &cred,
301     int commandId,
302     DBDataType dataType,
303     const Alias &alias,
304     const std::string &password)
305 {
306     int retCode = CKM_API_SUCCESS;
307     DBRow row;
308
309     try {
310         retCode = getDataHelper(cred, dataType, alias, password, row);
311     } catch (const KeyProvider::Exception::Base &e) {
312         LogError("KeyProvider failed with error: " << e.GetMessage());
313         retCode = CKM_API_ERROR_SERVER_ERROR;
314     } catch (const DBCryptoModule::Exception::Base &e) {
315         LogError("DBCryptoModule failed with message: " << e.GetMessage());
316         retCode = CKM_API_ERROR_SERVER_ERROR;
317     } catch (const DBCrypto::Exception::Base &e) {
318         LogError("DBCrypto failed with message: " << e.GetMessage());
319         retCode = CKM_API_ERROR_DB_ERROR;
320     }
321
322     if (CKM_API_SUCCESS != retCode) {
323         row.data.clear();
324         row.dataType = dataType;
325     }
326
327     MessageBuffer response;
328     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
329     Serialization::Serialize(response, commandId);
330     Serialization::Serialize(response, retCode);
331     Serialization::Serialize(response, static_cast<int>(row.dataType));
332     Serialization::Serialize(response, row.data);
333     return response.Pop();
334 }
335
336 RawBuffer CKMLogic::getDataList(
337     Credentials &cred,
338     int commandId,
339     DBDataType dataType)
340 {
341     int retCode = CKM_API_SUCCESS;
342     AliasVector aliasVector;
343
344     if (0 < m_userDataMap.count(cred.uid)) {
345         auto &handler = m_userDataMap[cred.uid];
346         Try {
347             if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
348                 handler.database.getAliases(dataType, cred.smackLabel, aliasVector);
349             } else {
350                 handler.database.getKeyAliases(cred.smackLabel, aliasVector);
351             }
352         } Catch (CKM::Exception) {
353             LogError("Failed to get aliases");
354             retCode = CKM_API_ERROR_DB_ERROR;
355         }
356     } else {
357         retCode = CKM_API_ERROR_DB_LOCKED;
358     }
359
360     MessageBuffer response;
361     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_LIST));
362     Serialization::Serialize(response, commandId);
363     Serialization::Serialize(response, retCode);
364     Serialization::Serialize(response, static_cast<int>(dataType));
365     Serialization::Serialize(response, aliasVector);
366     return response.Pop();
367 }
368
369 int CKMLogic::createKeyPairRSAHelper(
370     Credentials &cred,
371     int size,
372     const Alias &aliasPrivate,
373     const Alias &aliasPublic,
374     const PolicySerializable &policyPrivate,
375     const PolicySerializable &policyPublic)
376 {
377     if (0 >= m_userDataMap.count(cred.uid))
378         return CKM_API_ERROR_DB_LOCKED;
379
380     auto &handler = m_userDataMap[cred.uid];
381     GenericKey prv, pub;
382     int retCode;
383
384     if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
385         (retCode = CryptoService::createKeyPairRSA(size, prv, pub)))
386     {
387         LogDebug("CryptoService error with code: " << retCode);
388         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
389     }
390
391     DBCrypto::Transaction transaction(&handler.database);
392     retCode = saveDataHelper(cred,
393                             toDBDataType(prv.getType()),
394                             aliasPrivate,
395                             prv.getDER(),
396                             policyPrivate);
397
398     if (CKM_API_SUCCESS != retCode)
399         return retCode;
400
401     retCode = saveDataHelper(cred,
402                             toDBDataType(pub.getType()),
403                             aliasPublic,
404                             pub.getDER(),
405                             policyPublic);
406
407     if (CKM_API_SUCCESS != retCode)
408         return retCode;
409
410     transaction.commit();
411
412     return retCode;
413 }
414
415 RawBuffer CKMLogic::createKeyPairRSA(
416     Credentials &cred,
417     int commandId,
418     int size,
419     const Alias &aliasPrivate,
420     const Alias &aliasPublic,
421     const PolicySerializable &policyPrivate,
422     const PolicySerializable &policyPublic)
423 {
424     int retCode = CKM_API_SUCCESS;
425
426     try {
427         retCode = createKeyPairRSAHelper(
428                         cred,
429                         size,
430                         aliasPrivate,
431                         aliasPublic,
432                         policyPrivate,
433                         policyPublic);
434
435     } catch (DBCrypto::Exception::AliasExists &e) {
436         LogDebug("DBCrypto error: alias exists: " << e.GetMessage());
437         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
438     } catch (DBCrypto::Exception::TransactionError &e) {
439         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
440         retCode = CKM_API_ERROR_DB_ERROR;
441     } catch (DBCrypto::Exception::InternalError &e) {
442         LogDebug("DBCrypto internal error: " << e.GetMessage());
443         retCode = CKM_API_ERROR_DB_ERROR;
444     }
445
446     MessageBuffer response;
447     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
448     Serialization::Serialize(response, commandId);
449     Serialization::Serialize(response, retCode);
450
451     return response.Pop();
452 }
453
454 int CKMLogic::createKeyPairECDSAHelper(
455     Credentials &cred,
456     int type,
457     const Alias &aliasPrivate,
458     const Alias &aliasPublic,
459     const PolicySerializable &policyPrivate,
460     const PolicySerializable &policyPublic)
461 {
462     if (0 >= m_userDataMap.count(cred.uid))
463         return CKM_API_ERROR_DB_LOCKED;
464
465     auto &handler = m_userDataMap[cred.uid];
466     GenericKey prv, pub;
467     int retCode;
468
469     if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
470         (retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(type), prv, pub)))
471     {
472         LogError("CryptoService failed with code: " << retCode);
473         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
474     }
475
476     DBCrypto::Transaction transaction(&handler.database);
477
478     retCode = saveDataHelper(cred,
479                             toDBDataType(prv.getType()),
480                             aliasPrivate,
481                             prv.getDER(),
482                             policyPrivate);
483
484     if (CKM_API_SUCCESS != retCode)
485         return retCode;
486
487     retCode = saveDataHelper(cred,
488                             toDBDataType(pub.getType()),
489                             aliasPublic,
490                             pub.getDER(),
491                             policyPublic);
492
493     if (CKM_API_SUCCESS != retCode)
494         return retCode;
495
496     transaction.commit();
497
498     return retCode;
499 }
500
501 RawBuffer CKMLogic::createKeyPairECDSA(
502     Credentials &cred,
503     int commandId,
504     int type,
505     const Alias &aliasPrivate,
506     const Alias &aliasPublic,
507     const PolicySerializable &policyPrivate,
508     const PolicySerializable &policyPublic)
509 {
510     int retCode = CKM_API_SUCCESS;
511
512     try {
513         retCode = createKeyPairECDSAHelper(
514                         cred,
515                         type,
516                         aliasPrivate,
517                         aliasPublic,
518                         policyPrivate,
519                         policyPublic);
520     } catch (const DBCrypto::Exception::AliasExists &e) {
521         LogDebug("DBCrypto error: alias exists: " << e.GetMessage());
522         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
523     } catch (const DBCrypto::Exception::TransactionError &e) {
524         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
525         retCode = CKM_API_ERROR_DB_ERROR;
526     } catch (const DBCrypto::Exception::InternalError &e) {
527         LogDebug("DBCrypto internal error: " << e.GetMessage());
528         retCode = CKM_API_ERROR_DB_ERROR;
529     }
530
531     MessageBuffer response;
532     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
533     Serialization::Serialize(response, commandId);
534     Serialization::Serialize(response, retCode);
535
536     return response.Pop();
537 }
538
539 RawBuffer CKMLogic::getCertificateChain(
540     Credentials &cred,
541     int commandId,
542     const RawBuffer &certificate,
543     const RawBufferVector &untrustedRawCertVector)
544 {
545     (void)cred;
546
547     CertificateImpl cert(certificate, DataFormat::FORM_DER);
548     CertificateImplVector untrustedCertVector;
549     CertificateImplVector chainVector;
550     RawBufferVector chainRawVector;
551
552     for (auto &e: untrustedRawCertVector)
553         untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
554
555     LogDebug("Cert is empty: " << cert.empty());
556
557     int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
558
559     if (retCode == CKM_API_SUCCESS) {
560         for (auto &e : chainVector)
561             chainRawVector.push_back(e.getDER());
562     }
563
564     MessageBuffer response;
565     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_CERT));
566     Serialization::Serialize(response, commandId);
567     Serialization::Serialize(response, retCode);
568     Serialization::Serialize(response, chainRawVector);
569     return response.Pop();
570 }
571
572 RawBuffer CKMLogic::getCertificateChain(
573     Credentials &cred,
574     int commandId,
575     const RawBuffer &certificate,
576     const AliasVector &aliasVector)
577 {
578     (void) cred;
579     (void) commandId;
580     (void) certificate;
581     (void) aliasVector;
582
583     MessageBuffer response;
584     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_ALIAS));
585     Serialization::Serialize(response, commandId);
586     Serialization::Serialize(response, static_cast<int>(CKM_API_SUCCESS));
587     Serialization::Serialize(response, RawBufferVector());
588     return response.Pop();
589 }
590
591 RawBuffer CKMLogic::createSignature(
592         Credentials &cred,
593         int commandId,
594         const Alias &privateKeyAlias,
595         const std::string &password,           // password for private_key
596         const RawBuffer &message,
597         const HashAlgorithm hash,
598         const RSAPaddingAlgorithm padding)
599 {
600
601     DBRow row;
602     CryptoService cs;
603     RawBuffer signature;
604
605     int retCode = CKM_API_SUCCESS;
606
607     try {
608         do {
609             retCode = getDataHelper(cred, DBDataType::KEY_RSA_PUBLIC, privateKeyAlias, password, row);
610             if (CKM_API_SUCCESS != retCode) {
611                 LogError("getDataHelper return error:");
612                 break;
613             }
614
615             GenericKey keyParsed(row.data, std::string());
616             if (keyParsed.empty())
617                 retCode = CKM_API_ERROR_SERVER_ERROR;
618             else
619                 cs.createSignature(keyParsed, message, hash, padding, signature);
620         } while(0);
621     } catch (const KeyProvider::Exception::Base &e) {
622         LogError("KeyProvider failed with error: " << e.GetMessage());
623         retCode = CKM_API_ERROR_SERVER_ERROR;
624     } catch (const DBCryptoModule::Exception::Base &e) {
625         LogError("DBCryptoModule failed with message: " << e.GetMessage());
626         retCode = CKM_API_ERROR_SERVER_ERROR;
627     } catch (const DBCrypto::Exception::Base &e) {
628         LogError("DBCrypto failed with message: " << e.GetMessage());
629         retCode = CKM_API_ERROR_DB_ERROR;
630     }
631
632     MessageBuffer response;
633     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_SIGNATURE));
634     Serialization::Serialize(response, commandId);
635     Serialization::Serialize(response, retCode);
636     Serialization::Serialize(response, signature);
637     return response.Pop();
638 }
639
640 RawBuffer CKMLogic::verifySignature(
641         Credentials &cred,
642         int commandId,
643         const Alias &publicKeyOrCertAlias,
644         const std::string &password,           // password for public_key (optional)
645         const RawBuffer &message,
646         const RawBuffer &signature,
647         const HashAlgorithm hash,
648         const RSAPaddingAlgorithm padding)
649 {
650     int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
651
652     try {
653         do {
654             CryptoService cs;
655             DBRow row;
656             GenericKey key;
657
658             retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertAlias, password, row);
659
660             if (retCode == CKM_API_SUCCESS) {
661                 key = GenericKey(row.data);
662             } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
663                 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertAlias, password, row);
664                 if (retCode != CKM_API_SUCCESS)
665                     break;
666                 CertificateImpl cert(row.data, DataFormat::FORM_DER);
667                 key = cert.getGenericKey();
668             } else {
669                 break;
670             }
671
672             if (key.empty()) {
673                 retCode = CKM_API_ERROR_SERVER_ERROR;
674                 break;
675             }
676
677             retCode = cs.verifySignature(key, message, signature, hash, padding);
678         } while(0);
679     } catch (const CryptoService::Exception::Crypto_internal &e) {
680         LogError("KeyProvider failed with message: " << e.GetMessage());
681         retCode = CKM_API_ERROR_SERVER_ERROR;
682     } catch (const CryptoService::Exception::opensslError &e) {
683         LogError("KeyProvider failed with message: " << e.GetMessage());
684         retCode = CKM_API_ERROR_SERVER_ERROR;
685     } catch (const KeyProvider::Exception::Base &e) {
686         LogError("KeyProvider failed with error: " << e.GetMessage());
687         retCode = CKM_API_ERROR_SERVER_ERROR;
688     } catch (const DBCryptoModule::Exception::Base &e) {
689         LogError("DBCryptoModule failed with message: " << e.GetMessage());
690         retCode = CKM_API_ERROR_SERVER_ERROR;
691     } catch (const DBCrypto::Exception::Base &e) {
692         LogError("DBCrypto failed with message: " << e.GetMessage());
693         retCode = CKM_API_ERROR_DB_ERROR;
694     }
695
696     MessageBuffer response;
697     Serialization::Serialize(response, static_cast<int>(LogicCommand::VERIFY_SIGNATURE));
698     Serialization::Serialize(response, commandId);
699     Serialization::Serialize(response, retCode);
700
701     return response.Pop();
702 }
703 } // namespace CKM
704