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.crypto.removeKey(appSmackLabel);
117 handle.database.deleteKey(appSmackLabel);
120 } catch (const KeyProvider::Exception::PassWordError &e) {
121 LogError("Incorrect Password " << e.GetMessage());
122 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
123 } catch (const KeyProvider::Exception::Base &e) {
124 LogError("Error in KeyProvider " << e.GetMessage());
125 retCode = CKM_API_ERROR_SERVER_ERROR;
126 } catch (const CryptoLogic::Exception::Base &e) {
127 LogError("CryptoLogic error: " << e.GetMessage());
128 retCode = CKM_API_ERROR_SERVER_ERROR;
129 } catch (const FileSystem::Exception::Base &e) {
130 LogError("FileSystem error: " << e.GetMessage());
131 retCode = CKM_API_ERROR_FILE_SYSTEM;
132 } catch (const CKM::Exception &e) {
133 LogError("CKM::Exception: " << e.GetMessage());
134 retCode = CKM_API_ERROR_SERVER_ERROR;
137 if (CKM_API_SUCCESS != retCode)
138 m_userDataMap.erase(user);
143 int CKMLogic::unlockSystemDB()
145 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
148 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
150 // if user trying to access system service - check:
151 // * if user database is unlocked [mandatory]
152 // * if not - proceed with regular user database
153 // * if explicit system database label given -> switch to system DB
154 if ( !m_accessControl.isSystemService(cred) )
156 if (0 == m_userDataMap.count(cred.clientUid))
157 ThrowMsg(Exception::DatabaseLocked, "database with UID: " << cred.clientUid << " locked");
159 if (0 != incoming_label.compare(LABEL_SYSTEM_DB))
160 return m_userDataMap[cred.clientUid];
163 // system database selected, modify the label
164 if (CKM_API_SUCCESS != unlockSystemDB() )
165 ThrowMsg(Exception::DatabaseLocked, "can not unlock system database");
166 return m_userDataMap[SYSTEM_DB_UID];
169 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
171 int retCode = CKM_API_SUCCESS;
173 if( !m_accessControl.isSystemService(user) )
175 retCode = unlockDatabase(user, password);
179 // do not allow lock/unlock operations for system users
180 retCode = CKM_API_ERROR_INPUT_PARAM;
183 return MessageBuffer::Serialize(retCode).Pop();
186 RawBuffer CKMLogic::updateCCMode() {
187 m_accessControl.updateCCMode();
188 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
191 RawBuffer CKMLogic::lockUserKey(uid_t user)
193 int retCode = CKM_API_SUCCESS;
194 if( !m_accessControl.isSystemService(user) )
196 m_userDataMap.erase(user);
200 // do not allow lock/unlock operations for system users
201 retCode = CKM_API_ERROR_INPUT_PARAM;
204 return MessageBuffer::Serialize(retCode).Pop();
208 RawBuffer CKMLogic::removeUserData(uid_t user) {
209 int retCode = CKM_API_SUCCESS;
211 if (m_accessControl.isSystemService(user))
212 user = SYSTEM_DB_UID;
214 m_userDataMap.erase(user);
219 return MessageBuffer::Serialize(retCode).Pop();
222 int CKMLogic::changeUserPasswordHelper(uid_t user,
223 const Password &oldPassword,
224 const Password &newPassword)
226 // do not allow to change system database password
227 if( m_accessControl.isSystemService(user) )
228 return CKM_API_ERROR_INPUT_PARAM;
230 loadDKEKFile(user, oldPassword);
231 saveDKEKFile(user, newPassword);
233 return CKM_API_SUCCESS;
236 RawBuffer CKMLogic::changeUserPassword(
238 const Password &oldPassword,
239 const Password &newPassword)
241 int retCode = CKM_API_SUCCESS;
244 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
245 } catch (const KeyProvider::Exception::PassWordError &e) {
246 LogError("Incorrect Password " << e.GetMessage());
247 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
248 } catch (const KeyProvider::Exception::Base &e) {
249 LogError("Error in KeyProvider " << e.GetMessage());
250 retCode = CKM_API_ERROR_SERVER_ERROR;
251 } catch (const FileSystem::Exception::Base &e) {
252 LogError("Error in FileSystem " << e.GetMessage());
253 retCode = CKM_API_ERROR_FILE_SYSTEM;
254 } catch (const CKM::Exception &e) {
255 LogError("CKM::Exception: " << e.GetMessage());
256 retCode = CKM_API_ERROR_SERVER_ERROR;
259 return MessageBuffer::Serialize(retCode).Pop();
262 int CKMLogic::resetUserPasswordHelper(
264 const Password &newPassword)
266 // do not allow to reset system database password
267 if( m_accessControl.isSystemService(user) )
268 return CKM_API_ERROR_INPUT_PARAM;
270 int retCode = CKM_API_SUCCESS;
271 if (0 == m_userDataMap.count(user))
273 // Check if key exists. If exists we must return error
275 auto wrappedDKEKMain = fs.getDKEK();
276 if (!wrappedDKEKMain.empty())
277 retCode = CKM_API_ERROR_BAD_REQUEST;
279 saveDKEKFile(user, newPassword);
285 RawBuffer CKMLogic::resetUserPassword(
287 const Password &newPassword)
289 int retCode = CKM_API_SUCCESS;
291 retCode = resetUserPasswordHelper(user, newPassword);
292 } catch (const FileSystem::Exception::Base &e) {
293 LogError("Error in FileSystem " << e.GetMessage());
294 retCode = CKM_API_ERROR_FILE_SYSTEM;
295 } catch (const CKM::Exception &e) {
296 LogError("CKM::Exception: " << e.GetMessage());
297 retCode = CKM_API_ERROR_SERVER_ERROR;
300 return MessageBuffer::Serialize(retCode).Pop();
303 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
304 int retCode = CKM_API_SUCCESS;
308 if (smackLabel.empty()) {
309 retCode = CKM_API_ERROR_INPUT_PARAM;
311 UidVector uids = FileSystem::getUIDsFromDBFile();
312 for (auto userId : uids) {
313 if (0 == m_userDataMap.count(userId)) {
314 FileSystem fs(userId);
315 fs.addRemovedApp(smackLabel);
317 auto &handle = m_userDataMap[userId];
318 handle.crypto.removeKey(smackLabel);
319 handle.database.deleteKey(smackLabel);
324 } catch (const DB::Crypto::Exception::InternalError &e) {
325 LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
326 retCode = CKM_API_ERROR_DB_ERROR;
327 } catch (const DB::Crypto::Exception::TransactionError &e) {
328 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
329 retCode = CKM_API_ERROR_DB_ERROR;
330 } catch (const FileSystem::Exception::Base &e) {
331 LogError("Error in FileSystem " << e.GetMessage());
332 retCode = CKM_API_ERROR_FILE_SYSTEM;
333 } catch (const CKM::Exception &e) {
334 LogError("CKM::Exception: " << e.GetMessage());
335 retCode = CKM_API_ERROR_SERVER_ERROR;
338 return MessageBuffer::Serialize(retCode).Pop();
341 int CKMLogic::checkSaveConditions(
342 const Credentials &cred,
345 const Label &ownerLabel)
347 // verify name and label are correct
348 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
349 LogWarning("Invalid parameter passed to key-manager");
350 return CKM_API_ERROR_INPUT_PARAM;
353 // check if allowed to save using ownerLabel
354 int access_ec = m_accessControl.canSave(cred, ownerLabel);
355 if( access_ec != CKM_API_SUCCESS)
357 LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
361 // check if not a duplicate
362 if( handler.database.isNameLabelPresent(name, ownerLabel))
363 return CKM_API_ERROR_DB_ALIAS_EXISTS;
365 // encryption section
366 if (!handler.crypto.haveKey(ownerLabel))
369 auto key_optional = handler.database.getKey(ownerLabel);
371 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
372 got_key = handler.keyProvider.generateDEK(ownerLabel);
373 handler.database.saveKey(ownerLabel, got_key);
375 LogDebug("Key from DB");
376 got_key = *key_optional;
379 got_key = handler.keyProvider.getPureDEK(got_key);
380 handler.crypto.pushKey(ownerLabel, got_key);
383 return CKM_API_SUCCESS;
386 DB::Row CKMLogic::createEncryptedRow(
391 const RawBuffer &data,
392 const Policy &policy) const
394 DB::Row row(name, label, static_cast<int>(policy.extractable), dataType, data, static_cast<int>(data.size()));
396 // do not encrypt data with password during cc_mode on
397 if(m_accessControl.isCCMode()) {
398 crypto.encryptRow("", row);
400 crypto.encryptRow(policy.password, row);
405 int CKMLogic::verifyBinaryData(DataType dataType, const RawBuffer &input_data) const
407 // verify the data integrity
408 if (dataType.isKey())
410 KeyShPtr output_key = CKM::Key::create(input_data);
411 if(output_key.get() == NULL)
413 LogError("provided binary data is not valid key data");
414 return CKM_API_ERROR_INPUT_PARAM;
417 else if (dataType.isCertificate() || dataType.isChainCert())
419 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
420 if(cert.get() == NULL)
422 LogError("provided binary data is not valid certificate data");
423 return CKM_API_ERROR_INPUT_PARAM;
426 // TODO: add here BINARY_DATA verification, i.e: max size etc.
427 return CKM_API_SUCCESS;
430 RawBuffer CKMLogic::saveData(
431 const Credentials &cred,
435 const RawBuffer &data,
437 const PolicySerializable &policy)
439 int retCode = CKM_API_ERROR_UNKNOWN;
442 // check if data is correct
443 retCode = verifyBinaryData(dataType, data);
444 if(retCode == CKM_API_SUCCESS)
446 retCode = saveDataHelper(cred, name, label, dataType, data, policy);
448 } catch (const KeyProvider::Exception::Base &e) {
449 LogError("KeyProvider failed with message: " << e.GetMessage());
450 retCode = CKM_API_ERROR_SERVER_ERROR;
451 } catch (const CryptoLogic::Exception::Base &e) {
452 LogError("CryptoLogic failed with message: " << e.GetMessage());
453 retCode = CKM_API_ERROR_SERVER_ERROR;
454 } catch (const DB::Crypto::Exception::InternalError &e) {
455 LogError("DB::Crypto failed with message: " << e.GetMessage());
456 retCode = CKM_API_ERROR_DB_ERROR;
457 } catch (const DB::Crypto::Exception::TransactionError &e) {
458 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
459 retCode = CKM_API_ERROR_DB_ERROR;
460 } catch (const FileSystem::Exception::Base &e) {
461 LogError("Error in FileSystem " << e.GetMessage());
462 retCode = CKM_API_ERROR_FILE_SYSTEM;
463 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
464 LogError("Error " << e.GetMessage());
465 retCode = CKM_API_ERROR_DB_LOCKED;
466 } catch (const CKM::Exception &e) {
467 LogError("CKM::Exception: " << e.GetMessage());
468 retCode = CKM_API_ERROR_SERVER_ERROR;
471 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
474 static_cast<int>(dataType));
475 return response.Pop();
478 int CKMLogic::extractPKCS12Data(
481 const Label &ownerLabel,
482 const PKCS12Serializable &pkcs,
483 const PolicySerializable &keyPolicy,
484 const PolicySerializable &certPolicy,
485 DB::RowVector &output) const
487 // private key is mandatory
489 return CKM_API_ERROR_INVALID_FORMAT;
490 Key* keyPtr = pkcs.getKey().get();
491 DataType keyType = DataType(keyPtr->getType());
492 RawBuffer keyData = keyPtr->getDER();
493 int retCode = verifyBinaryData(keyType, keyData);
494 if(retCode != CKM_API_SUCCESS)
496 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
498 // certificate is mandatory
499 if( !pkcs.getCertificate() )
500 return CKM_API_ERROR_INVALID_FORMAT;
501 RawBuffer certData = pkcs.getCertificate().get()->getDER();
502 retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
503 if(retCode != CKM_API_SUCCESS)
505 output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
508 unsigned int cert_index = 0;
509 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
511 DataType chainDataType = DataType::getChainDatatype(cert_index ++);
512 RawBuffer caCertData = ca->getDER();
513 int retCode = verifyBinaryData(chainDataType, caCertData);
514 if(retCode != CKM_API_SUCCESS)
517 output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
520 return CKM_API_SUCCESS;
523 RawBuffer CKMLogic::savePKCS12(
524 const Credentials &cred,
528 const PKCS12Serializable &pkcs,
529 const PolicySerializable &keyPolicy,
530 const PolicySerializable &certPolicy)
532 int retCode = CKM_API_ERROR_UNKNOWN;
534 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
535 } catch (const KeyProvider::Exception::Base &e) {
536 LogError("KeyProvider failed with message: " << e.GetMessage());
537 retCode = CKM_API_ERROR_SERVER_ERROR;
538 } catch (const CryptoLogic::Exception::Base &e) {
539 LogError("CryptoLogic failed with message: " << e.GetMessage());
540 retCode = CKM_API_ERROR_SERVER_ERROR;
541 } catch (const DB::Crypto::Exception::InternalError &e) {
542 LogError("DB::Crypto failed with message: " << e.GetMessage());
543 retCode = CKM_API_ERROR_DB_ERROR;
544 } catch (const DB::Crypto::Exception::TransactionError &e) {
545 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
546 retCode = CKM_API_ERROR_DB_ERROR;
547 } catch (const CKM::Exception &e) {
548 LogError("CKM::Exception: " << e.GetMessage());
549 retCode = CKM_API_ERROR_SERVER_ERROR;
552 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
555 return response.Pop();
559 int CKMLogic::removeDataHelper(
560 const Credentials &cred,
564 auto &handler = selectDatabase(cred, label);
566 // use client label if not explicitly provided
567 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
568 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
569 LogError("Invalid label or name format");
570 return CKM_API_ERROR_INPUT_PARAM;
573 DB::Crypto::Transaction transaction(&handler.database);
575 // read and check permissions
576 PermissionMaskOptional permissionRowOpt =
577 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
578 int retCode = m_accessControl.canDelete(cred,
579 PermissionForLabel(cred.smackLabel, permissionRowOpt));
580 if(retCode != CKM_API_SUCCESS)
582 LogWarning("access control check result: " << retCode);
586 auto erased = handler.database.deleteRow(name, ownerLabel);
587 // check if the data existed or not
589 transaction.commit();
591 LogError("No row for given name and label");
592 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
595 return CKM_API_SUCCESS;
598 RawBuffer CKMLogic::removeData(
599 const Credentials &cred,
604 int retCode = CKM_API_ERROR_UNKNOWN;
608 retCode = removeDataHelper(cred, name, label);
610 catch (const CKMLogic::Exception::DatabaseLocked &e)
612 LogError("Error " << e.GetMessage());
613 retCode = CKM_API_ERROR_DB_LOCKED;
615 catch (const CKM::Exception &)
617 LogError("Error in deleting row!");
618 retCode = CKM_API_ERROR_DB_ERROR;
621 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
624 return response.Pop();
627 int CKMLogic::readSingleRow(const Name &name,
628 const Label &ownerLabel,
630 DB::Crypto & database,
633 DB::Crypto::RowOptional row_optional;
634 if (dataType.isKey())
636 // read all key types
637 row_optional = database.getRow(name,
639 DataType::DB_KEY_FIRST,
640 DataType::DB_KEY_LAST);
642 // read anything else
643 row_optional = database.getRow(name,
649 LogError("No row for given name, label and type");
650 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
655 return CKM_API_SUCCESS;
659 int CKMLogic::readMultiRow(const Name &name,
660 const Label &ownerLabel,
662 DB::Crypto & database,
663 DB::RowVector &output)
665 if (dataType.isKey())
667 // read all key types
668 database.getRows(name,
670 DataType::DB_KEY_FIRST,
671 DataType::DB_KEY_LAST,
674 else if (dataType.isChainCert())
676 // read all key types
677 database.getRows(name,
679 DataType::DB_CHAIN_FIRST,
680 DataType::DB_CHAIN_LAST,
685 // read anything else
686 database.getRows(name,
693 LogError("No row for given name, label and type");
694 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
697 return CKM_API_SUCCESS;
700 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
702 const Label &ownerLabel,
703 const Label &accessorLabel,
706 DB::Crypto & database)
708 PermissionMaskOptional permissionRowOpt =
709 database.getPermissionRow(name, ownerLabel, accessorLabel);
712 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
713 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
716 int CKMLogic::readDataHelper(
718 const Credentials &cred,
722 const Password &password,
725 auto &handler = selectDatabase(cred, label);
727 // use client label if not explicitly provided
728 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
730 if (!isNameValid(name) || !isLabelValid(ownerLabel))
731 return CKM_API_ERROR_INPUT_PARAM;
734 DB::Crypto::Transaction transaction(&handler.database);
735 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
736 if(CKM_API_SUCCESS != retCode)
739 // all read rows belong to the same owner
740 DB::Row & firstRow = rows.at(0);
742 // check access rights
743 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
744 if(CKM_API_SUCCESS != retCode)
748 if (!handler.crypto.haveKey(firstRow.ownerLabel)) {
750 auto key_optional = handler.database.getKey(firstRow.ownerLabel);
752 LogError("No key for given label in database");
753 return CKM_API_ERROR_DB_ERROR;
756 key = handler.keyProvider.getPureDEK(key);
757 handler.crypto.pushKey(firstRow.ownerLabel, key);
759 for(auto &row : rows)
760 handler.crypto.decryptRow(password, row);
762 return CKM_API_SUCCESS;
765 int CKMLogic::readDataHelper(
767 const Credentials &cred,
771 const Password &password,
774 auto &handler = selectDatabase(cred, label);
776 // use client label if not explicitly provided
777 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
779 if (!isNameValid(name) || !isLabelValid(ownerLabel))
780 return CKM_API_ERROR_INPUT_PARAM;
783 DB::Crypto::Transaction transaction(&handler.database);
784 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
785 if(CKM_API_SUCCESS != retCode)
788 // check access rights
789 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
790 if(CKM_API_SUCCESS != retCode)
794 if (!handler.crypto.haveKey(row.ownerLabel)) {
796 auto key_optional = handler.database.getKey(row.ownerLabel);
798 LogError("No key for given label in database");
799 return CKM_API_ERROR_DB_ERROR;
802 key = handler.keyProvider.getPureDEK(key);
803 handler.crypto.pushKey(row.ownerLabel, key);
805 handler.crypto.decryptRow(password, row);
807 return CKM_API_SUCCESS;
810 RawBuffer CKMLogic::getData(
811 const Credentials &cred,
816 const Password &password)
818 int retCode = CKM_API_SUCCESS;
822 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
823 } catch (const KeyProvider::Exception::Base &e) {
824 LogError("KeyProvider failed with error: " << e.GetMessage());
825 retCode = CKM_API_ERROR_SERVER_ERROR;
826 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
827 LogError("CryptoLogic failed with message: " << e.GetMessage());
828 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
829 } catch (const CryptoLogic::Exception::Base &e) {
830 LogError("CryptoLogic failed with message: " << e.GetMessage());
831 retCode = CKM_API_ERROR_SERVER_ERROR;
832 } catch (const DB::Crypto::Exception::Base &e) {
833 LogError("DB::Crypto failed with message: " << e.GetMessage());
834 retCode = CKM_API_ERROR_DB_ERROR;
835 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
836 LogError("Error " << e.GetMessage());
837 retCode = CKM_API_ERROR_DB_LOCKED;
838 } catch (const CKM::Exception &e) {
839 LogError("CKM::Exception: " << e.GetMessage());
840 retCode = CKM_API_ERROR_SERVER_ERROR;
843 if (CKM_API_SUCCESS != retCode) {
845 row.dataType = dataType;
848 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
851 static_cast<int>(row.dataType),
853 return response.Pop();
856 int CKMLogic::getPKCS12Helper(
857 const Credentials &cred,
860 const Password &keyPassword,
861 const Password &certPassword,
863 CertificateShPtr & cert,
864 CertificateShPtrVector & caChain)
868 // read private key (mandatory)
870 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
871 if(retCode != CKM_API_SUCCESS)
873 privKey = CKM::Key::create(privKeyRow.data);
875 // read certificate (mandatory)
877 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
878 if(retCode != CKM_API_SUCCESS)
880 cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
882 // read CA cert chain (optional)
883 DB::RowVector rawCaChain;
884 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
885 if(retCode != CKM_API_SUCCESS &&
886 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
888 for(auto &rawCaCert : rawCaChain)
889 caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
891 // if anything found, return it
892 if(privKey || cert || caChain.size()>0)
893 retCode = CKM_API_SUCCESS;
898 RawBuffer CKMLogic::getPKCS12(
899 const Credentials &cred,
903 const Password &keyPassword,
904 const Password &certPassword)
906 int retCode = CKM_API_ERROR_UNKNOWN;
908 PKCS12Serializable output;
911 CertificateShPtr cert;
912 CertificateShPtrVector caChain;
913 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
916 if(retCode == CKM_API_SUCCESS)
917 output = PKCS12Serializable(privKey, cert, caChain);
919 } catch (const KeyProvider::Exception::Base &e) {
920 LogError("KeyProvider failed with error: " << e.GetMessage());
921 retCode = CKM_API_ERROR_SERVER_ERROR;
922 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
923 LogError("CryptoLogic failed with message: " << e.GetMessage());
924 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
925 } catch (const CryptoLogic::Exception::Base &e) {
926 LogError("CryptoLogic failed with message: " << e.GetMessage());
927 retCode = CKM_API_ERROR_SERVER_ERROR;
928 } catch (const DB::Crypto::Exception::Base &e) {
929 LogError("DB::Crypto failed with message: " << e.GetMessage());
930 retCode = CKM_API_ERROR_DB_ERROR;
931 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
932 LogError("Error " << e.GetMessage());
933 retCode = CKM_API_ERROR_DB_LOCKED;
934 } catch (const CKM::Exception &e) {
935 LogError("CKM::Exception: " << e.GetMessage());
936 retCode = CKM_API_ERROR_SERVER_ERROR;
939 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
943 return response.Pop();
946 int CKMLogic::getDataListHelper(const Credentials &cred,
947 const DataType dataType,
948 LabelNameVector &labelNameVector)
950 int retCode = CKM_API_ERROR_DB_LOCKED;
951 if (0 < m_userDataMap.count(cred.clientUid))
953 auto &database = m_userDataMap[cred.clientUid].database;
956 LabelNameVector tmpVector;
957 if (dataType.isKey()) {
958 // list all key types
959 database.listNames(cred.smackLabel,
961 DataType::DB_KEY_FIRST,
962 DataType::DB_KEY_LAST);
964 // list anything else
965 database.listNames(cred.smackLabel,
969 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
970 retCode = CKM_API_SUCCESS;
972 Catch (CKM::Exception) {
973 LogError("Failed to get names");
974 retCode = CKM_API_ERROR_DB_ERROR;
980 RawBuffer CKMLogic::getDataList(
981 const Credentials &cred,
985 LabelNameVector systemVector;
986 LabelNameVector userVector;
987 LabelNameVector labelNameVector;
989 int retCode = unlockSystemDB();
990 if (CKM_API_SUCCESS == retCode)
993 if (m_accessControl.isSystemService(cred))
996 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1003 // user - lookup system, then client DB
1004 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1010 if(retCode == CKM_API_SUCCESS)
1012 retCode = getDataListHelper(cred,
1019 if(retCode == CKM_API_SUCCESS)
1021 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1022 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1024 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1027 static_cast<int>(dataType),
1029 return response.Pop();
1032 int CKMLogic::saveDataHelper(
1033 const Credentials &cred,
1037 const RawBuffer &data,
1038 const PolicySerializable &policy)
1040 auto &handler = selectDatabase(cred, label);
1042 // use client label if not explicitly provided
1043 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1044 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1045 return CKM_API_ERROR_INPUT_PARAM;
1047 // check if save is possible
1048 DB::Crypto::Transaction transaction(&handler.database);
1049 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1050 if(retCode != CKM_API_SUCCESS)
1054 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
1055 handler.database.saveRow(encryptedRow);
1057 transaction.commit();
1058 return CKM_API_SUCCESS;
1061 int CKMLogic::saveDataHelper(
1062 const Credentials &cred,
1065 const PKCS12Serializable &pkcs,
1066 const PolicySerializable &keyPolicy,
1067 const PolicySerializable &certPolicy)
1069 auto &handler = selectDatabase(cred, label);
1071 // use client label if not explicitly provided
1072 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1073 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1074 return CKM_API_ERROR_INPUT_PARAM;
1076 // check if save is possible
1077 DB::Crypto::Transaction transaction(&handler.database);
1078 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1079 if(retCode != CKM_API_SUCCESS)
1082 // extract and encrypt the data
1083 DB::RowVector encryptedRows;
1084 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1085 if(retCode != CKM_API_SUCCESS)
1089 handler.database.saveRows(name, ownerLabel, encryptedRows);
1090 transaction.commit();
1092 return CKM_API_SUCCESS;
1096 int CKMLogic::createKeyPairHelper(
1097 const Credentials &cred,
1098 const KeyType key_type,
1099 const int additional_param,
1100 const Name &namePrivate,
1101 const Label &labelPrivate,
1102 const Name &namePublic,
1103 const Label &labelPublic,
1104 const PolicySerializable &policyPrivate,
1105 const PolicySerializable &policyPublic)
1107 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1108 auto &handlerPub = selectDatabase(cred, labelPublic);
1115 case KeyType::KEY_RSA_PUBLIC:
1116 case KeyType::KEY_RSA_PRIVATE:
1117 retCode = Crypto::SW::CryptoService::createKeyPairRSA(additional_param, prv, pub);
1120 case KeyType::KEY_DSA_PUBLIC:
1121 case KeyType::KEY_DSA_PRIVATE:
1122 retCode = Crypto::SW::CryptoService::createKeyPairDSA(additional_param, prv, pub);
1125 case KeyType::KEY_ECDSA_PUBLIC:
1126 case KeyType::KEY_ECDSA_PRIVATE:
1127 retCode = Crypto::SW::CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
1131 return CKM_API_ERROR_INPUT_PARAM;
1134 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
1136 LogDebug("CryptoService error with code: " << retCode);
1137 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
1140 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1141 // in case the same database is used for private and public - the second
1142 // transaction will not be executed
1143 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1145 retCode = saveDataHelper(cred,
1148 DataType(prv.getType()),
1151 if (CKM_API_SUCCESS != retCode)
1154 retCode = saveDataHelper(cred,
1157 DataType(pub.getType()),
1160 if (CKM_API_SUCCESS != retCode)
1163 transactionPub.commit();
1164 transactionPriv.commit();
1169 RawBuffer CKMLogic::createKeyPair(
1170 const Credentials &cred,
1171 LogicCommand protocol_cmd,
1173 const int additional_param,
1174 const Name &namePrivate,
1175 const Label &labelPrivate,
1176 const Name &namePublic,
1177 const Label &labelPublic,
1178 const PolicySerializable &policyPrivate,
1179 const PolicySerializable &policyPublic)
1181 int retCode = CKM_API_SUCCESS;
1183 KeyType key_type = KeyType::KEY_NONE;
1184 switch(protocol_cmd)
1186 case LogicCommand::CREATE_KEY_PAIR_RSA:
1187 key_type = KeyType::KEY_RSA_PUBLIC;
1189 case LogicCommand::CREATE_KEY_PAIR_DSA:
1190 key_type = KeyType::KEY_DSA_PUBLIC;
1192 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
1193 key_type = KeyType::KEY_ECDSA_PUBLIC;
1200 retCode = createKeyPairHelper(
1210 } catch (DB::Crypto::Exception::TransactionError &e) {
1211 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1212 retCode = CKM_API_ERROR_DB_ERROR;
1213 } catch (CKM::CryptoLogic::Exception::Base &e) {
1214 LogDebug("CryptoLogic error: " << e.GetMessage());
1215 retCode = CKM_API_ERROR_SERVER_ERROR;
1216 } catch (DB::Crypto::Exception::InternalError &e) {
1217 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1218 retCode = CKM_API_ERROR_DB_ERROR;
1219 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1220 LogError("Error " << e.GetMessage());
1221 retCode = CKM_API_ERROR_DB_LOCKED;
1222 } catch (const CKM::Exception &e) {
1223 LogError("CKM::Exception: " << e.GetMessage());
1224 retCode = CKM_API_ERROR_SERVER_ERROR;
1227 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
1230 int CKMLogic::readCertificateHelper(
1231 const Credentials &cred,
1232 const LabelNameVector &labelNameVector,
1233 CertificateImplVector &certVector)
1236 for (auto &i: labelNameVector) {
1237 int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1238 if (ec != CKM_API_SUCCESS)
1240 certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1242 // try to read chain certificates (if present)
1243 DB::RowVector rawCaChain;
1244 ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1245 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1247 for(auto &rawCaCert : rawCaChain)
1248 certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1250 return CKM_API_SUCCESS;
1253 int CKMLogic::getCertificateChainHelper(
1254 const CertificateImpl &cert,
1255 const RawBufferVector &untrustedCertificates,
1256 const RawBufferVector &trustedCertificates,
1257 bool useTrustedSystemCertificates,
1258 RawBufferVector &chainRawVector)
1260 CertificateImplVector untrustedCertVector;
1261 CertificateImplVector trustedCertVector;
1262 CertificateImplVector chainVector;
1265 return CKM_API_ERROR_INPUT_PARAM;
1267 for (auto &e: untrustedCertificates)
1268 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1269 for (auto &e: trustedCertificates)
1270 trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1272 CertificateStore store;
1273 int retCode = store.verifyCertificate(cert,
1274 untrustedCertVector,
1276 useTrustedSystemCertificates,
1277 m_accessControl.isCCMode(),
1279 if (retCode != CKM_API_SUCCESS)
1282 for (auto &e : chainVector)
1283 chainRawVector.push_back(e.getDER());
1284 return CKM_API_SUCCESS;
1287 int CKMLogic::getCertificateChainHelper(
1288 const Credentials &cred,
1289 const CertificateImpl &cert,
1290 const LabelNameVector &untrusted,
1291 const LabelNameVector &trusted,
1292 bool useTrustedSystemCertificates,
1293 RawBufferVector &chainRawVector)
1295 CertificateImplVector untrustedCertVector;
1296 CertificateImplVector trustedCertVector;
1297 CertificateImplVector chainVector;
1301 return CKM_API_ERROR_INPUT_PARAM;
1303 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1304 if (retCode != CKM_API_SUCCESS)
1306 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1307 if (retCode != CKM_API_SUCCESS)
1310 CertificateStore store;
1311 retCode = store.verifyCertificate(cert,
1312 untrustedCertVector,
1314 useTrustedSystemCertificates,
1315 m_accessControl.isCCMode(),
1317 if (retCode != CKM_API_SUCCESS)
1320 for (auto &i: chainVector)
1321 chainRawVector.push_back(i.getDER());
1323 return CKM_API_SUCCESS;
1326 RawBuffer CKMLogic::getCertificateChain(
1327 const Credentials & /*cred*/,
1329 const RawBuffer &certificate,
1330 const RawBufferVector &untrustedCertificates,
1331 const RawBufferVector &trustedCertificates,
1332 bool useTrustedSystemCertificates)
1334 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1335 RawBufferVector chainRawVector;
1336 int retCode = CKM_API_ERROR_UNKNOWN;
1338 retCode = getCertificateChainHelper(cert,
1339 untrustedCertificates,
1340 trustedCertificates,
1341 useTrustedSystemCertificates,
1343 } catch (const CryptoLogic::Exception::Base &e) {
1344 LogError("CryptoLogic failed with message: " << e.GetMessage());
1345 retCode = CKM_API_ERROR_SERVER_ERROR;
1346 } catch (const DB::Crypto::Exception::Base &e) {
1347 LogError("DB::Crypto failed with message: " << e.GetMessage());
1348 retCode = CKM_API_ERROR_DB_ERROR;
1349 } catch (const std::exception& e) {
1350 LogError("STD exception " << e.what());
1351 retCode = CKM_API_ERROR_SERVER_ERROR;
1353 LogError("Unknown error.");
1356 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1360 return response.Pop();
1363 RawBuffer CKMLogic::getCertificateChain(
1364 const Credentials &cred,
1366 const RawBuffer &certificate,
1367 const LabelNameVector &untrustedCertificates,
1368 const LabelNameVector &trustedCertificates,
1369 bool useTrustedSystemCertificates)
1371 int retCode = CKM_API_ERROR_UNKNOWN;
1372 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1373 RawBufferVector chainRawVector;
1375 retCode = getCertificateChainHelper(cred,
1377 untrustedCertificates,
1378 trustedCertificates,
1379 useTrustedSystemCertificates,
1381 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1382 LogError("CryptoLogic failed with message: " << e.GetMessage());
1383 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1384 } catch (const CryptoLogic::Exception::Base &e) {
1385 LogError("CryptoLogic failed with message: " << e.GetMessage());
1386 retCode = CKM_API_ERROR_SERVER_ERROR;
1387 } catch (const DB::Crypto::Exception::Base &e) {
1388 LogError("DB::Crypto failed with message: " << e.GetMessage());
1389 retCode = CKM_API_ERROR_DB_ERROR;
1390 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1391 LogError("Error " << e.GetMessage());
1392 retCode = CKM_API_ERROR_DB_LOCKED;
1393 } catch (const std::exception& e) {
1394 LogError("STD exception " << e.what());
1395 retCode = CKM_API_ERROR_SERVER_ERROR;
1397 LogError("Unknown error.");
1400 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1404 return response.Pop();
1407 RawBuffer CKMLogic::createSignature(
1408 const Credentials &cred,
1410 const Name &privateKeyName,
1411 const Label & ownerLabel,
1412 const Password &password, // password for private_key
1413 const RawBuffer &message,
1414 const HashAlgorithm hash,
1415 const RSAPaddingAlgorithm padding)
1418 Crypto::SW::CryptoService cs;
1419 RawBuffer signature;
1421 int retCode = CKM_API_SUCCESS;
1424 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1425 if(retCode == CKM_API_SUCCESS)
1427 KeyImpl keyParsed(row.data, Password());
1428 if (keyParsed.empty())
1429 retCode = CKM_API_ERROR_SERVER_ERROR;
1431 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
1433 } catch (const KeyProvider::Exception::Base &e) {
1434 LogError("KeyProvider failed with message: " << e.GetMessage());
1435 retCode = CKM_API_ERROR_SERVER_ERROR;
1436 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1437 LogError("CryptoLogic failed with message: " << e.GetMessage());
1438 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1439 } catch (const CryptoLogic::Exception::Base &e) {
1440 LogError("CryptoLogic failed with message: " << e.GetMessage());
1441 retCode = CKM_API_ERROR_SERVER_ERROR;
1442 } catch (const DB::Crypto::Exception::Base &e) {
1443 LogError("DB::Crypto failed with message: " << e.GetMessage());
1444 retCode = CKM_API_ERROR_DB_ERROR;
1445 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1446 LogError("Error " << e.GetMessage());
1447 retCode = CKM_API_ERROR_DB_LOCKED;
1448 } catch (const CKM::Exception &e) {
1449 LogError("Unknown CKM::Exception: " << e.GetMessage());
1450 retCode = CKM_API_ERROR_SERVER_ERROR;
1453 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1457 return response.Pop();
1460 RawBuffer CKMLogic::verifySignature(
1461 const Credentials &cred,
1463 const Name &publicKeyOrCertName,
1464 const Label & ownerLabel,
1465 const Password &password, // password for public_key (optional)
1466 const RawBuffer &message,
1467 const RawBuffer &signature,
1468 const HashAlgorithm hash,
1469 const RSAPaddingAlgorithm padding)
1471 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1475 Crypto::SW::CryptoService cs;
1479 // try certificate first - looking for a public key.
1480 // in case of PKCS, pub key from certificate will be found first
1481 // rather than private key from the same PKCS.
1482 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
1483 if (retCode == CKM_API_SUCCESS) {
1484 CertificateImpl cert(row.data, DataFormat::FORM_DER);
1485 key = cert.getKeyImpl();
1486 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1487 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
1488 if (retCode != CKM_API_SUCCESS)
1490 key = KeyImpl(row.data);
1496 retCode = CKM_API_ERROR_SERVER_ERROR;
1500 retCode = cs.verifySignature(key, message, signature, hash, padding);
1502 } catch (const Crypto::SW::CryptoService::Exception::Crypto_internal &e) {
1503 LogError("KeyProvider failed with message: " << e.GetMessage());
1504 retCode = CKM_API_ERROR_SERVER_ERROR;
1505 } catch (const Crypto::SW::CryptoService::Exception::opensslError &e) {
1506 LogError("KeyProvider failed with message: " << e.GetMessage());
1507 retCode = CKM_API_ERROR_SERVER_ERROR;
1508 } catch (const KeyProvider::Exception::Base &e) {
1509 LogError("KeyProvider failed with error: " << e.GetMessage());
1510 retCode = CKM_API_ERROR_SERVER_ERROR;
1511 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1512 LogError("CryptoLogic failed with message: " << e.GetMessage());
1513 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1514 } catch (const CryptoLogic::Exception::Base &e) {
1515 LogError("CryptoLogic failed with message: " << e.GetMessage());
1516 retCode = CKM_API_ERROR_SERVER_ERROR;
1517 } catch (const DB::Crypto::Exception::Base &e) {
1518 LogError("DB::Crypto failed with message: " << e.GetMessage());
1519 retCode = CKM_API_ERROR_DB_ERROR;
1520 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1521 LogError("Error " << e.GetMessage());
1522 retCode = CKM_API_ERROR_DB_LOCKED;
1523 } catch (const CKM::Exception &e) {
1524 LogError("Unknown CKM::Exception: " << e.GetMessage());
1525 retCode = CKM_API_ERROR_SERVER_ERROR;
1528 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1531 return response.Pop();
1534 int CKMLogic::setPermissionHelper(
1535 const Credentials &cred, // who's the client
1537 const Label &label, // who's the owner
1538 const Label &accessorLabel, // who will get the access
1539 const PermissionMask permissionMask)
1541 auto &handler = selectDatabase(cred, label);
1543 // we don't know the client
1544 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1545 return CKM_API_ERROR_INPUT_PARAM;
1547 // use client label if not explicitly provided
1548 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1550 // verify name and label are correct
1551 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1552 return CKM_API_ERROR_INPUT_PARAM;
1554 // currently we don't support modification of owner's permissions to his own rows
1555 if (ownerLabel==accessorLabel)
1556 return CKM_API_ERROR_INPUT_PARAM;
1558 // system database does not support write/remove permissions
1559 if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
1560 (permissionMask & Permission::REMOVE))
1561 return CKM_API_ERROR_INPUT_PARAM;
1563 // can the client modify permissions to owner's row?
1564 int retCode = m_accessControl.canModify(cred, ownerLabel);
1565 if(retCode != CKM_API_SUCCESS)
1568 DB::Crypto::Transaction transaction(&handler.database);
1570 if( !handler.database.isNameLabelPresent(name, ownerLabel) )
1571 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1573 // removing non-existing permissions: fail
1574 if(permissionMask == Permission::NONE)
1576 if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1577 return CKM_API_ERROR_INPUT_PARAM;
1580 // set permissions to the row owned by ownerLabel for accessorLabel
1581 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1582 transaction.commit();
1584 return CKM_API_SUCCESS;
1587 RawBuffer CKMLogic::setPermission(
1588 const Credentials &cred,
1593 const Label &accessorLabel,
1594 const PermissionMask permissionMask)
1598 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1599 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1600 LogError("Error " << e.GetMessage());
1601 retCode = CKM_API_ERROR_DB_LOCKED;
1602 } Catch (CKM::Exception) {
1603 LogError("Error in set row!");
1604 retCode = CKM_API_ERROR_DB_ERROR;
1607 return MessageBuffer::Serialize(command, msgID, retCode).Pop();