2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
18 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
20 * @brief Sample service implementation.
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>
30 #include <certificate-config.h>
31 #include <certificate-store.h>
33 #include <sw-backend/crypto-service.h>
36 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
37 const uid_t SYSTEM_DB_UID = 0;
38 const char * const SYSTEM_DB_PASSWD = "cAtRugU7";
40 bool isLabelValid(const CKM::Label &label) {
41 // TODO: copy code from libprivilege control (for check smack label)
42 if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
47 bool isNameValid(const CKM::Name &name) {
48 if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
52 } // anonymous namespace
58 CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
60 m_accessControl.updateCCMode();
63 CKMLogic::~CKMLogic(){}
65 void CKMLogic::loadDKEKFile(uid_t user, const Password &password) {
66 auto &handle = m_userDataMap[user];
70 auto wrappedDKEK = fs.getDKEK();
72 if (wrappedDKEK.empty()) {
73 wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
74 fs.saveDKEK(wrappedDKEK);
77 handle.keyProvider = KeyProvider(wrappedDKEK, password);
80 void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
81 auto &handle = m_userDataMap[user];
84 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
87 int CKMLogic::unlockDatabase(uid_t user, const Password & password)
89 if (0<m_userDataMap.count(user) && m_userDataMap[user].keyProvider.isInitialized())
90 return CKM_API_SUCCESS;
92 int retCode = CKM_API_SUCCESS;
95 auto &handle = m_userDataMap[user];
98 loadDKEKFile(user, password);
100 auto wrappedDatabaseDEK = fs.getDBDEK();
101 if (wrappedDatabaseDEK.empty()) {
102 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
103 fs.saveDBDEK(wrappedDatabaseDEK);
106 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
108 handle.database = DB::Crypto(fs.getDBPath(), key);
109 handle.crypto = CryptoLogic();
111 if ( !m_accessControl.isSystemService(user) )
113 // remove data of removed apps during locked state
114 AppLabelVector removedApps = fs.clearRemovedsApps();
115 for(auto& appSmackLabel : removedApps) {
116 handle.database.deleteKey(appSmackLabel);
119 } catch (const KeyProvider::Exception::PassWordError &e) {
120 LogError("Incorrect Password " << e.GetMessage());
121 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
122 } catch (const KeyProvider::Exception::Base &e) {
123 LogError("Error in KeyProvider " << e.GetMessage());
124 retCode = CKM_API_ERROR_SERVER_ERROR;
125 } catch (const CryptoLogic::Exception::Base &e) {
126 LogError("CryptoLogic error: " << e.GetMessage());
127 retCode = CKM_API_ERROR_SERVER_ERROR;
128 } catch (const FileSystem::Exception::Base &e) {
129 LogError("FileSystem error: " << e.GetMessage());
130 retCode = CKM_API_ERROR_FILE_SYSTEM;
131 } catch (const CKM::Exception &e) {
132 LogError("CKM::Exception: " << e.GetMessage());
133 retCode = CKM_API_ERROR_SERVER_ERROR;
136 if (CKM_API_SUCCESS != retCode)
137 m_userDataMap.erase(user);
142 int CKMLogic::unlockSystemDB()
144 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
147 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
149 // if user trying to access system service - check:
150 // * if user database is unlocked [mandatory]
151 // * if not - proceed with regular user database
152 // * if explicit system database label given -> switch to system DB
153 if ( !m_accessControl.isSystemService(cred) )
155 if (0 == m_userDataMap.count(cred.clientUid))
156 ThrowMsg(Exception::DatabaseLocked, "database with UID: " << cred.clientUid << " locked");
158 if (0 != incoming_label.compare(LABEL_SYSTEM_DB))
159 return m_userDataMap[cred.clientUid];
162 // system database selected, modify the label
163 if (CKM_API_SUCCESS != unlockSystemDB() )
164 ThrowMsg(Exception::DatabaseLocked, "can not unlock system database");
165 return m_userDataMap[SYSTEM_DB_UID];
168 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
170 int retCode = CKM_API_SUCCESS;
172 if( !m_accessControl.isSystemService(user) )
174 retCode = unlockDatabase(user, password);
178 // do not allow lock/unlock operations for system users
179 retCode = CKM_API_ERROR_INPUT_PARAM;
182 return MessageBuffer::Serialize(retCode).Pop();
185 RawBuffer CKMLogic::updateCCMode() {
186 m_accessControl.updateCCMode();
187 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
190 RawBuffer CKMLogic::lockUserKey(uid_t user)
192 int retCode = CKM_API_SUCCESS;
193 if( !m_accessControl.isSystemService(user) )
195 m_userDataMap.erase(user);
199 // do not allow lock/unlock operations for system users
200 retCode = CKM_API_ERROR_INPUT_PARAM;
203 return MessageBuffer::Serialize(retCode).Pop();
207 RawBuffer CKMLogic::removeUserData(uid_t user) {
208 int retCode = CKM_API_SUCCESS;
210 if (m_accessControl.isSystemService(user))
211 user = SYSTEM_DB_UID;
213 m_userDataMap.erase(user);
218 return MessageBuffer::Serialize(retCode).Pop();
221 int CKMLogic::changeUserPasswordHelper(uid_t user,
222 const Password &oldPassword,
223 const Password &newPassword)
225 // do not allow to change system database password
226 if( m_accessControl.isSystemService(user) )
227 return CKM_API_ERROR_INPUT_PARAM;
229 loadDKEKFile(user, oldPassword);
230 saveDKEKFile(user, newPassword);
232 return CKM_API_SUCCESS;
235 RawBuffer CKMLogic::changeUserPassword(
237 const Password &oldPassword,
238 const Password &newPassword)
240 int retCode = CKM_API_SUCCESS;
243 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
244 } catch (const KeyProvider::Exception::PassWordError &e) {
245 LogError("Incorrect Password " << e.GetMessage());
246 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
247 } catch (const KeyProvider::Exception::Base &e) {
248 LogError("Error in KeyProvider " << e.GetMessage());
249 retCode = CKM_API_ERROR_SERVER_ERROR;
250 } catch (const FileSystem::Exception::Base &e) {
251 LogError("Error in FileSystem " << e.GetMessage());
252 retCode = CKM_API_ERROR_FILE_SYSTEM;
253 } catch (const CKM::Exception &e) {
254 LogError("CKM::Exception: " << e.GetMessage());
255 retCode = CKM_API_ERROR_SERVER_ERROR;
258 return MessageBuffer::Serialize(retCode).Pop();
261 int CKMLogic::resetUserPasswordHelper(
263 const Password &newPassword)
265 // do not allow to reset system database password
266 if( m_accessControl.isSystemService(user) )
267 return CKM_API_ERROR_INPUT_PARAM;
269 int retCode = CKM_API_SUCCESS;
270 if (0 == m_userDataMap.count(user))
272 // Check if key exists. If exists we must return error
274 auto wrappedDKEKMain = fs.getDKEK();
275 if (!wrappedDKEKMain.empty())
276 retCode = CKM_API_ERROR_BAD_REQUEST;
278 saveDKEKFile(user, newPassword);
284 RawBuffer CKMLogic::resetUserPassword(
286 const Password &newPassword)
288 int retCode = CKM_API_SUCCESS;
290 retCode = resetUserPasswordHelper(user, newPassword);
291 } catch (const FileSystem::Exception::Base &e) {
292 LogError("Error in FileSystem " << e.GetMessage());
293 retCode = CKM_API_ERROR_FILE_SYSTEM;
294 } catch (const CKM::Exception &e) {
295 LogError("CKM::Exception: " << e.GetMessage());
296 retCode = CKM_API_ERROR_SERVER_ERROR;
299 return MessageBuffer::Serialize(retCode).Pop();
302 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
303 int retCode = CKM_API_SUCCESS;
307 if (smackLabel.empty()) {
308 retCode = CKM_API_ERROR_INPUT_PARAM;
310 UidVector uids = FileSystem::getUIDsFromDBFile();
311 for (auto userId : uids) {
312 if (0 == m_userDataMap.count(userId)) {
313 FileSystem fs(userId);
314 fs.addRemovedApp(smackLabel);
316 auto &handle = m_userDataMap[userId];
317 handle.database.deleteKey(smackLabel);
322 } catch (const DB::Crypto::Exception::InternalError &e) {
323 LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
324 retCode = CKM_API_ERROR_DB_ERROR;
325 } catch (const DB::Crypto::Exception::TransactionError &e) {
326 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
327 retCode = CKM_API_ERROR_DB_ERROR;
328 } catch (const FileSystem::Exception::Base &e) {
329 LogError("Error in FileSystem " << e.GetMessage());
330 retCode = CKM_API_ERROR_FILE_SYSTEM;
331 } catch (const CKM::Exception &e) {
332 LogError("CKM::Exception: " << e.GetMessage());
333 retCode = CKM_API_ERROR_SERVER_ERROR;
336 return MessageBuffer::Serialize(retCode).Pop();
339 int CKMLogic::checkSaveConditions(
340 const Credentials &cred,
343 const Label &ownerLabel)
345 // verify name and label are correct
346 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
347 LogWarning("Invalid parameter passed to key-manager");
348 return CKM_API_ERROR_INPUT_PARAM;
351 // check if allowed to save using ownerLabel
352 int access_ec = m_accessControl.canSave(cred, ownerLabel);
353 if( access_ec != CKM_API_SUCCESS)
355 LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
359 // check if not a duplicate
360 if( handler.database.isNameLabelPresent(name, ownerLabel))
361 return CKM_API_ERROR_DB_ALIAS_EXISTS;
363 // encryption section
364 if (!handler.crypto.haveKey(ownerLabel))
367 auto key_optional = handler.database.getKey(ownerLabel);
369 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
370 got_key = handler.keyProvider.generateDEK(ownerLabel);
371 handler.database.saveKey(ownerLabel, got_key);
373 LogDebug("Key from DB");
374 got_key = *key_optional;
377 got_key = handler.keyProvider.getPureDEK(got_key);
378 handler.crypto.pushKey(ownerLabel, got_key);
381 return CKM_API_SUCCESS;
384 DB::Row CKMLogic::createEncryptedRow(
389 const RawBuffer &data,
390 const Policy &policy) const
392 DB::Row row(name, label, static_cast<int>(policy.extractable), dataType, data, static_cast<int>(data.size()));
394 // do not encrypt data with password during cc_mode on
395 if(m_accessControl.isCCMode()) {
396 crypto.encryptRow("", row);
398 crypto.encryptRow(policy.password, row);
403 int CKMLogic::verifyBinaryData(DataType dataType, const RawBuffer &input_data) const
405 // verify the data integrity
406 if (dataType.isKey())
408 KeyShPtr output_key = CKM::Key::create(input_data);
409 if(output_key.get() == NULL)
411 LogError("provided binary data is not valid key data");
412 return CKM_API_ERROR_INPUT_PARAM;
415 else if (dataType.isCertificate() || dataType.isChainCert())
417 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
418 if(cert.get() == NULL)
420 LogError("provided binary data is not valid certificate data");
421 return CKM_API_ERROR_INPUT_PARAM;
424 // TODO: add here BINARY_DATA verification, i.e: max size etc.
425 return CKM_API_SUCCESS;
428 RawBuffer CKMLogic::saveData(
429 const Credentials &cred,
433 const RawBuffer &data,
435 const PolicySerializable &policy)
437 int retCode = CKM_API_ERROR_UNKNOWN;
440 // check if data is correct
441 retCode = verifyBinaryData(dataType, data);
442 if(retCode == CKM_API_SUCCESS)
444 retCode = saveDataHelper(cred, name, label, dataType, data, policy);
446 } catch (const KeyProvider::Exception::Base &e) {
447 LogError("KeyProvider failed with message: " << e.GetMessage());
448 retCode = CKM_API_ERROR_SERVER_ERROR;
449 } catch (const CryptoLogic::Exception::Base &e) {
450 LogError("CryptoLogic failed with message: " << e.GetMessage());
451 retCode = CKM_API_ERROR_SERVER_ERROR;
452 } catch (const DB::Crypto::Exception::InternalError &e) {
453 LogError("DB::Crypto failed with message: " << e.GetMessage());
454 retCode = CKM_API_ERROR_DB_ERROR;
455 } catch (const DB::Crypto::Exception::TransactionError &e) {
456 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
457 retCode = CKM_API_ERROR_DB_ERROR;
458 } catch (const FileSystem::Exception::Base &e) {
459 LogError("Error in FileSystem " << e.GetMessage());
460 retCode = CKM_API_ERROR_FILE_SYSTEM;
461 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
462 LogError("Error " << e.GetMessage());
463 retCode = CKM_API_ERROR_DB_LOCKED;
464 } catch (const CKM::Exception &e) {
465 LogError("CKM::Exception: " << e.GetMessage());
466 retCode = CKM_API_ERROR_SERVER_ERROR;
469 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
472 static_cast<int>(dataType));
473 return response.Pop();
476 int CKMLogic::extractPKCS12Data(
479 const Label &ownerLabel,
480 const PKCS12Serializable &pkcs,
481 const PolicySerializable &keyPolicy,
482 const PolicySerializable &certPolicy,
483 DB::RowVector &output) const
485 // private key is mandatory
487 return CKM_API_ERROR_INVALID_FORMAT;
488 Key* keyPtr = pkcs.getKey().get();
489 DataType keyType = DataType(keyPtr->getType());
490 RawBuffer keyData = keyPtr->getDER();
491 int retCode = verifyBinaryData(keyType, keyData);
492 if(retCode != CKM_API_SUCCESS)
494 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
496 // certificate is mandatory
497 if( !pkcs.getCertificate() )
498 return CKM_API_ERROR_INVALID_FORMAT;
499 RawBuffer certData = pkcs.getCertificate().get()->getDER();
500 retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
501 if(retCode != CKM_API_SUCCESS)
503 output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
506 unsigned int cert_index = 0;
507 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
509 DataType chainDataType = DataType::getChainDatatype(cert_index ++);
510 RawBuffer caCertData = ca->getDER();
511 int retCode = verifyBinaryData(chainDataType, caCertData);
512 if(retCode != CKM_API_SUCCESS)
515 output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
518 return CKM_API_SUCCESS;
521 RawBuffer CKMLogic::savePKCS12(
522 const Credentials &cred,
526 const PKCS12Serializable &pkcs,
527 const PolicySerializable &keyPolicy,
528 const PolicySerializable &certPolicy)
530 int retCode = CKM_API_ERROR_UNKNOWN;
532 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
533 } catch (const KeyProvider::Exception::Base &e) {
534 LogError("KeyProvider failed with message: " << e.GetMessage());
535 retCode = CKM_API_ERROR_SERVER_ERROR;
536 } catch (const CryptoLogic::Exception::Base &e) {
537 LogError("CryptoLogic failed with message: " << e.GetMessage());
538 retCode = CKM_API_ERROR_SERVER_ERROR;
539 } catch (const DB::Crypto::Exception::InternalError &e) {
540 LogError("DB::Crypto failed with message: " << e.GetMessage());
541 retCode = CKM_API_ERROR_DB_ERROR;
542 } catch (const DB::Crypto::Exception::TransactionError &e) {
543 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
544 retCode = CKM_API_ERROR_DB_ERROR;
545 } catch (const CKM::Exception &e) {
546 LogError("CKM::Exception: " << e.GetMessage());
547 retCode = CKM_API_ERROR_SERVER_ERROR;
550 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
553 return response.Pop();
557 int CKMLogic::removeDataHelper(
558 const Credentials &cred,
562 auto &handler = selectDatabase(cred, label);
564 // use client label if not explicitly provided
565 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
566 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
567 LogError("Invalid label or name format");
568 return CKM_API_ERROR_INPUT_PARAM;
571 DB::Crypto::Transaction transaction(&handler.database);
573 // read and check permissions
574 PermissionMaskOptional permissionRowOpt =
575 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
576 int retCode = m_accessControl.canDelete(cred,
577 PermissionForLabel(cred.smackLabel, permissionRowOpt));
578 if(retCode != CKM_API_SUCCESS)
580 LogWarning("access control check result: " << retCode);
584 auto erased = handler.database.deleteRow(name, ownerLabel);
585 // check if the data existed or not
587 transaction.commit();
589 LogError("No row for given name and label");
590 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
593 return CKM_API_SUCCESS;
596 RawBuffer CKMLogic::removeData(
597 const Credentials &cred,
602 int retCode = CKM_API_ERROR_UNKNOWN;
606 retCode = removeDataHelper(cred, name, label);
608 catch (const CKMLogic::Exception::DatabaseLocked &e)
610 LogError("Error " << e.GetMessage());
611 retCode = CKM_API_ERROR_DB_LOCKED;
613 catch (const CKM::Exception &)
615 LogError("Error in deleting row!");
616 retCode = CKM_API_ERROR_DB_ERROR;
619 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
622 return response.Pop();
625 int CKMLogic::readSingleRow(const Name &name,
626 const Label &ownerLabel,
628 DB::Crypto & database,
631 DB::Crypto::RowOptional row_optional;
632 if (dataType.isKey())
634 // read all key types
635 row_optional = database.getRow(name,
637 DataType::DB_KEY_FIRST,
638 DataType::DB_KEY_LAST);
640 // read anything else
641 row_optional = database.getRow(name,
647 LogError("No row for given name, label and type");
648 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
653 return CKM_API_SUCCESS;
657 int CKMLogic::readMultiRow(const Name &name,
658 const Label &ownerLabel,
660 DB::Crypto & database,
661 DB::RowVector &output)
663 if (dataType.isKey())
665 // read all key types
666 database.getRows(name,
668 DataType::DB_KEY_FIRST,
669 DataType::DB_KEY_LAST,
672 else if (dataType.isChainCert())
674 // read all key types
675 database.getRows(name,
677 DataType::DB_CHAIN_FIRST,
678 DataType::DB_CHAIN_LAST,
683 // read anything else
684 database.getRows(name,
691 LogError("No row for given name, label and type");
692 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
695 return CKM_API_SUCCESS;
698 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
700 const Label &ownerLabel,
701 const Label &accessorLabel,
704 DB::Crypto & database)
706 PermissionMaskOptional permissionRowOpt =
707 database.getPermissionRow(name, ownerLabel, accessorLabel);
710 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
711 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
714 int CKMLogic::readDataHelper(
716 const Credentials &cred,
720 const Password &password,
723 auto &handler = selectDatabase(cred, label);
725 // use client label if not explicitly provided
726 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
728 if (!isNameValid(name) || !isLabelValid(ownerLabel))
729 return CKM_API_ERROR_INPUT_PARAM;
732 DB::Crypto::Transaction transaction(&handler.database);
733 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
734 if(CKM_API_SUCCESS != retCode)
737 // all read rows belong to the same owner
738 DB::Row & firstRow = rows.at(0);
740 // check access rights
741 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
742 if(CKM_API_SUCCESS != retCode)
746 if (!handler.crypto.haveKey(firstRow.ownerLabel)) {
748 auto key_optional = handler.database.getKey(firstRow.ownerLabel);
750 LogError("No key for given label in database");
751 return CKM_API_ERROR_DB_ERROR;
754 key = handler.keyProvider.getPureDEK(key);
755 handler.crypto.pushKey(firstRow.ownerLabel, key);
757 for(auto &row : rows)
758 handler.crypto.decryptRow(password, row);
760 return CKM_API_SUCCESS;
763 int CKMLogic::readDataHelper(
765 const Credentials &cred,
769 const Password &password,
772 auto &handler = selectDatabase(cred, label);
774 // use client label if not explicitly provided
775 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
777 if (!isNameValid(name) || !isLabelValid(ownerLabel))
778 return CKM_API_ERROR_INPUT_PARAM;
781 DB::Crypto::Transaction transaction(&handler.database);
782 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
783 if(CKM_API_SUCCESS != retCode)
786 // check access rights
787 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
788 if(CKM_API_SUCCESS != retCode)
792 if (!handler.crypto.haveKey(row.ownerLabel)) {
794 auto key_optional = handler.database.getKey(row.ownerLabel);
796 LogError("No key for given label in database");
797 return CKM_API_ERROR_DB_ERROR;
800 key = handler.keyProvider.getPureDEK(key);
801 handler.crypto.pushKey(row.ownerLabel, key);
803 handler.crypto.decryptRow(password, row);
805 return CKM_API_SUCCESS;
808 RawBuffer CKMLogic::getData(
809 const Credentials &cred,
814 const Password &password)
816 int retCode = CKM_API_SUCCESS;
820 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
821 } catch (const KeyProvider::Exception::Base &e) {
822 LogError("KeyProvider failed with error: " << e.GetMessage());
823 retCode = CKM_API_ERROR_SERVER_ERROR;
824 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
825 LogError("CryptoLogic failed with message: " << e.GetMessage());
826 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
827 } catch (const CryptoLogic::Exception::Base &e) {
828 LogError("CryptoLogic failed with message: " << e.GetMessage());
829 retCode = CKM_API_ERROR_SERVER_ERROR;
830 } catch (const DB::Crypto::Exception::Base &e) {
831 LogError("DB::Crypto failed with message: " << e.GetMessage());
832 retCode = CKM_API_ERROR_DB_ERROR;
833 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
834 LogError("Error " << e.GetMessage());
835 retCode = CKM_API_ERROR_DB_LOCKED;
836 } catch (const CKM::Exception &e) {
837 LogError("CKM::Exception: " << e.GetMessage());
838 retCode = CKM_API_ERROR_SERVER_ERROR;
841 if (CKM_API_SUCCESS != retCode) {
843 row.dataType = dataType;
846 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
849 static_cast<int>(row.dataType),
851 return response.Pop();
854 int CKMLogic::getPKCS12Helper(
855 const Credentials &cred,
858 const Password &keyPassword,
859 const Password &certPassword,
861 CertificateShPtr & cert,
862 CertificateShPtrVector & caChain)
866 // read private key (mandatory)
868 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
869 if(retCode != CKM_API_SUCCESS)
871 privKey = CKM::Key::create(privKeyRow.data);
873 // read certificate (mandatory)
875 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
876 if(retCode != CKM_API_SUCCESS)
878 cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
880 // read CA cert chain (optional)
881 DB::RowVector rawCaChain;
882 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
883 if(retCode != CKM_API_SUCCESS &&
884 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
886 for(auto &rawCaCert : rawCaChain)
887 caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
889 // if anything found, return it
890 if(privKey || cert || caChain.size()>0)
891 retCode = CKM_API_SUCCESS;
896 RawBuffer CKMLogic::getPKCS12(
897 const Credentials &cred,
901 const Password &keyPassword,
902 const Password &certPassword)
904 int retCode = CKM_API_ERROR_UNKNOWN;
906 PKCS12Serializable output;
909 CertificateShPtr cert;
910 CertificateShPtrVector caChain;
911 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
914 if(retCode == CKM_API_SUCCESS)
915 output = PKCS12Serializable(privKey, cert, caChain);
917 } catch (const KeyProvider::Exception::Base &e) {
918 LogError("KeyProvider failed with error: " << e.GetMessage());
919 retCode = CKM_API_ERROR_SERVER_ERROR;
920 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
921 LogError("CryptoLogic failed with message: " << e.GetMessage());
922 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
923 } catch (const CryptoLogic::Exception::Base &e) {
924 LogError("CryptoLogic failed with message: " << e.GetMessage());
925 retCode = CKM_API_ERROR_SERVER_ERROR;
926 } catch (const DB::Crypto::Exception::Base &e) {
927 LogError("DB::Crypto failed with message: " << e.GetMessage());
928 retCode = CKM_API_ERROR_DB_ERROR;
929 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
930 LogError("Error " << e.GetMessage());
931 retCode = CKM_API_ERROR_DB_LOCKED;
932 } catch (const CKM::Exception &e) {
933 LogError("CKM::Exception: " << e.GetMessage());
934 retCode = CKM_API_ERROR_SERVER_ERROR;
937 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
941 return response.Pop();
944 int CKMLogic::getDataListHelper(const Credentials &cred,
945 const DataType dataType,
946 LabelNameVector &labelNameVector)
948 int retCode = CKM_API_ERROR_DB_LOCKED;
949 if (0 < m_userDataMap.count(cred.clientUid))
951 auto &database = m_userDataMap[cred.clientUid].database;
954 LabelNameVector tmpVector;
955 if (dataType.isKey()) {
956 // list all key types
957 database.listNames(cred.smackLabel,
959 DataType::DB_KEY_FIRST,
960 DataType::DB_KEY_LAST);
962 // list anything else
963 database.listNames(cred.smackLabel,
967 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
968 retCode = CKM_API_SUCCESS;
970 Catch (CKM::Exception) {
971 LogError("Failed to get names");
972 retCode = CKM_API_ERROR_DB_ERROR;
978 RawBuffer CKMLogic::getDataList(
979 const Credentials &cred,
983 LabelNameVector systemVector;
984 LabelNameVector userVector;
985 LabelNameVector labelNameVector;
987 int retCode = unlockSystemDB();
988 if (CKM_API_SUCCESS == retCode)
991 if (m_accessControl.isSystemService(cred))
994 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1001 // user - lookup system, then client DB
1002 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1008 if(retCode == CKM_API_SUCCESS)
1010 retCode = getDataListHelper(cred,
1017 if(retCode == CKM_API_SUCCESS)
1019 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1020 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1022 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1025 static_cast<int>(dataType),
1027 return response.Pop();
1030 int CKMLogic::saveDataHelper(
1031 const Credentials &cred,
1035 const RawBuffer &data,
1036 const PolicySerializable &policy)
1038 auto &handler = selectDatabase(cred, label);
1040 // use client label if not explicitly provided
1041 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1042 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1043 return CKM_API_ERROR_INPUT_PARAM;
1045 // check if save is possible
1046 DB::Crypto::Transaction transaction(&handler.database);
1047 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1048 if(retCode != CKM_API_SUCCESS)
1052 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
1053 handler.database.saveRow(encryptedRow);
1055 transaction.commit();
1056 return CKM_API_SUCCESS;
1059 int CKMLogic::saveDataHelper(
1060 const Credentials &cred,
1063 const PKCS12Serializable &pkcs,
1064 const PolicySerializable &keyPolicy,
1065 const PolicySerializable &certPolicy)
1067 auto &handler = selectDatabase(cred, label);
1069 // use client label if not explicitly provided
1070 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1071 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1072 return CKM_API_ERROR_INPUT_PARAM;
1074 // check if save is possible
1075 DB::Crypto::Transaction transaction(&handler.database);
1076 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1077 if(retCode != CKM_API_SUCCESS)
1080 // extract and encrypt the data
1081 DB::RowVector encryptedRows;
1082 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1083 if(retCode != CKM_API_SUCCESS)
1087 handler.database.saveRows(name, ownerLabel, encryptedRows);
1088 transaction.commit();
1090 return CKM_API_SUCCESS;
1094 int CKMLogic::createKeyPairHelper(
1095 const Credentials &cred,
1096 const KeyType key_type,
1097 const int additional_param,
1098 const Name &namePrivate,
1099 const Label &labelPrivate,
1100 const Name &namePublic,
1101 const Label &labelPublic,
1102 const PolicySerializable &policyPrivate,
1103 const PolicySerializable &policyPublic)
1105 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1106 auto &handlerPub = selectDatabase(cred, labelPublic);
1113 case KeyType::KEY_RSA_PUBLIC:
1114 case KeyType::KEY_RSA_PRIVATE:
1115 retCode = Crypto::SW::CryptoService::createKeyPairRSA(additional_param, prv, pub);
1118 case KeyType::KEY_DSA_PUBLIC:
1119 case KeyType::KEY_DSA_PRIVATE:
1120 retCode = Crypto::SW::CryptoService::createKeyPairDSA(additional_param, prv, pub);
1123 case KeyType::KEY_ECDSA_PUBLIC:
1124 case KeyType::KEY_ECDSA_PRIVATE:
1125 retCode = Crypto::SW::CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
1129 return CKM_API_ERROR_INPUT_PARAM;
1132 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
1134 LogDebug("CryptoService error with code: " << retCode);
1135 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
1138 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1139 // in case the same database is used for private and public - the second
1140 // transaction will not be executed
1141 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1143 retCode = saveDataHelper(cred,
1146 DataType(prv.getType()),
1149 if (CKM_API_SUCCESS != retCode)
1152 retCode = saveDataHelper(cred,
1155 DataType(pub.getType()),
1158 if (CKM_API_SUCCESS != retCode)
1161 transactionPub.commit();
1162 transactionPriv.commit();
1167 RawBuffer CKMLogic::createKeyPair(
1168 const Credentials &cred,
1169 LogicCommand protocol_cmd,
1171 const int additional_param,
1172 const Name &namePrivate,
1173 const Label &labelPrivate,
1174 const Name &namePublic,
1175 const Label &labelPublic,
1176 const PolicySerializable &policyPrivate,
1177 const PolicySerializable &policyPublic)
1179 int retCode = CKM_API_SUCCESS;
1181 KeyType key_type = KeyType::KEY_NONE;
1182 switch(protocol_cmd)
1184 case LogicCommand::CREATE_KEY_PAIR_RSA:
1185 key_type = KeyType::KEY_RSA_PUBLIC;
1187 case LogicCommand::CREATE_KEY_PAIR_DSA:
1188 key_type = KeyType::KEY_DSA_PUBLIC;
1190 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
1191 key_type = KeyType::KEY_ECDSA_PUBLIC;
1198 retCode = createKeyPairHelper(
1208 } catch (DB::Crypto::Exception::TransactionError &e) {
1209 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1210 retCode = CKM_API_ERROR_DB_ERROR;
1211 } catch (CKM::CryptoLogic::Exception::Base &e) {
1212 LogDebug("CryptoLogic error: " << e.GetMessage());
1213 retCode = CKM_API_ERROR_SERVER_ERROR;
1214 } catch (DB::Crypto::Exception::InternalError &e) {
1215 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1216 retCode = CKM_API_ERROR_DB_ERROR;
1217 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1218 LogError("Error " << e.GetMessage());
1219 retCode = CKM_API_ERROR_DB_LOCKED;
1220 } catch (const CKM::Exception &e) {
1221 LogError("CKM::Exception: " << e.GetMessage());
1222 retCode = CKM_API_ERROR_SERVER_ERROR;
1225 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
1228 int CKMLogic::readCertificateHelper(
1229 const Credentials &cred,
1230 const LabelNameVector &labelNameVector,
1231 CertificateImplVector &certVector)
1234 for (auto &i: labelNameVector) {
1235 int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1236 if (ec != CKM_API_SUCCESS)
1238 certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1240 // try to read chain certificates (if present)
1241 DB::RowVector rawCaChain;
1242 ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1243 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1245 for(auto &rawCaCert : rawCaChain)
1246 certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1248 return CKM_API_SUCCESS;
1251 int CKMLogic::getCertificateChainHelper(
1252 const CertificateImpl &cert,
1253 const RawBufferVector &untrustedCertificates,
1254 const RawBufferVector &trustedCertificates,
1255 bool useTrustedSystemCertificates,
1256 RawBufferVector &chainRawVector)
1258 CertificateImplVector untrustedCertVector;
1259 CertificateImplVector trustedCertVector;
1260 CertificateImplVector chainVector;
1263 return CKM_API_ERROR_INPUT_PARAM;
1265 for (auto &e: untrustedCertificates)
1266 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1267 for (auto &e: trustedCertificates)
1268 trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1270 CertificateStore store;
1271 int retCode = store.verifyCertificate(cert,
1272 untrustedCertVector,
1274 useTrustedSystemCertificates,
1275 m_accessControl.isCCMode(),
1277 if (retCode != CKM_API_SUCCESS)
1280 for (auto &e : chainVector)
1281 chainRawVector.push_back(e.getDER());
1282 return CKM_API_SUCCESS;
1285 int CKMLogic::getCertificateChainHelper(
1286 const Credentials &cred,
1287 const CertificateImpl &cert,
1288 const LabelNameVector &untrusted,
1289 const LabelNameVector &trusted,
1290 bool useTrustedSystemCertificates,
1291 RawBufferVector &chainRawVector)
1293 CertificateImplVector untrustedCertVector;
1294 CertificateImplVector trustedCertVector;
1295 CertificateImplVector chainVector;
1299 return CKM_API_ERROR_INPUT_PARAM;
1301 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1302 if (retCode != CKM_API_SUCCESS)
1304 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1305 if (retCode != CKM_API_SUCCESS)
1308 CertificateStore store;
1309 retCode = store.verifyCertificate(cert,
1310 untrustedCertVector,
1312 useTrustedSystemCertificates,
1313 m_accessControl.isCCMode(),
1315 if (retCode != CKM_API_SUCCESS)
1318 for (auto &i: chainVector)
1319 chainRawVector.push_back(i.getDER());
1321 return CKM_API_SUCCESS;
1324 RawBuffer CKMLogic::getCertificateChain(
1325 const Credentials & /*cred*/,
1327 const RawBuffer &certificate,
1328 const RawBufferVector &untrustedCertificates,
1329 const RawBufferVector &trustedCertificates,
1330 bool useTrustedSystemCertificates)
1332 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1333 RawBufferVector chainRawVector;
1334 int retCode = CKM_API_ERROR_UNKNOWN;
1336 retCode = getCertificateChainHelper(cert,
1337 untrustedCertificates,
1338 trustedCertificates,
1339 useTrustedSystemCertificates,
1341 } catch (const CryptoLogic::Exception::Base &e) {
1342 LogError("CryptoLogic failed with message: " << e.GetMessage());
1343 retCode = CKM_API_ERROR_SERVER_ERROR;
1344 } catch (const DB::Crypto::Exception::Base &e) {
1345 LogError("DB::Crypto failed with message: " << e.GetMessage());
1346 retCode = CKM_API_ERROR_DB_ERROR;
1347 } catch (const std::exception& e) {
1348 LogError("STD exception " << e.what());
1349 retCode = CKM_API_ERROR_SERVER_ERROR;
1351 LogError("Unknown error.");
1354 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1358 return response.Pop();
1361 RawBuffer CKMLogic::getCertificateChain(
1362 const Credentials &cred,
1364 const RawBuffer &certificate,
1365 const LabelNameVector &untrustedCertificates,
1366 const LabelNameVector &trustedCertificates,
1367 bool useTrustedSystemCertificates)
1369 int retCode = CKM_API_ERROR_UNKNOWN;
1370 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1371 RawBufferVector chainRawVector;
1373 retCode = getCertificateChainHelper(cred,
1375 untrustedCertificates,
1376 trustedCertificates,
1377 useTrustedSystemCertificates,
1379 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1380 LogError("CryptoLogic failed with message: " << e.GetMessage());
1381 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1382 } catch (const CryptoLogic::Exception::Base &e) {
1383 LogError("CryptoLogic failed with message: " << e.GetMessage());
1384 retCode = CKM_API_ERROR_SERVER_ERROR;
1385 } catch (const DB::Crypto::Exception::Base &e) {
1386 LogError("DB::Crypto failed with message: " << e.GetMessage());
1387 retCode = CKM_API_ERROR_DB_ERROR;
1388 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1389 LogError("Error " << e.GetMessage());
1390 retCode = CKM_API_ERROR_DB_LOCKED;
1391 } catch (const std::exception& e) {
1392 LogError("STD exception " << e.what());
1393 retCode = CKM_API_ERROR_SERVER_ERROR;
1395 LogError("Unknown error.");
1398 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1402 return response.Pop();
1405 RawBuffer CKMLogic::createSignature(
1406 const Credentials &cred,
1408 const Name &privateKeyName,
1409 const Label & ownerLabel,
1410 const Password &password, // password for private_key
1411 const RawBuffer &message,
1412 const HashAlgorithm hash,
1413 const RSAPaddingAlgorithm padding)
1416 Crypto::SW::CryptoService cs;
1417 RawBuffer signature;
1419 int retCode = CKM_API_SUCCESS;
1422 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1423 if(retCode == CKM_API_SUCCESS)
1425 KeyImpl keyParsed(row.data, Password());
1426 if (keyParsed.empty())
1427 retCode = CKM_API_ERROR_SERVER_ERROR;
1429 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
1431 } catch (const KeyProvider::Exception::Base &e) {
1432 LogError("KeyProvider failed with message: " << e.GetMessage());
1433 retCode = CKM_API_ERROR_SERVER_ERROR;
1434 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1435 LogError("CryptoLogic failed with message: " << e.GetMessage());
1436 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1437 } catch (const CryptoLogic::Exception::Base &e) {
1438 LogError("CryptoLogic failed with message: " << e.GetMessage());
1439 retCode = CKM_API_ERROR_SERVER_ERROR;
1440 } catch (const DB::Crypto::Exception::Base &e) {
1441 LogError("DB::Crypto failed with message: " << e.GetMessage());
1442 retCode = CKM_API_ERROR_DB_ERROR;
1443 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1444 LogError("Error " << e.GetMessage());
1445 retCode = CKM_API_ERROR_DB_LOCKED;
1446 } catch (const CKM::Exception &e) {
1447 LogError("Unknown CKM::Exception: " << e.GetMessage());
1448 retCode = CKM_API_ERROR_SERVER_ERROR;
1451 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1455 return response.Pop();
1458 RawBuffer CKMLogic::verifySignature(
1459 const Credentials &cred,
1461 const Name &publicKeyOrCertName,
1462 const Label & ownerLabel,
1463 const Password &password, // password for public_key (optional)
1464 const RawBuffer &message,
1465 const RawBuffer &signature,
1466 const HashAlgorithm hash,
1467 const RSAPaddingAlgorithm padding)
1469 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1473 Crypto::SW::CryptoService cs;
1477 // try certificate first - looking for a public key.
1478 // in case of PKCS, pub key from certificate will be found first
1479 // rather than private key from the same PKCS.
1480 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
1481 if (retCode == CKM_API_SUCCESS) {
1482 CertificateImpl cert(row.data, DataFormat::FORM_DER);
1483 key = cert.getKeyImpl();
1484 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1485 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
1486 if (retCode != CKM_API_SUCCESS)
1488 key = KeyImpl(row.data);
1494 retCode = CKM_API_ERROR_SERVER_ERROR;
1498 retCode = cs.verifySignature(key, message, signature, hash, padding);
1500 } catch (const Crypto::SW::CryptoService::Exception::Crypto_internal &e) {
1501 LogError("KeyProvider failed with message: " << e.GetMessage());
1502 retCode = CKM_API_ERROR_SERVER_ERROR;
1503 } catch (const Crypto::SW::CryptoService::Exception::opensslError &e) {
1504 LogError("KeyProvider failed with message: " << e.GetMessage());
1505 retCode = CKM_API_ERROR_SERVER_ERROR;
1506 } catch (const KeyProvider::Exception::Base &e) {
1507 LogError("KeyProvider failed with error: " << e.GetMessage());
1508 retCode = CKM_API_ERROR_SERVER_ERROR;
1509 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1510 LogError("CryptoLogic failed with message: " << e.GetMessage());
1511 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1512 } catch (const CryptoLogic::Exception::Base &e) {
1513 LogError("CryptoLogic failed with message: " << e.GetMessage());
1514 retCode = CKM_API_ERROR_SERVER_ERROR;
1515 } catch (const DB::Crypto::Exception::Base &e) {
1516 LogError("DB::Crypto failed with message: " << e.GetMessage());
1517 retCode = CKM_API_ERROR_DB_ERROR;
1518 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1519 LogError("Error " << e.GetMessage());
1520 retCode = CKM_API_ERROR_DB_LOCKED;
1521 } catch (const CKM::Exception &e) {
1522 LogError("Unknown CKM::Exception: " << e.GetMessage());
1523 retCode = CKM_API_ERROR_SERVER_ERROR;
1526 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1529 return response.Pop();
1532 int CKMLogic::setPermissionHelper(
1533 const Credentials &cred, // who's the client
1535 const Label &label, // who's the owner
1536 const Label &accessorLabel, // who will get the access
1537 const PermissionMask permissionMask)
1539 auto &handler = selectDatabase(cred, label);
1541 // we don't know the client
1542 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1543 return CKM_API_ERROR_INPUT_PARAM;
1545 // use client label if not explicitly provided
1546 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1548 // verify name and label are correct
1549 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1550 return CKM_API_ERROR_INPUT_PARAM;
1552 // currently we don't support modification of owner's permissions to his own rows
1553 if (ownerLabel==accessorLabel)
1554 return CKM_API_ERROR_INPUT_PARAM;
1556 // system database does not support write/remove permissions
1557 if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
1558 (permissionMask & Permission::REMOVE))
1559 return CKM_API_ERROR_INPUT_PARAM;
1561 // can the client modify permissions to owner's row?
1562 int retCode = m_accessControl.canModify(cred, ownerLabel);
1563 if(retCode != CKM_API_SUCCESS)
1566 DB::Crypto::Transaction transaction(&handler.database);
1568 if( !handler.database.isNameLabelPresent(name, ownerLabel) )
1569 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1571 // removing non-existing permissions: fail
1572 if(permissionMask == Permission::NONE)
1574 if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1575 return CKM_API_ERROR_INPUT_PARAM;
1578 // set permissions to the row owned by ownerLabel for accessorLabel
1579 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1580 transaction.commit();
1582 return CKM_API_SUCCESS;
1585 RawBuffer CKMLogic::setPermission(
1586 const Credentials &cred,
1591 const Label &accessorLabel,
1592 const PermissionMask permissionMask)
1596 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1597 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1598 LogError("Error " << e.GetMessage());
1599 retCode = CKM_API_ERROR_DB_LOCKED;
1600 } Catch (CKM::Exception) {
1601 LogError("Error in set row!");
1602 retCode = CKM_API_ERROR_DB_ERROR;
1605 return MessageBuffer::Serialize(command, msgID, retCode).Pop();