Use SafeBuffer in C++ api. Rename SafeBuffer to RawBuffer.
[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 std::string &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 std::string &oldPassword,
120     const std::string &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 std::string &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         // check if the data exists or not
253         DBCrypto::DBRowOptional row_optional;
254         if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
255             row_optional = m_userDataMap[cred.uid].database.getDBRow(alias, cred.smackLabel, dataType);
256         } else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST))
257                 && (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
258         {
259             row_optional = m_userDataMap[cred.uid].database.getKeyDBRow(alias, cred.smackLabel);
260         } else {
261             LogError("Unknown type of requested data" << (int)dataType);
262             retCode = CKM_API_ERROR_BAD_REQUEST;
263         }
264         if(!row_optional) {
265             LogError("No row for given alias, label and type");
266             retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
267         }
268
269         // remove if the data exists
270         if(retCode == CKM_API_SUCCESS) {
271             Try {
272                 m_userDataMap[cred.uid].database.deleteDBRow(alias, cred.smackLabel);
273             } Catch (CKM::Exception) {
274                 LogError("Error in deleting row!");
275                 retCode = CKM_API_ERROR_DB_ERROR;
276             }
277         }
278     } else {
279         retCode = CKM_API_ERROR_DB_LOCKED;
280     }
281
282     MessageBuffer response;
283     Serialization::Serialize(response, static_cast<int>(LogicCommand::REMOVE));
284     Serialization::Serialize(response, commandId);
285     Serialization::Serialize(response, retCode);
286     Serialization::Serialize(response, static_cast<int>(dataType));
287
288     return response.Pop();
289 }
290
291 int CKMLogic::getDataHelper(
292     Credentials &cred,
293     DBDataType dataType,
294     const Alias &alias,
295     const std::string &password,
296     DBRow &row)
297 {
298
299     if (0 == m_userDataMap.count(cred.uid))
300         return CKM_API_ERROR_DB_LOCKED;
301
302     auto &handler = m_userDataMap[cred.uid];
303
304     DBCrypto::DBRowOptional row_optional;
305     if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
306         row_optional = handler.database.getDBRow(alias, cred.smackLabel, dataType);
307     } else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST))
308             && (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
309     {
310         row_optional = handler.database.getKeyDBRow(alias, cred.smackLabel);
311     } else {
312         LogError("Unknown type of requested data" << (int)dataType);
313         return CKM_API_ERROR_BAD_REQUEST;
314     }
315     if(!row_optional) {
316         LogError("No row for given alias, label and type");
317         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
318     } else {
319         row = *row_optional;
320     }
321
322     if (!handler.crypto.haveKey(row.smackLabel)) {
323         RawBuffer key;
324         auto key_optional = handler.database.getKey(row.smackLabel);
325         if(!key_optional) {
326             LogError("No key for given label in database");
327             return CKM_API_ERROR_DB_ERROR;
328         }
329         key = *key_optional;
330         key = handler.keyProvider.getPureDEK(key);
331         handler.crypto.pushKey(cred.smackLabel, key);
332     }
333     handler.crypto.decryptRow(password, row);
334
335     return CKM_API_SUCCESS;
336 }
337
338 RawBuffer CKMLogic::getData(
339     Credentials &cred,
340     int commandId,
341     DBDataType dataType,
342     const Alias &alias,
343     const std::string &password)
344 {
345     int retCode = CKM_API_SUCCESS;
346     DBRow row;
347
348     try {
349         retCode = getDataHelper(cred, dataType, alias, password, row);
350     } catch (const KeyProvider::Exception::Base &e) {
351         LogError("KeyProvider failed with error: " << e.GetMessage());
352         retCode = CKM_API_ERROR_SERVER_ERROR;
353     } catch (const CryptoLogic::Exception::Base &e) {
354         LogError("CryptoLogic failed with message: " << e.GetMessage());
355         retCode = CKM_API_ERROR_SERVER_ERROR;
356     } catch (const DBCrypto::Exception::Base &e) {
357         LogError("DBCrypto failed with message: " << e.GetMessage());
358         retCode = CKM_API_ERROR_DB_ERROR;
359     }
360
361     if (CKM_API_SUCCESS != retCode) {
362         row.data.clear();
363         row.dataType = dataType;
364     }
365
366     MessageBuffer response;
367     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
368     Serialization::Serialize(response, commandId);
369     Serialization::Serialize(response, retCode);
370     Serialization::Serialize(response, static_cast<int>(row.dataType));
371     Serialization::Serialize(response, row.data);
372     return response.Pop();
373 }
374
375 RawBuffer CKMLogic::getDataList(
376     Credentials &cred,
377     int commandId,
378     DBDataType dataType)
379 {
380     int retCode = CKM_API_SUCCESS;
381     AliasVector aliasVector;
382
383     if (0 < m_userDataMap.count(cred.uid)) {
384         auto &handler = m_userDataMap[cred.uid];
385         Try {
386             if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
387                 handler.database.getAliases(dataType, cred.smackLabel, aliasVector);
388             } else {
389                 handler.database.getKeyAliases(cred.smackLabel, aliasVector);
390             }
391         } Catch (CKM::Exception) {
392             LogError("Failed to get aliases");
393             retCode = CKM_API_ERROR_DB_ERROR;
394         }
395     } else {
396         retCode = CKM_API_ERROR_DB_LOCKED;
397     }
398
399     MessageBuffer response;
400     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_LIST));
401     Serialization::Serialize(response, commandId);
402     Serialization::Serialize(response, retCode);
403     Serialization::Serialize(response, static_cast<int>(dataType));
404     Serialization::Serialize(response, aliasVector);
405     return response.Pop();
406 }
407
408 int CKMLogic::createKeyPairRSAHelper(
409     Credentials &cred,
410     int size,
411     const Alias &aliasPrivate,
412     const Alias &aliasPublic,
413     const PolicySerializable &policyPrivate,
414     const PolicySerializable &policyPublic)
415 {
416     if (0 >= m_userDataMap.count(cred.uid))
417         return CKM_API_ERROR_DB_LOCKED;
418
419     auto &handler = m_userDataMap[cred.uid];
420     GenericKey prv, pub;
421     int retCode;
422
423     if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
424         (retCode = CryptoService::createKeyPairRSA(size, prv, pub)))
425     {
426         LogDebug("CryptoService error with code: " << retCode);
427         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
428     }
429
430     DBCrypto::Transaction transaction(&handler.database);
431     retCode = saveDataHelper(cred,
432                             toDBDataType(prv.getType()),
433                             aliasPrivate,
434                             prv.getDER(),
435                             policyPrivate);
436
437     if (CKM_API_SUCCESS != retCode)
438         return retCode;
439
440     retCode = saveDataHelper(cred,
441                             toDBDataType(pub.getType()),
442                             aliasPublic,
443                             pub.getDER(),
444                             policyPublic);
445
446     if (CKM_API_SUCCESS != retCode)
447         return retCode;
448
449     transaction.commit();
450
451     return retCode;
452 }
453
454 RawBuffer CKMLogic::createKeyPairRSA(
455     Credentials &cred,
456     int commandId,
457     int size,
458     const Alias &aliasPrivate,
459     const Alias &aliasPublic,
460     const PolicySerializable &policyPrivate,
461     const PolicySerializable &policyPublic)
462 {
463     int retCode = CKM_API_SUCCESS;
464
465     try {
466         retCode = createKeyPairRSAHelper(
467                         cred,
468                         size,
469                         aliasPrivate,
470                         aliasPublic,
471                         policyPrivate,
472                         policyPublic);
473
474     } catch (DBCrypto::Exception::AliasExists &e) {
475         LogDebug("DBCrypto error: alias exists: " << e.GetMessage());
476         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
477     } catch (DBCrypto::Exception::TransactionError &e) {
478         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
479         retCode = CKM_API_ERROR_DB_ERROR;
480     } catch (CKM::CryptoLogic::Exception::Base &e) {
481         LogDebug("CryptoLogic error: " << e.GetMessage());
482         retCode = CKM_API_ERROR_SERVER_ERROR;
483     } catch (DBCrypto::Exception::InternalError &e) {
484         LogDebug("DBCrypto internal error: " << e.GetMessage());
485         retCode = CKM_API_ERROR_DB_ERROR;
486     }
487
488     MessageBuffer response;
489     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
490     Serialization::Serialize(response, commandId);
491     Serialization::Serialize(response, retCode);
492
493     return response.Pop();
494 }
495
496 int CKMLogic::createKeyPairECDSAHelper(
497     Credentials &cred,
498     int type,
499     const Alias &aliasPrivate,
500     const Alias &aliasPublic,
501     const PolicySerializable &policyPrivate,
502     const PolicySerializable &policyPublic)
503 {
504     if (0 >= m_userDataMap.count(cred.uid))
505         return CKM_API_ERROR_DB_LOCKED;
506
507     auto &handler = m_userDataMap[cred.uid];
508     GenericKey prv, pub;
509     int retCode;
510
511     if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
512         (retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(type), prv, pub)))
513     {
514         LogError("CryptoService failed with code: " << retCode);
515         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
516     }
517
518     DBCrypto::Transaction transaction(&handler.database);
519
520     retCode = saveDataHelper(cred,
521                             toDBDataType(prv.getType()),
522                             aliasPrivate,
523                             prv.getDER(),
524                             policyPrivate);
525
526     if (CKM_API_SUCCESS != retCode)
527         return retCode;
528
529     retCode = saveDataHelper(cred,
530                             toDBDataType(pub.getType()),
531                             aliasPublic,
532                             pub.getDER(),
533                             policyPublic);
534
535     if (CKM_API_SUCCESS != retCode)
536         return retCode;
537
538     transaction.commit();
539
540     return retCode;
541 }
542
543 RawBuffer CKMLogic::createKeyPairECDSA(
544     Credentials &cred,
545     int commandId,
546     int type,
547     const Alias &aliasPrivate,
548     const Alias &aliasPublic,
549     const PolicySerializable &policyPrivate,
550     const PolicySerializable &policyPublic)
551 {
552     int retCode = CKM_API_SUCCESS;
553
554     try {
555         retCode = createKeyPairECDSAHelper(
556                         cred,
557                         type,
558                         aliasPrivate,
559                         aliasPublic,
560                         policyPrivate,
561                         policyPublic);
562     } catch (const DBCrypto::Exception::AliasExists &e) {
563         LogDebug("DBCrypto error: alias exists: " << e.GetMessage());
564         retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
565     } catch (const DBCrypto::Exception::TransactionError &e) {
566         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
567         retCode = CKM_API_ERROR_DB_ERROR;
568     } catch (const CKM::CryptoLogic::Exception::Base &e) {
569         LogDebug("CryptoLogic error: " << e.GetMessage());
570         retCode = CKM_API_ERROR_SERVER_ERROR;
571     } catch (const DBCrypto::Exception::InternalError &e) {
572         LogDebug("DBCrypto internal error: " << e.GetMessage());
573         retCode = CKM_API_ERROR_DB_ERROR;
574     }
575
576     MessageBuffer response;
577     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
578     Serialization::Serialize(response, commandId);
579     Serialization::Serialize(response, retCode);
580
581     return response.Pop();
582 }
583
584 RawBuffer CKMLogic::getCertificateChain(
585     Credentials &cred,
586     int commandId,
587     const RawBuffer &certificate,
588     const RawBufferVector &untrustedRawCertVector)
589 {
590     (void)cred;
591
592     CertificateImpl cert(certificate, DataFormat::FORM_DER);
593     CertificateImplVector untrustedCertVector;
594     CertificateImplVector chainVector;
595     RawBufferVector chainRawVector;
596
597     for (auto &e: untrustedRawCertVector)
598         untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
599
600     LogDebug("Cert is empty: " << cert.empty());
601
602     int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
603
604     if (retCode == CKM_API_SUCCESS) {
605         for (auto &e : chainVector)
606             chainRawVector.push_back(e.getDER());
607     }
608
609     MessageBuffer response;
610     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_CERT));
611     Serialization::Serialize(response, commandId);
612     Serialization::Serialize(response, retCode);
613     Serialization::Serialize(response, chainRawVector);
614     return response.Pop();
615 }
616
617 RawBuffer CKMLogic::getCertificateChain(
618     Credentials &cred,
619     int commandId,
620     const RawBuffer &certificate,
621     const AliasVector &aliasVector)
622 {
623     int retCode = CKM_API_SUCCESS;
624     RawBufferVector chainRawVector;
625     try {
626         CertificateImpl cert(certificate, DataFormat::FORM_DER);
627         CertificateImplVector untrustedCertVector;
628         CertificateImplVector chainVector;
629         DBRow row;
630
631         if (cert.empty()) {
632             retCode = CKM_API_ERROR_SERVER_ERROR;
633             goto senderror;
634         }
635
636         for (auto &i: aliasVector) {
637             retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i, std::string(), row);
638
639             if (retCode != CKM_API_SUCCESS)
640                 goto senderror;
641
642             untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
643         }
644
645         retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
646
647         if (retCode != CKM_API_SUCCESS)
648             goto senderror;
649
650         for (auto &i: chainVector)
651             chainRawVector.push_back(i.getDER());
652
653     } catch (const CryptoLogic::Exception::Base &e) {
654         LogError("DBCyptorModule failed with message: " << e.GetMessage());
655         retCode = CKM_API_ERROR_SERVER_ERROR;
656     } catch (const DBCrypto::Exception::Base &e) {
657         LogError("DBCrypto failed with message: " << e.GetMessage());
658         retCode = CKM_API_ERROR_DB_ERROR;
659     } catch (...) {
660         LogError("Unknown error.");
661     }
662
663 senderror:
664     MessageBuffer response;
665     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_ALIAS));
666     Serialization::Serialize(response, commandId);
667     Serialization::Serialize(response, retCode);
668     Serialization::Serialize(response, chainRawVector);
669     return response.Pop();
670 }
671
672 RawBuffer CKMLogic::createSignature(
673         Credentials &cred,
674         int commandId,
675         const Alias &privateKeyAlias,
676         const std::string &password,           // password for private_key
677         const RawBuffer &message,
678         const HashAlgorithm hash,
679         const RSAPaddingAlgorithm padding)
680 {
681     DBRow row;
682     CryptoService cs;
683     RawBuffer signature;
684
685     int retCode = CKM_API_SUCCESS;
686
687     try {
688         do {
689             retCode = getDataHelper(cred, DBDataType::KEY_RSA_PUBLIC, privateKeyAlias, password, row);
690             if (CKM_API_SUCCESS != retCode) {
691                 LogError("getDataHelper return error");
692                 break;
693             }
694
695             GenericKey keyParsed(row.data, std::string());
696             if (keyParsed.empty())
697                 retCode = CKM_API_ERROR_SERVER_ERROR;
698             else
699                 cs.createSignature(keyParsed, message, hash, padding, signature);
700         } while(0);
701     } catch (const KeyProvider::Exception::Base &e) {
702         LogError("KeyProvider failed with message: " << e.GetMessage());
703         retCode = CKM_API_ERROR_SERVER_ERROR;
704     } catch (const CryptoLogic::Exception::Base &e) {
705         LogError("CryptoLogic failed with message: " << e.GetMessage());
706         retCode = CKM_API_ERROR_SERVER_ERROR;
707     } catch (const DBCrypto::Exception::Base &e) {
708         LogError("DBCrypto failed with message: " << e.GetMessage());
709         retCode = CKM_API_ERROR_DB_ERROR;
710     } catch (const CKM::Exception &e) {
711         LogError("Unknown CKM::Exception: " << e.GetMessage());
712         retCode = CKM_API_ERROR_SERVER_ERROR;
713     }
714
715     MessageBuffer response;
716     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_SIGNATURE));
717     Serialization::Serialize(response, commandId);
718     Serialization::Serialize(response, retCode);
719     Serialization::Serialize(response, signature);
720     return response.Pop();
721 }
722
723 RawBuffer CKMLogic::verifySignature(
724         Credentials &cred,
725         int commandId,
726         const Alias &publicKeyOrCertAlias,
727         const std::string &password,           // password for public_key (optional)
728         const RawBuffer &message,
729         const RawBuffer &signature,
730         const HashAlgorithm hash,
731         const RSAPaddingAlgorithm padding)
732 {
733     int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
734
735     try {
736         do {
737             CryptoService cs;
738             DBRow row;
739             GenericKey key;
740
741             retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertAlias, password, row);
742
743             if (retCode == CKM_API_SUCCESS) {
744                 key = GenericKey(row.data);
745             } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
746                 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertAlias, password, row);
747                 if (retCode != CKM_API_SUCCESS)
748                     break;
749                 CertificateImpl cert(row.data, DataFormat::FORM_DER);
750                 key = cert.getGenericKey();
751             } else {
752                 break;
753             }
754
755             if (key.empty()) {
756                 retCode = CKM_API_ERROR_SERVER_ERROR;
757                 break;
758             }
759
760             retCode = cs.verifySignature(key, message, signature, hash, padding);
761         } while(0);
762     } catch (const CryptoService::Exception::Crypto_internal &e) {
763         LogError("KeyProvider failed with message: " << e.GetMessage());
764         retCode = CKM_API_ERROR_SERVER_ERROR;
765     } catch (const CryptoService::Exception::opensslError &e) {
766         LogError("KeyProvider failed with message: " << e.GetMessage());
767         retCode = CKM_API_ERROR_SERVER_ERROR;
768     } catch (const KeyProvider::Exception::Base &e) {
769         LogError("KeyProvider failed with error: " << e.GetMessage());
770         retCode = CKM_API_ERROR_SERVER_ERROR;
771     } catch (const CryptoLogic::Exception::Base &e) {
772         LogError("CryptoLogic failed with message: " << e.GetMessage());
773         retCode = CKM_API_ERROR_SERVER_ERROR;
774     } catch (const DBCrypto::Exception::Base &e) {
775         LogError("DBCrypto failed with message: " << e.GetMessage());
776         retCode = CKM_API_ERROR_DB_ERROR;
777     } catch (const CKM::Exception &e) {
778         LogError("Unknown CKM::Exception: " << e.GetMessage());
779         retCode = CKM_API_ERROR_SERVER_ERROR;
780     }
781
782     MessageBuffer response;
783     Serialization::Serialize(response, static_cast<int>(LogicCommand::VERIFY_SIGNATURE));
784     Serialization::Serialize(response, commandId);
785     Serialization::Serialize(response, retCode);
786
787     return response.Pop();
788 }
789 } // namespace CKM
790