e8e7f0c2414b03557c710ac89bdedd54693922ea
[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 <ckm-logic.h>
29 #include <key-impl.h>
30 #include <certificate-config.h>
31 #include <certificate-store.h>
32
33 #include <sw-backend/crypto-service.h>
34
35 namespace {
36 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
37
38 bool isLabelValid(const CKM::Label &label) {
39     // TODO: copy code from libprivilege control (for check smack label)
40     if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
41         return false;
42     return true;
43 }
44
45 bool isNameValid(const CKM::Name &name) {
46     if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
47         return false;
48     return true;
49 }
50
51 } // anonymous namespace
52
53 namespace CKM {
54
55 CKMLogic::CKMLogic()
56 {
57     CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
58
59     m_accessControl.updateCCMode();
60 }
61
62 CKMLogic::~CKMLogic(){}
63
64 void CKMLogic::loadDKEKFile(uid_t user, const Password &password) {
65     auto &handle = m_userDataMap[user];
66
67     FileSystem fs(user);
68
69     auto wrappedDKEK = fs.getDKEK();
70
71     if (wrappedDKEK.empty()) {
72         wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
73         fs.saveDKEK(wrappedDKEK);
74     }
75
76     handle.keyProvider = KeyProvider(wrappedDKEK, password);
77 }
78
79 void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
80     auto &handle = m_userDataMap[user];
81
82     FileSystem fs(user);
83     fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
84 }
85
86 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
87     int retCode = CKM_API_SUCCESS;
88
89     try {
90         if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
91             auto &handle = m_userDataMap[user];
92             FileSystem fs(user);
93
94             loadDKEKFile(user, password);
95
96             auto wrappedDatabaseDEK = fs.getDBDEK();
97
98             if (wrappedDatabaseDEK.empty()) {
99                 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
100                 fs.saveDBDEK(wrappedDatabaseDEK);
101             }
102
103             RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
104             handle.database = DB::Crypto(fs.getDBPath(), key);
105             handle.crypto = CryptoLogic();
106
107             // remove data of removed apps during locked state
108             AppLabelVector removedApps = fs.clearRemovedsApps();
109             for(auto& appSmackLabel : removedApps) {
110                 handle.database.deleteKey(appSmackLabel);
111             }
112         }
113     } catch (const KeyProvider::Exception::PassWordError &e) {
114         LogError("Incorrect Password " << e.GetMessage());
115         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
116     } catch (const KeyProvider::Exception::Base &e) {
117         LogError("Error in KeyProvider " << e.GetMessage());
118         retCode = CKM_API_ERROR_SERVER_ERROR;
119     } catch (const CryptoLogic::Exception::Base &e) {
120         LogError("CryptoLogic error: " << e.GetMessage());
121         retCode = CKM_API_ERROR_SERVER_ERROR;
122     } catch (const FileSystem::Exception::Base &e) {
123         LogError("FileSystem error: " << e.GetMessage());
124         retCode = CKM_API_ERROR_FILE_SYSTEM;
125     } catch (const CKM::Exception &e) {
126         LogError("CKM::Exception: " << e.GetMessage());
127         retCode = CKM_API_ERROR_SERVER_ERROR;
128     }
129
130     if(retCode != CKM_API_SUCCESS) {
131         // When not successful, UserData in m_userDataMap should be erased.
132         // Because other operations make decision based on the existence of UserData in m_userDataMap.
133         m_userDataMap.erase(user);
134     }
135
136     return MessageBuffer::Serialize(retCode).Pop();
137 }
138
139 RawBuffer CKMLogic::updateCCMode() {
140     m_accessControl.updateCCMode();
141     return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
142 }
143
144 RawBuffer CKMLogic::lockUserKey(uid_t user) {
145     int retCode = CKM_API_SUCCESS;
146     // TODO try catch for all errors that should be supported by error code
147     m_userDataMap.erase(user);
148
149     return MessageBuffer::Serialize(retCode).Pop();
150
151 }
152
153 RawBuffer CKMLogic::removeUserData(uid_t user) {
154     int retCode = CKM_API_SUCCESS;
155     // TODO try catch for all errors that should be supported by error code
156     m_userDataMap.erase(user);
157
158     FileSystem fs(user);
159     fs.removeUserData();
160
161     return MessageBuffer::Serialize(retCode).Pop();
162 }
163
164 RawBuffer CKMLogic::changeUserPassword(
165     uid_t user,
166     const Password &oldPassword,
167     const Password &newPassword)
168 {
169     int retCode = CKM_API_SUCCESS;
170     try {
171         loadDKEKFile(user, oldPassword);
172         saveDKEKFile(user, newPassword);
173     } catch (const KeyProvider::Exception::PassWordError &e) {
174         LogError("Incorrect Password " << e.GetMessage());
175         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
176     } catch (const KeyProvider::Exception::Base &e) {
177         LogError("Error in KeyProvider " << e.GetMessage());
178         retCode = CKM_API_ERROR_SERVER_ERROR;
179     } catch (const FileSystem::Exception::Base &e) {
180         LogError("Error in FileSystem " << e.GetMessage());
181         retCode = CKM_API_ERROR_FILE_SYSTEM;
182     } catch (const CKM::Exception &e) {
183         LogError("CKM::Exception: " << e.GetMessage());
184         retCode = CKM_API_ERROR_SERVER_ERROR;
185     }
186
187     return MessageBuffer::Serialize(retCode).Pop();
188 }
189
190 RawBuffer CKMLogic::resetUserPassword(
191     uid_t user,
192     const Password &newPassword)
193 {
194     int retCode = CKM_API_SUCCESS;
195
196     try {
197         if (0 == m_userDataMap.count(user)) {
198             // Check if key exists. If exists we must return error
199             FileSystem fs(user);
200             auto wrappedDKEKMain = fs.getDKEK();
201             if (!wrappedDKEKMain.empty())
202                 retCode = CKM_API_ERROR_BAD_REQUEST;
203         } else {
204             saveDKEKFile(user, newPassword);
205         }
206     } catch (const FileSystem::Exception::Base &e) {
207         LogError("Error in FileSystem " << e.GetMessage());
208         retCode = CKM_API_ERROR_FILE_SYSTEM;
209     } catch (const CKM::Exception &e) {
210         LogError("CKM::Exception: " << e.GetMessage());
211         retCode = CKM_API_ERROR_SERVER_ERROR;
212     }
213
214     return MessageBuffer::Serialize(retCode).Pop();
215 }
216
217 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
218     int retCode = CKM_API_SUCCESS;
219
220     try {
221
222         if (smackLabel.empty()) {
223             retCode = CKM_API_ERROR_INPUT_PARAM;
224         } else {
225             UidVector uids = FileSystem::getUIDsFromDBFile();
226             for (auto userId : uids) {
227                 if (0 == m_userDataMap.count(userId)) {
228                     FileSystem fs(userId);
229                     fs.addRemovedApp(smackLabel);
230                 } else {
231                     auto &handle = m_userDataMap[userId];
232                     handle.database.deleteKey(smackLabel);
233                 }
234             }
235         }
236
237     } catch (const DB::Crypto::Exception::InternalError &e) {
238         LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
239         retCode = CKM_API_ERROR_DB_ERROR;
240     } catch (const DB::Crypto::Exception::TransactionError &e) {
241         LogError("DB::Crypto transaction failed with message " << e.GetMessage());
242         retCode = CKM_API_ERROR_DB_ERROR;
243     } catch (const FileSystem::Exception::Base &e) {
244         LogError("Error in FileSystem " << e.GetMessage());
245         retCode = CKM_API_ERROR_FILE_SYSTEM;
246     } catch (const CKM::Exception &e) {
247         LogError("CKM::Exception: " << e.GetMessage());
248         retCode = CKM_API_ERROR_SERVER_ERROR;
249     }
250
251     return MessageBuffer::Serialize(retCode).Pop();
252 }
253
254 int CKMLogic::checkSaveConditions(
255     const Credentials &cred,
256     UserData &handler,
257     const Name &name,
258     const Label &ownerLabel)
259 {
260     // verify name and label are correct
261     if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
262         LogWarning("Invalid parameter passed to key-manager");
263         return CKM_API_ERROR_INPUT_PARAM;
264     }
265
266     // check if allowed to save using ownerLabel
267     int access_ec = m_accessControl.canSave(ownerLabel, cred.smackLabel);
268     if(access_ec != CKM_API_SUCCESS)
269     {
270         LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
271         return access_ec;
272     }
273
274     // check if not a duplicate
275     if( handler.database.isNameLabelPresent(name, cred.smackLabel) )
276         return CKM_API_ERROR_DB_ALIAS_EXISTS;
277
278     // encryption section
279     if (!handler.crypto.haveKey(cred.smackLabel)) {
280         RawBuffer got_key;
281         auto key_optional = handler.database.getKey(cred.smackLabel);
282         if(!key_optional) {
283             LogDebug("No Key in database found. Generating new one for label: "
284                     << cred.smackLabel);
285             got_key = handler.keyProvider.generateDEK(cred.smackLabel);
286             handler.database.saveKey(cred.smackLabel, got_key);
287         } else {
288             LogDebug("Key from DB");
289             got_key = *key_optional;
290         }
291
292         got_key = handler.keyProvider.getPureDEK(got_key);
293         handler.crypto.pushKey(cred.smackLabel, got_key);
294     }
295
296     return CKM_API_SUCCESS;
297 }
298
299 DB::Row CKMLogic::createEncryptedRow(
300     CryptoLogic &crypto,
301     const Name &name,
302     const Label &label,
303     DataType dataType,
304     const RawBuffer &data,
305     const Policy &policy) const
306 {
307     DB::Row row = { name, label, policy.extractable, dataType, DBCMAlgType::NONE,
308                   0, RawBuffer(), static_cast<int>(data.size()), data, RawBuffer() };
309
310     // do not encrypt data with password during cc_mode on
311     if(m_accessControl.isCCMode()) {
312         crypto.encryptRow("", row);
313     } else {
314         crypto.encryptRow(policy.password, row);
315     }
316     return row;
317 }
318
319 int CKMLogic::verifyBinaryData(DataType dataType, const RawBuffer &input_data) const
320 {
321     // verify the data integrity
322     if (dataType.isKey())
323     {
324         KeyShPtr output_key = CKM::Key::create(input_data);
325         if(output_key.get() == NULL)
326         {
327             LogError("provided binary data is not valid key data");
328             return CKM_API_ERROR_INPUT_PARAM;
329         }
330     }
331     else if (dataType.isCertificate() || dataType.isChainCert())
332     {
333         CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
334         if(cert.get() == NULL)
335         {
336             LogError("provided binary data is not valid certificate data");
337             return CKM_API_ERROR_INPUT_PARAM;
338         }
339     }
340     // TODO: add here BINARY_DATA verification, i.e: max size etc.
341     return CKM_API_SUCCESS;
342 }
343
344 RawBuffer CKMLogic::saveData(
345     const Credentials &cred,
346     int commandId,
347     const Name &name,
348     const Label &label,
349     const RawBuffer &data,
350     DataType dataType,
351     const PolicySerializable &policy)
352 {
353     int retCode;
354     if (0 == m_userDataMap.count(cred.uid))
355         retCode = CKM_API_ERROR_DB_LOCKED;
356     else
357     {
358         try {
359             // check if data is correct
360             retCode = verifyBinaryData(dataType, data);
361             if(retCode == CKM_API_SUCCESS)
362             {
363                 retCode = saveDataHelper(cred, name, label, dataType, data, policy);
364             }
365         } catch (const KeyProvider::Exception::Base &e) {
366             LogError("KeyProvider failed with message: " << e.GetMessage());
367             retCode = CKM_API_ERROR_SERVER_ERROR;
368         } catch (const CryptoLogic::Exception::Base &e) {
369             LogError("CryptoLogic failed with message: " << e.GetMessage());
370             retCode = CKM_API_ERROR_SERVER_ERROR;
371         } catch (const DB::Crypto::Exception::InternalError &e) {
372             LogError("DB::Crypto failed with message: " << e.GetMessage());
373             retCode = CKM_API_ERROR_DB_ERROR;
374         } catch (const DB::Crypto::Exception::TransactionError &e) {
375             LogError("DB::Crypto transaction failed with message " << e.GetMessage());
376             retCode = CKM_API_ERROR_DB_ERROR;
377         } catch (const FileSystem::Exception::Base &e) {
378             LogError("Error in FileSystem " << e.GetMessage());
379             retCode = CKM_API_ERROR_FILE_SYSTEM;
380         } catch (const CKM::Exception &e) {
381             LogError("CKM::Exception: " << e.GetMessage());
382             retCode = CKM_API_ERROR_SERVER_ERROR;
383         }
384     }
385
386     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
387                                              commandId,
388                                              retCode,
389                                              static_cast<int>(dataType));
390     return response.Pop();
391 }
392
393 int CKMLogic::extractPKCS12Data(
394     CryptoLogic &crypto,
395     const Name &name,
396     const Label &ownerLabel,
397     const PKCS12Serializable &pkcs,
398     const PolicySerializable &keyPolicy,
399     const PolicySerializable &certPolicy,
400     DB::RowVector &output) const
401 {
402     // private key is mandatory
403     if( !pkcs.getKey() )
404         return CKM_API_ERROR_INVALID_FORMAT;
405     Key* keyPtr = pkcs.getKey().get();
406     DataType keyType = DataType(keyPtr->getType());
407     RawBuffer keyData = keyPtr->getDER();
408     int retCode = verifyBinaryData(keyType, keyData);
409     if(retCode != CKM_API_SUCCESS)
410         return retCode;
411     output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
412
413     // certificate is mandatory
414     if( !pkcs.getCertificate() )
415         return CKM_API_ERROR_INVALID_FORMAT;
416     RawBuffer certData = pkcs.getCertificate().get()->getDER();
417     retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
418     if(retCode != CKM_API_SUCCESS)
419         return retCode;
420     output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
421
422     // CA cert chain
423     unsigned int cert_index = 0;
424     for(const auto & ca : pkcs.getCaCertificateShPtrVector())
425     {
426         DataType chainDataType = DataType::getChainDatatype(cert_index ++);
427         RawBuffer caCertData = ca->getDER();
428         int retCode = verifyBinaryData(chainDataType, caCertData);
429         if(retCode != CKM_API_SUCCESS)
430             return retCode;
431
432         output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
433     }
434
435     return CKM_API_SUCCESS;
436 }
437
438 RawBuffer CKMLogic::savePKCS12(
439     const Credentials &cred,
440     int commandId,
441     const Name &name,
442     const Label &label,
443     const PKCS12Serializable &pkcs,
444     const PolicySerializable &keyPolicy,
445     const PolicySerializable &certPolicy)
446 {
447     int retCode;
448     if (0 == m_userDataMap.count(cred.uid))
449         retCode = CKM_API_ERROR_DB_LOCKED;
450     else
451     {
452         try {
453             retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
454         } catch (const KeyProvider::Exception::Base &e) {
455             LogError("KeyProvider failed with message: " << e.GetMessage());
456             retCode = CKM_API_ERROR_SERVER_ERROR;
457         } catch (const CryptoLogic::Exception::Base &e) {
458             LogError("CryptoLogic failed with message: " << e.GetMessage());
459             retCode = CKM_API_ERROR_SERVER_ERROR;
460         } catch (const DB::Crypto::Exception::InternalError &e) {
461             LogError("DB::Crypto failed with message: " << e.GetMessage());
462             retCode = CKM_API_ERROR_DB_ERROR;
463         } catch (const DB::Crypto::Exception::TransactionError &e) {
464             LogError("DB::Crypto transaction failed with message " << e.GetMessage());
465             retCode = CKM_API_ERROR_DB_ERROR;
466         } catch (const CKM::Exception &e) {
467             LogError("CKM::Exception: " << e.GetMessage());
468             retCode = CKM_API_ERROR_SERVER_ERROR;
469         }
470     }
471
472     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
473                                              commandId,
474                                              retCode);
475     return response.Pop();
476 }
477
478
479 int CKMLogic::removeDataHelper(
480         const Credentials &cred,
481         const Name &name,
482         const Label &ownerLabel)
483 {
484     if (0 == m_userDataMap.count(cred.uid))
485         return CKM_API_ERROR_DB_LOCKED;
486
487     if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
488         LogError("Invalid label or name format");
489         return CKM_API_ERROR_INPUT_PARAM;
490     }
491
492     auto &database = m_userDataMap[cred.uid].database;
493     DB::Crypto::Transaction transaction(&database);
494
495     // read and check permissions
496     PermissionMaskOptional permissionRowOpt =
497             database.getPermissionRow(name, ownerLabel, cred.smackLabel);
498     int access_ec = m_accessControl.canDelete(PermissionForLabel(cred.smackLabel, permissionRowOpt));
499     if(access_ec != CKM_API_SUCCESS)
500     {
501         LogWarning("access control check result: " << access_ec);
502         return access_ec;
503     }
504
505     auto erased = database.deleteRow(name, ownerLabel);
506     // check if the data existed or not
507     if(erased)
508         transaction.commit();
509     else {
510         LogError("No row for given name and label");
511         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
512     }
513
514     return CKM_API_SUCCESS;
515 }
516
517 RawBuffer CKMLogic::removeData(
518     const Credentials &cred,
519     int commandId,
520     const Name &name,
521     const Label &label)
522 {
523     int retCode;
524     Try {
525         // use client label if not explicitly provided
526         const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
527
528         retCode = removeDataHelper(cred, name, ownerLabel);
529     } Catch (CKM::Exception) {
530         LogError("Error in deleting row!");
531         retCode = CKM_API_ERROR_DB_ERROR;
532     }
533
534     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
535                                              commandId,
536                                              retCode);
537     return response.Pop();
538 }
539
540 int CKMLogic::readSingleRow(const Name &name,
541                             const Label &ownerLabel,
542                             DataType dataType,
543                             DB::Crypto & database,
544                             DB::Row &row)
545 {
546     DB::Crypto::RowOptional row_optional;
547     if (dataType.isKey())
548     {
549         // read all key types
550         row_optional = database.getRow(name,
551                                          ownerLabel,
552                                          DataType::DB_KEY_FIRST,
553                                          DataType::DB_KEY_LAST);
554     } else {
555         // read anything else
556         row_optional = database.getRow(name,
557                                          ownerLabel,
558                                          dataType);
559     }
560
561     if(!row_optional) {
562         LogError("No row for given name, label and type");
563         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
564     } else {
565         row = *row_optional;
566     }
567
568     return CKM_API_SUCCESS;
569 }
570
571
572 int CKMLogic::readMultiRow(const Name &name,
573                            const Label &ownerLabel,
574                            DataType dataType,
575                            DB::Crypto & database,
576                            DB::RowVector &output)
577 {
578     if (dataType.isKey())
579     {
580         // read all key types
581         database.getRows(name,
582                           ownerLabel,
583                           DataType::DB_KEY_FIRST,
584                           DataType::DB_KEY_LAST,
585                           output);
586     }
587     else if (dataType.isChainCert())
588     {
589         // read all key types
590         database.getRows(name,
591                           ownerLabel,
592                           DataType::DB_CHAIN_FIRST,
593                           DataType::DB_CHAIN_LAST,
594                           output);
595     }
596     else
597     {
598         // read anything else
599         database.getRows(name,
600                           ownerLabel,
601                           dataType,
602                           output);
603     }
604
605     if(!output.size()) {
606         LogError("No row for given name, label and type");
607         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
608     }
609
610     return CKM_API_SUCCESS;
611 }
612
613 int CKMLogic::checkDataPermissionsHelper(const Name &name,
614                                          const Label &ownerLabel,
615                                          const Label &accessorLabel,
616                                          const DB::Row &row,
617                                          bool exportFlag,
618                                          DB::Crypto & database)
619 {
620     PermissionMaskOptional permissionRowOpt =
621             database.getPermissionRow(name, ownerLabel, accessorLabel);
622
623     if(exportFlag)
624         return m_accessControl.canExport(row, PermissionForLabel(accessorLabel, permissionRowOpt));
625     return m_accessControl.canRead(PermissionForLabel(accessorLabel, permissionRowOpt));
626 }
627
628 int CKMLogic::readDataHelper(
629     bool exportFlag,
630     const Credentials &cred,
631     DataType dataType,
632     const Name &name,
633     const Label &label,
634     const Password &password,
635     DB::RowVector &rows)
636 {
637     if (0 == m_userDataMap.count(cred.uid))
638         return CKM_API_ERROR_DB_LOCKED;
639
640     // use client label if not explicitly provided
641     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
642
643     if (!isNameValid(name) || !isLabelValid(ownerLabel))
644         return CKM_API_ERROR_INPUT_PARAM;
645
646     auto &handler = m_userDataMap[cred.uid];
647
648     // read rows
649     DB::Crypto::Transaction transaction(&handler.database);
650     int ec = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
651     if(CKM_API_SUCCESS != ec)
652         return ec;
653
654     // all read rows belong to the same owner
655     DB::Row & firstRow = rows.at(0);
656
657     // check access rights
658     ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
659     if(CKM_API_SUCCESS != ec)
660         return ec;
661
662     // decrypt row
663     if (!handler.crypto.haveKey(firstRow.ownerLabel)) {
664         RawBuffer key;
665         auto key_optional = handler.database.getKey(firstRow.ownerLabel);
666         if(!key_optional) {
667             LogError("No key for given label in database");
668             return CKM_API_ERROR_DB_ERROR;
669         }
670         key = *key_optional;
671         key = handler.keyProvider.getPureDEK(key);
672         handler.crypto.pushKey(firstRow.ownerLabel, key);
673     }
674     for(auto &row : rows)
675         handler.crypto.decryptRow(password, row);
676
677     return CKM_API_SUCCESS;
678 }
679
680 int CKMLogic::readDataHelper(
681     bool exportFlag,
682     const Credentials &cred,
683     DataType dataType,
684     const Name &name,
685     const Label &label,
686     const Password &password,
687     DB::Row &row)
688 {
689     if (0 == m_userDataMap.count(cred.uid))
690         return CKM_API_ERROR_DB_LOCKED;
691
692     // use client label if not explicitly provided
693     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
694
695     if (!isNameValid(name) || !isLabelValid(ownerLabel))
696         return CKM_API_ERROR_INPUT_PARAM;
697
698     auto &handler = m_userDataMap[cred.uid];
699
700     // read row
701     DB::Crypto::Transaction transaction(&handler.database);
702     int ec = readSingleRow(name, ownerLabel, dataType, handler.database, row);
703     if(CKM_API_SUCCESS != ec)
704         return ec;
705
706
707     // check access rights
708     ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
709     if(CKM_API_SUCCESS != ec)
710         return ec;
711
712     // decrypt row
713     if (!handler.crypto.haveKey(row.ownerLabel)) {
714         RawBuffer key;
715         auto key_optional = handler.database.getKey(row.ownerLabel);
716         if(!key_optional) {
717             LogError("No key for given label in database");
718             return CKM_API_ERROR_DB_ERROR;
719         }
720         key = *key_optional;
721         key = handler.keyProvider.getPureDEK(key);
722         handler.crypto.pushKey(row.ownerLabel, key);
723     }
724     handler.crypto.decryptRow(password, row);
725
726     return CKM_API_SUCCESS;
727 }
728
729 RawBuffer CKMLogic::getData(
730     const Credentials &cred,
731     int commandId,
732     DataType dataType,
733     const Name &name,
734     const Label &label,
735     const Password &password)
736 {
737     int retCode = CKM_API_SUCCESS;
738     DB::Row row;
739
740     try {
741         retCode = readDataHelper(true, cred, dataType, name, label, password, row);
742     } catch (const KeyProvider::Exception::Base &e) {
743         LogError("KeyProvider failed with error: " << e.GetMessage());
744         retCode = CKM_API_ERROR_SERVER_ERROR;
745     } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
746         LogError("CryptoLogic failed with message: " << e.GetMessage());
747         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
748     } catch (const CryptoLogic::Exception::Base &e) {
749         LogError("CryptoLogic failed with message: " << e.GetMessage());
750         retCode = CKM_API_ERROR_SERVER_ERROR;
751     } catch (const DB::Crypto::Exception::Base &e) {
752         LogError("DB::Crypto failed with message: " << e.GetMessage());
753         retCode = CKM_API_ERROR_DB_ERROR;
754     } catch (const CKM::Exception &e) {
755         LogError("CKM::Exception: " << e.GetMessage());
756         retCode = CKM_API_ERROR_SERVER_ERROR;
757     }
758
759     if (CKM_API_SUCCESS != retCode) {
760         row.data.clear();
761         row.dataType = dataType;
762     }
763
764     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
765                                              commandId,
766                                              retCode,
767                                              static_cast<int>(row.dataType),
768                                              row.data);
769     return response.Pop();
770 }
771
772 int CKMLogic::getPKCS12Helper(
773     const Credentials &cred,
774     const Name &name,
775     const Label &label,
776     const Password &keyPassword,
777     const Password &certPassword,
778     KeyShPtr & privKey,
779     CertificateShPtr & cert,
780     CertificateShPtrVector & caChain)
781 {
782     int retCode;
783
784     // read private key (mandatory)
785     DB::Row privKeyRow;
786     retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
787     if(retCode != CKM_API_SUCCESS)
788         return retCode;
789     privKey = CKM::Key::create(privKeyRow.data);
790
791     // read certificate (mandatory)
792     DB::Row certRow;
793     retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
794     if(retCode != CKM_API_SUCCESS)
795         return retCode;
796     cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
797
798     // read CA cert chain (optional)
799     DB::RowVector rawCaChain;
800     retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
801     if(retCode != CKM_API_SUCCESS &&
802        retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
803         return retCode;
804     for(auto &rawCaCert : rawCaChain)
805         caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
806
807     // if anything found, return it
808     if(privKey || cert || caChain.size()>0)
809         retCode = CKM_API_SUCCESS;
810
811     return retCode;
812 }
813
814 RawBuffer CKMLogic::getPKCS12(
815         const Credentials &cred,
816         int commandId,
817         const Name &name,
818         const Label &label,
819         const Password &keyPassword,
820         const Password &certPassword)
821 {
822     int retCode;
823     PKCS12Serializable output;
824
825     try {
826         KeyShPtr privKey;
827         CertificateShPtr cert;
828         CertificateShPtrVector caChain;
829         retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
830
831         // prepare response
832         if(retCode == CKM_API_SUCCESS)
833             output = PKCS12Serializable(privKey, cert, caChain);
834
835     } catch (const KeyProvider::Exception::Base &e) {
836         LogError("KeyProvider failed with error: " << e.GetMessage());
837         retCode = CKM_API_ERROR_SERVER_ERROR;
838     } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
839         LogError("CryptoLogic failed with message: " << e.GetMessage());
840         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
841     } catch (const CryptoLogic::Exception::Base &e) {
842         LogError("CryptoLogic failed with message: " << e.GetMessage());
843         retCode = CKM_API_ERROR_SERVER_ERROR;
844     } catch (const DB::Crypto::Exception::Base &e) {
845         LogError("DB::Crypto failed with message: " << e.GetMessage());
846         retCode = CKM_API_ERROR_DB_ERROR;
847     } catch (const CKM::Exception &e) {
848         LogError("CKM::Exception: " << e.GetMessage());
849         retCode = CKM_API_ERROR_SERVER_ERROR;
850     }
851
852     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
853                                              commandId,
854                                              retCode,
855                                              output);
856     return response.Pop();
857 }
858
859 RawBuffer CKMLogic::getDataList(
860     const Credentials &cred,
861     int commandId,
862     DataType dataType)
863 {
864     int retCode = CKM_API_SUCCESS;
865     LabelNameVector labelNameVector;
866
867     if (0 < m_userDataMap.count(cred.uid)) {
868         auto &database = m_userDataMap[cred.uid].database;
869
870         Try {
871             if (dataType.isKey()) {
872                 // list all key types
873                 database.listNames(cred.smackLabel,
874                                    labelNameVector,
875                                    DataType::DB_KEY_FIRST,
876                                    DataType::DB_KEY_LAST);
877             } else {
878                 // list anything else
879                 database.listNames(cred.smackLabel,
880                                    labelNameVector,
881                                    dataType);
882             }
883         }
884         Catch (CKM::Exception) {
885             LogError("Failed to get names");
886             retCode = CKM_API_ERROR_DB_ERROR;
887         }
888     } else {
889         retCode = CKM_API_ERROR_DB_LOCKED;
890     }
891
892     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
893                                              commandId,
894                                              retCode,
895                                              static_cast<int>(dataType),
896                                              labelNameVector);
897     return response.Pop();
898 }
899
900 int CKMLogic::saveDataHelper(
901     const Credentials &cred,
902     const Name &name,
903     const Label &label,
904     DataType dataType,
905     const RawBuffer &data,
906     const PolicySerializable &policy)
907 {
908     auto &handler = m_userDataMap[cred.uid];
909
910     // use client label if not explicitly provided
911     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
912
913     // check if save is possible
914     DB::Crypto::Transaction transaction(&handler.database);
915     int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
916     if(retCode != CKM_API_SUCCESS)
917         return retCode;
918
919     // save the data
920     DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
921     handler.database.saveRow(encryptedRow);
922
923     transaction.commit();
924     return CKM_API_SUCCESS;
925 }
926
927 int CKMLogic::saveDataHelper(
928     const Credentials &cred,
929     const Name &name,
930     const Label &label,
931     const PKCS12Serializable &pkcs,
932     const PolicySerializable &keyPolicy,
933     const PolicySerializable &certPolicy)
934 {
935     auto &handler = m_userDataMap[cred.uid];
936
937     // use client label if not explicitly provided
938     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
939
940     // check if save is possible
941     DB::Crypto::Transaction transaction(&handler.database);
942     int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
943     if(retCode != CKM_API_SUCCESS)
944         return retCode;
945
946     // extract and encrypt the data
947     DB::RowVector encryptedRows;
948     retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
949     if(retCode != CKM_API_SUCCESS)
950         return retCode;
951
952     // save the data
953     handler.database.saveRows(name, ownerLabel, encryptedRows);
954     transaction.commit();
955
956     return CKM_API_SUCCESS;
957 }
958
959
960 int CKMLogic::createKeyPairHelper(
961     const Credentials &cred,
962     const KeyType key_type,
963     const int additional_param,
964     const Name &namePrivate,
965     const Label &labelPrivate,
966     const Name &namePublic,
967     const Label &labelPublic,
968     const PolicySerializable &policyPrivate,
969     const PolicySerializable &policyPublic)
970 {
971     if (0 == m_userDataMap.count(cred.uid))
972         return CKM_API_ERROR_DB_LOCKED;
973
974     KeyImpl prv, pub;
975     int retCode;
976     switch(key_type)
977     {
978         case KeyType::KEY_RSA_PUBLIC:
979         case KeyType::KEY_RSA_PRIVATE:
980             retCode = Crypto::SW::CryptoService::createKeyPairRSA(additional_param, prv, pub);
981             break;
982
983         case KeyType::KEY_DSA_PUBLIC:
984         case KeyType::KEY_DSA_PRIVATE:
985             retCode = Crypto::SW::CryptoService::createKeyPairDSA(additional_param, prv, pub);
986             break;
987
988         case KeyType::KEY_ECDSA_PUBLIC:
989         case KeyType::KEY_ECDSA_PRIVATE:
990             retCode = Crypto::SW::CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
991             break;
992
993         default:
994             return CKM_API_ERROR_INPUT_PARAM;
995     }
996
997     if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
998     {
999         LogDebug("CryptoService error with code: " << retCode);
1000         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
1001     }
1002
1003     auto &database = m_userDataMap[cred.uid].database;
1004     DB::Crypto::Transaction transaction(&database);
1005
1006     retCode = saveDataHelper(cred,
1007                              namePrivate,
1008                              labelPrivate,
1009                              DataType(prv.getType()),
1010                              prv.getDER(),
1011                              policyPrivate);
1012     if (CKM_API_SUCCESS != retCode)
1013         return retCode;
1014
1015     retCode = saveDataHelper(cred,
1016                              namePublic,
1017                              labelPublic,
1018                              DataType(pub.getType()),
1019                              pub.getDER(),
1020                              policyPublic);
1021     if (CKM_API_SUCCESS != retCode)
1022         return retCode;
1023
1024     transaction.commit();
1025
1026     return retCode;
1027 }
1028
1029 RawBuffer CKMLogic::createKeyPair(
1030     const Credentials &cred,
1031     LogicCommand protocol_cmd,
1032     int commandId,
1033     const int additional_param,
1034     const Name &namePrivate,
1035     const Label &labelPrivate,
1036     const Name &namePublic,
1037     const Label &labelPublic,
1038     const PolicySerializable &policyPrivate,
1039     const PolicySerializable &policyPublic)
1040 {
1041     int retCode = CKM_API_SUCCESS;
1042
1043     KeyType key_type = KeyType::KEY_NONE;
1044     switch(protocol_cmd)
1045     {
1046         case LogicCommand::CREATE_KEY_PAIR_RSA:
1047             key_type = KeyType::KEY_RSA_PUBLIC;
1048             break;
1049         case LogicCommand::CREATE_KEY_PAIR_DSA:
1050             key_type = KeyType::KEY_DSA_PUBLIC;
1051             break;
1052         case LogicCommand::CREATE_KEY_PAIR_ECDSA:
1053             key_type = KeyType::KEY_ECDSA_PUBLIC;
1054             break;
1055         default:
1056             break;
1057     }
1058
1059     try {
1060         retCode = createKeyPairHelper(
1061                         cred,
1062                         key_type,
1063                         additional_param,
1064                         namePrivate,
1065                         labelPrivate,
1066                         namePublic,
1067                         labelPublic,
1068                         policyPrivate,
1069                         policyPublic);
1070     } catch (DB::Crypto::Exception::TransactionError &e) {
1071         LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1072         retCode = CKM_API_ERROR_DB_ERROR;
1073     } catch (CKM::CryptoLogic::Exception::Base &e) {
1074         LogDebug("CryptoLogic error: " << e.GetMessage());
1075         retCode = CKM_API_ERROR_SERVER_ERROR;
1076     } catch (DB::Crypto::Exception::InternalError &e) {
1077         LogDebug("DB::Crypto internal error: " << e.GetMessage());
1078         retCode = CKM_API_ERROR_DB_ERROR;
1079     } catch (const CKM::Exception &e) {
1080         LogError("CKM::Exception: " << e.GetMessage());
1081         retCode = CKM_API_ERROR_SERVER_ERROR;
1082     }
1083
1084     return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
1085 }
1086
1087 int CKMLogic::readCertificateHelper(
1088         const Credentials &cred,
1089         const LabelNameVector &labelNameVector,
1090         CertificateImplVector &certVector)
1091 {
1092     DB::Row row;
1093     for (auto &i: labelNameVector) {
1094         int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1095         if (ec != CKM_API_SUCCESS)
1096             return ec;
1097         certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1098
1099         // try to read chain certificates (if present)
1100         DB::RowVector rawCaChain;
1101         ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1102         if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1103             return ec;
1104         for(auto &rawCaCert : rawCaChain)
1105             certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1106     }
1107     return CKM_API_SUCCESS;
1108 }
1109
1110 int CKMLogic::getCertificateChainHelper(
1111         const CertificateImpl &cert,
1112         const RawBufferVector &untrustedCertificates,
1113         const RawBufferVector &trustedCertificates,
1114         bool useTrustedSystemCertificates,
1115         RawBufferVector &chainRawVector)
1116 {
1117     CertificateImplVector untrustedCertVector;
1118     CertificateImplVector trustedCertVector;
1119     CertificateImplVector chainVector;
1120
1121     if (cert.empty())
1122         return CKM_API_ERROR_INPUT_PARAM;
1123
1124     for (auto &e: untrustedCertificates)
1125         untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1126     for (auto &e: trustedCertificates)
1127         trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1128
1129     CertificateStore store;
1130     int retCode = store.verifyCertificate(cert,
1131                                           untrustedCertVector,
1132                                           trustedCertVector,
1133                                           useTrustedSystemCertificates,
1134                                           m_accessControl.isCCMode(),
1135                                           chainVector);
1136     if (retCode != CKM_API_SUCCESS)
1137         return retCode;
1138
1139     for (auto &e : chainVector)
1140         chainRawVector.push_back(e.getDER());
1141     return CKM_API_SUCCESS;
1142 }
1143
1144 int CKMLogic::getCertificateChainHelper(
1145         const Credentials &cred,
1146         const CertificateImpl &cert,
1147         const LabelNameVector &untrusted,
1148         const LabelNameVector &trusted,
1149         bool useTrustedSystemCertificates,
1150         RawBufferVector &chainRawVector)
1151 {
1152     CertificateImplVector untrustedCertVector;
1153     CertificateImplVector trustedCertVector;
1154     CertificateImplVector chainVector;
1155     DB::Row row;
1156
1157     if (cert.empty())
1158         return CKM_API_ERROR_INPUT_PARAM;
1159
1160     int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1161     if (retCode != CKM_API_SUCCESS)
1162         return retCode;
1163     retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1164     if (retCode != CKM_API_SUCCESS)
1165         return retCode;
1166
1167     CertificateStore store;
1168     retCode = store.verifyCertificate(cert,
1169                                       untrustedCertVector,
1170                                       trustedCertVector,
1171                                       useTrustedSystemCertificates,
1172                                       m_accessControl.isCCMode(),
1173                                       chainVector);
1174     if (retCode != CKM_API_SUCCESS)
1175         return retCode;
1176
1177     for (auto &i: chainVector)
1178         chainRawVector.push_back(i.getDER());
1179
1180     return CKM_API_SUCCESS;
1181 }
1182
1183 RawBuffer CKMLogic::getCertificateChain(
1184     const Credentials & /*cred*/,
1185     int commandId,
1186     const RawBuffer &certificate,
1187     const RawBufferVector &untrustedCertificates,
1188     const RawBufferVector &trustedCertificates,
1189     bool useTrustedSystemCertificates)
1190 {
1191     CertificateImpl cert(certificate, DataFormat::FORM_DER);
1192     RawBufferVector chainRawVector;
1193     int retCode = CKM_API_ERROR_UNKNOWN;
1194     try {
1195         retCode = getCertificateChainHelper(cert,
1196                                             untrustedCertificates,
1197                                             trustedCertificates,
1198                                             useTrustedSystemCertificates,
1199                                             chainRawVector);
1200     } catch (const CryptoLogic::Exception::Base &e) {
1201         LogError("CryptoLogic failed with message: " << e.GetMessage());
1202         retCode = CKM_API_ERROR_SERVER_ERROR;
1203     } catch (const DB::Crypto::Exception::Base &e) {
1204         LogError("DB::Crypto failed with message: " << e.GetMessage());
1205         retCode = CKM_API_ERROR_DB_ERROR;
1206     } catch (const std::exception& e) {
1207         LogError("STD exception " << e.what());
1208         retCode = CKM_API_ERROR_SERVER_ERROR;
1209     } catch (...) {
1210         LogError("Unknown error.");
1211     }
1212
1213     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1214                                              commandId,
1215                                              retCode,
1216                                              chainRawVector);
1217     return response.Pop();
1218 }
1219
1220 RawBuffer CKMLogic::getCertificateChain(
1221     const Credentials &cred,
1222     int commandId,
1223     const RawBuffer &certificate,
1224     const LabelNameVector &untrustedCertificates,
1225     const LabelNameVector &trustedCertificates,
1226     bool useTrustedSystemCertificates)
1227 {
1228     int retCode = CKM_API_ERROR_UNKNOWN;
1229     CertificateImpl cert(certificate, DataFormat::FORM_DER);
1230     RawBufferVector chainRawVector;
1231     try {
1232         retCode = getCertificateChainHelper(cred,
1233                                             cert,
1234                                             untrustedCertificates,
1235                                             trustedCertificates,
1236                                             useTrustedSystemCertificates,
1237                                             chainRawVector);
1238     } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1239         LogError("CryptoLogic failed with message: " << e.GetMessage());
1240         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1241     } catch (const CryptoLogic::Exception::Base &e) {
1242         LogError("CryptoLogic failed with message: " << e.GetMessage());
1243         retCode = CKM_API_ERROR_SERVER_ERROR;
1244     } catch (const DB::Crypto::Exception::Base &e) {
1245         LogError("DB::Crypto failed with message: " << e.GetMessage());
1246         retCode = CKM_API_ERROR_DB_ERROR;
1247     } catch (const std::exception& e) {
1248         LogError("STD exception " << e.what());
1249         retCode = CKM_API_ERROR_SERVER_ERROR;
1250     } catch (...) {
1251         LogError("Unknown error.");
1252     }
1253
1254     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1255                                              commandId,
1256                                              retCode,
1257                                              chainRawVector);
1258     return response.Pop();
1259 }
1260
1261 RawBuffer CKMLogic::createSignature(
1262         const Credentials &cred,
1263         int commandId,
1264         const Name &privateKeyName,
1265         const Label & ownerLabel,
1266         const Password &password,           // password for private_key
1267         const RawBuffer &message,
1268         const HashAlgorithm hash,
1269         const RSAPaddingAlgorithm padding)
1270 {
1271     DB::Row row;
1272     Crypto::SW::CryptoService cs;
1273     RawBuffer signature;
1274
1275     int retCode = CKM_API_SUCCESS;
1276
1277     try {
1278         retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1279         if(retCode == CKM_API_SUCCESS)
1280         {
1281             KeyImpl keyParsed(row.data, Password());
1282             if (keyParsed.empty())
1283                 retCode = CKM_API_ERROR_SERVER_ERROR;
1284             else
1285                 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
1286         }
1287     } catch (const KeyProvider::Exception::Base &e) {
1288         LogError("KeyProvider failed with message: " << e.GetMessage());
1289         retCode = CKM_API_ERROR_SERVER_ERROR;
1290     } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1291         LogError("CryptoLogic failed with message: " << e.GetMessage());
1292         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1293     } catch (const CryptoLogic::Exception::Base &e) {
1294         LogError("CryptoLogic failed with message: " << e.GetMessage());
1295         retCode = CKM_API_ERROR_SERVER_ERROR;
1296     } catch (const DB::Crypto::Exception::Base &e) {
1297         LogError("DB::Crypto failed with message: " << e.GetMessage());
1298         retCode = CKM_API_ERROR_DB_ERROR;
1299     } catch (const CKM::Exception &e) {
1300         LogError("Unknown CKM::Exception: " << e.GetMessage());
1301         retCode = CKM_API_ERROR_SERVER_ERROR;
1302     }
1303
1304     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1305                                              commandId,
1306                                              retCode,
1307                                              signature);
1308     return response.Pop();
1309 }
1310
1311 RawBuffer CKMLogic::verifySignature(
1312         const Credentials &cred,
1313         int commandId,
1314         const Name &publicKeyOrCertName,
1315         const Label & ownerLabel,
1316         const Password &password,           // password for public_key (optional)
1317         const RawBuffer &message,
1318         const RawBuffer &signature,
1319         const HashAlgorithm hash,
1320         const RSAPaddingAlgorithm padding)
1321 {
1322     int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1323
1324     try {
1325         do {
1326             Crypto::SW::CryptoService cs;
1327             DB::Row row;
1328             KeyImpl key;
1329
1330             // try certificate first - looking for a public key.
1331             // in case of PKCS, pub key from certificate will be found first
1332             // rather than private key from the same PKCS.
1333             retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
1334             if (retCode == CKM_API_SUCCESS) {
1335                 CertificateImpl cert(row.data, DataFormat::FORM_DER);
1336                 key = cert.getKeyImpl();
1337             } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1338                 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
1339                 if (retCode != CKM_API_SUCCESS)
1340                     break;
1341                 key = KeyImpl(row.data);
1342             } else {
1343                 break;
1344             }
1345
1346             if (key.empty()) {
1347                 retCode = CKM_API_ERROR_SERVER_ERROR;
1348                 break;
1349             }
1350
1351             retCode = cs.verifySignature(key, message, signature, hash, padding);
1352         } while(0);
1353     } catch (const Crypto::SW::CryptoService::Exception::Crypto_internal &e) {
1354         LogError("KeyProvider failed with message: " << e.GetMessage());
1355         retCode = CKM_API_ERROR_SERVER_ERROR;
1356     } catch (const Crypto::SW::CryptoService::Exception::opensslError &e) {
1357         LogError("KeyProvider failed with message: " << e.GetMessage());
1358         retCode = CKM_API_ERROR_SERVER_ERROR;
1359     } catch (const KeyProvider::Exception::Base &e) {
1360         LogError("KeyProvider failed with error: " << e.GetMessage());
1361         retCode = CKM_API_ERROR_SERVER_ERROR;
1362     } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1363         LogError("CryptoLogic failed with message: " << e.GetMessage());
1364         retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1365     } catch (const CryptoLogic::Exception::Base &e) {
1366         LogError("CryptoLogic failed with message: " << e.GetMessage());
1367         retCode = CKM_API_ERROR_SERVER_ERROR;
1368     } catch (const DB::Crypto::Exception::Base &e) {
1369         LogError("DB::Crypto failed with message: " << e.GetMessage());
1370         retCode = CKM_API_ERROR_DB_ERROR;
1371     } catch (const CKM::Exception &e) {
1372         LogError("Unknown CKM::Exception: " << e.GetMessage());
1373         retCode = CKM_API_ERROR_SERVER_ERROR;
1374     }
1375
1376     auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1377                                              commandId,
1378                                              retCode);
1379     return response.Pop();
1380 }
1381
1382 int CKMLogic::setPermissionHelper(
1383         const Credentials &cred,                // who's the client
1384         const Name &name,
1385         const Label &label,                     // who's the owner
1386         const Label &accessorLabel,             // who will get the access
1387         const PermissionMask permissionMask)
1388 {
1389     // we don't know the client
1390     if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1391         return CKM_API_ERROR_INPUT_PARAM;
1392
1393     // use client label if not explicitly provided
1394     const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1395
1396     // verify name and label are correct
1397     if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1398         return CKM_API_ERROR_INPUT_PARAM;
1399
1400     // currently we don't support modification of owner's permissions to his own rows
1401     if (ownerLabel==accessorLabel)
1402         return CKM_API_ERROR_INPUT_PARAM;
1403
1404     // can the client modify permissions to owner's row?
1405     int access_ec = m_accessControl.canModify(ownerLabel, cred.smackLabel);
1406     if(access_ec != CKM_API_SUCCESS)
1407         return access_ec;
1408
1409     if (0 == m_userDataMap.count(cred.uid))
1410         return CKM_API_ERROR_DB_LOCKED;
1411
1412     auto &database = m_userDataMap[cred.uid].database;
1413     DB::Crypto::Transaction transaction(&database);
1414
1415     if( !database.isNameLabelPresent(name, ownerLabel) )
1416         return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1417
1418     // removing non-existing permissions: fail
1419     if(permissionMask == Permission::NONE)
1420     {
1421         if(!database.getPermissionRow(name, ownerLabel, accessorLabel))
1422             return CKM_API_ERROR_INPUT_PARAM;
1423     }
1424
1425     // set permissions to the row owned by ownerLabel for accessorLabel
1426     database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1427     transaction.commit();
1428
1429     return CKM_API_SUCCESS;
1430 }
1431
1432 RawBuffer CKMLogic::setPermission(
1433         const Credentials &cred,
1434         const int command,
1435         const int msgID,
1436         const Name &name,
1437         const Label &label,
1438         const Label &accessorLabel,
1439         const PermissionMask permissionMask)
1440 {
1441     int retCode;
1442     Try {
1443         retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1444     } Catch (CKM::Exception) {
1445         LogError("Error in set row!");
1446         retCode = CKM_API_ERROR_DB_ERROR;
1447     }
1448
1449     return MessageBuffer::Serialize(command, msgID, retCode).Pop();
1450 }
1451
1452 } // namespace CKM
1453