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 <key-aes-impl.h>
31 #include <certificate-config.h>
32 #include <certificate-store.h>
35 #include <InitialValuesFile.h>
36 #include <sw-backend/store.h>
37 #include <generic-backend/exception.h>
40 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
41 const char * const INIT_VALUES_DIR = "/opt/data/ckm/initial_values/";
42 const char * const INIT_VALUES_XSD = "/usr/share/ckm/initial_values.xsd";
43 const char * const INIT_VALUES_FILE_SUFFIX = ".xml";
44 const char * const SYSTEM_DB_PASSWD = "cAtRugU7";
46 bool isLabelValid(const CKM::Label &label) {
47 // TODO: copy code from libprivilege control (for check smack label)
48 if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
53 bool isNameValid(const CKM::Name &name) {
54 if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
58 } // anonymous namespace
62 const uid_t CKMLogic::SYSTEM_DB_UID = 0;
66 CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
68 m_accessControl.updateCCMode();
70 // make initial file list
71 std::vector<std::string> filesToParse;
72 DIR *dp = opendir(INIT_VALUES_DIR);
76 while ((entry = readdir(dp)))
78 std::string filename = std::string(entry->d_name);
81 std::string lowercaseFilename = filename;
82 std::transform(lowercaseFilename.begin(), lowercaseFilename.end(), lowercaseFilename.begin(), ::tolower);
83 if(lowercaseFilename.find(INIT_VALUES_FILE_SUFFIX) == std::string::npos)
86 filesToParse.push_back(std::string(INIT_VALUES_DIR) + filename);
92 for(const auto & file : filesToParse)
94 InitialValues::InitialValuesFile xmlFile(file.c_str(), *this);
95 int rc = xmlFile.Validate(INIT_VALUES_XSD);
96 if(rc == XML::Parser::PARSE_SUCCESS)
99 if(rc != XML::Parser::PARSE_SUCCESS)
100 LogError("invalid initial values file: " << file << ", parsing code: " << rc);
103 LogError("invalid initial values file: " << file << ", validation code: " << rc);
104 unlink(file.c_str());
108 CKMLogic::~CKMLogic(){}
110 void CKMLogic::loadDKEKFile(uid_t user, const Password &password) {
111 auto &handle = m_userDataMap[user];
115 auto wrappedDKEK = fs.getDKEK();
117 if (wrappedDKEK.empty()) {
118 wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
119 fs.saveDKEK(wrappedDKEK);
122 handle.keyProvider = KeyProvider(wrappedDKEK, password);
125 void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
126 auto &handle = m_userDataMap[user];
129 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
132 int CKMLogic::unlockDatabase(uid_t user, const Password & password)
134 if (0<m_userDataMap.count(user) && m_userDataMap[user].keyProvider.isInitialized())
135 return CKM_API_SUCCESS;
137 int retCode = CKM_API_SUCCESS;
140 auto &handle = m_userDataMap[user];
143 loadDKEKFile(user, password);
145 auto wrappedDatabaseDEK = fs.getDBDEK();
146 if (wrappedDatabaseDEK.empty()) {
147 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
148 fs.saveDBDEK(wrappedDatabaseDEK);
151 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
153 handle.database = DB::Crypto(fs.getDBPath(), key);
154 handle.crypto = CryptoLogic();
156 if ( !m_accessControl.isSystemService(user) )
158 // remove data of removed apps during locked state
159 AppLabelVector removedApps = fs.clearRemovedsApps();
160 for(auto& appSmackLabel : removedApps) {
161 handle.crypto.removeKey(appSmackLabel);
162 handle.database.deleteKey(appSmackLabel);
165 } catch (const KeyProvider::Exception::PassWordError &e) {
166 LogError("Incorrect Password " << e.GetMessage());
167 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
168 } catch (const KeyProvider::Exception::Base &e) {
169 LogError("Error in KeyProvider " << e.GetMessage());
170 retCode = CKM_API_ERROR_SERVER_ERROR;
171 } catch (const Exc::Exception &e) {
173 } catch (const CKM::Exception &e) {
174 LogError("CKM::Exception: " << e.GetMessage());
175 retCode = CKM_API_ERROR_SERVER_ERROR;
178 if (CKM_API_SUCCESS != retCode)
179 m_userDataMap.erase(user);
184 int CKMLogic::unlockSystemDB()
186 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
189 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
191 // if user trying to access system service - check:
192 // * if user database is unlocked [mandatory]
193 // * if not - proceed with regular user database
194 // * if explicit system database label given -> switch to system DB
195 if ( !m_accessControl.isSystemService(cred) )
197 if (0 == m_userDataMap.count(cred.clientUid))
198 ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked");
200 if (0 != incoming_label.compare(LABEL_SYSTEM_DB))
201 return m_userDataMap[cred.clientUid];
204 // system database selected, modify the label
205 if (CKM_API_SUCCESS != unlockSystemDB() )
206 ThrowErr(Exc::DatabaseLocked, "can not unlock system database");
207 return m_userDataMap[SYSTEM_DB_UID];
210 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
212 int retCode = CKM_API_SUCCESS;
214 if( !m_accessControl.isSystemService(user) )
216 retCode = unlockDatabase(user, password);
220 // do not allow lock/unlock operations for system users
221 retCode = CKM_API_ERROR_INPUT_PARAM;
224 return MessageBuffer::Serialize(retCode).Pop();
227 RawBuffer CKMLogic::updateCCMode() {
228 m_accessControl.updateCCMode();
229 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
232 RawBuffer CKMLogic::lockUserKey(uid_t user)
234 int retCode = CKM_API_SUCCESS;
235 if( !m_accessControl.isSystemService(user) )
237 m_userDataMap.erase(user);
241 // do not allow lock/unlock operations for system users
242 retCode = CKM_API_ERROR_INPUT_PARAM;
245 return MessageBuffer::Serialize(retCode).Pop();
249 RawBuffer CKMLogic::removeUserData(uid_t user) {
250 int retCode = CKM_API_SUCCESS;
252 if (m_accessControl.isSystemService(user))
253 user = SYSTEM_DB_UID;
255 m_userDataMap.erase(user);
260 return MessageBuffer::Serialize(retCode).Pop();
263 int CKMLogic::changeUserPasswordHelper(uid_t user,
264 const Password &oldPassword,
265 const Password &newPassword)
267 // do not allow to change system database password
268 if( m_accessControl.isSystemService(user) )
269 return CKM_API_ERROR_INPUT_PARAM;
271 loadDKEKFile(user, oldPassword);
272 saveDKEKFile(user, newPassword);
274 return CKM_API_SUCCESS;
277 RawBuffer CKMLogic::changeUserPassword(
279 const Password &oldPassword,
280 const Password &newPassword)
282 int retCode = CKM_API_SUCCESS;
285 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
286 } catch (const KeyProvider::Exception::PassWordError &e) {
287 LogError("Incorrect Password " << e.GetMessage());
288 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
289 } catch (const KeyProvider::Exception::Base &e) {
290 LogError("Error in KeyProvider " << e.GetMessage());
291 retCode = CKM_API_ERROR_SERVER_ERROR;
292 } catch (const Exc::Exception &e) {
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 int CKMLogic::resetUserPasswordHelper(
304 const Password &newPassword)
306 // do not allow to reset system database password
307 if( m_accessControl.isSystemService(user) )
308 return CKM_API_ERROR_INPUT_PARAM;
310 int retCode = CKM_API_SUCCESS;
311 if (0 == m_userDataMap.count(user))
313 // Check if key exists. If exists we must return error
315 auto wrappedDKEKMain = fs.getDKEK();
316 if (!wrappedDKEKMain.empty())
317 retCode = CKM_API_ERROR_BAD_REQUEST;
319 saveDKEKFile(user, newPassword);
325 RawBuffer CKMLogic::resetUserPassword(
327 const Password &newPassword)
329 int retCode = CKM_API_SUCCESS;
331 retCode = resetUserPasswordHelper(user, newPassword);
332 } catch (const Exc::Exception &e) {
334 } catch (const CKM::Exception &e) {
335 LogError("CKM::Exception: " << e.GetMessage());
336 retCode = CKM_API_ERROR_SERVER_ERROR;
339 return MessageBuffer::Serialize(retCode).Pop();
342 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
343 int retCode = CKM_API_SUCCESS;
347 if (smackLabel.empty()) {
348 retCode = CKM_API_ERROR_INPUT_PARAM;
350 UidVector uids = FileSystem::getUIDsFromDBFile();
351 for (auto userId : uids) {
352 if (0 == m_userDataMap.count(userId)) {
353 FileSystem fs(userId);
354 fs.addRemovedApp(smackLabel);
356 auto &handle = m_userDataMap[userId];
357 handle.crypto.removeKey(smackLabel);
358 handle.database.deleteKey(smackLabel);
363 } catch (const DB::Crypto::Exception::InternalError &e) {
364 LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
365 retCode = CKM_API_ERROR_DB_ERROR;
366 } catch (const DB::Crypto::Exception::TransactionError &e) {
367 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
368 retCode = CKM_API_ERROR_DB_ERROR;
369 } catch (const Exc::Exception &e) {
371 } catch (const CKM::Exception &e) {
372 LogError("CKM::Exception: " << e.GetMessage());
373 retCode = CKM_API_ERROR_SERVER_ERROR;
376 return MessageBuffer::Serialize(retCode).Pop();
379 int CKMLogic::checkSaveConditions(
380 const Credentials &cred,
383 const Label &ownerLabel)
385 // verify name and label are correct
386 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
387 LogWarning("Invalid parameter passed to key-manager");
388 return CKM_API_ERROR_INPUT_PARAM;
391 // check if allowed to save using ownerLabel
392 int access_ec = m_accessControl.canSave(cred, ownerLabel);
393 if( access_ec != CKM_API_SUCCESS)
395 LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
399 // check if not a duplicate
400 if( handler.database.isNameLabelPresent(name, ownerLabel))
401 return CKM_API_ERROR_DB_ALIAS_EXISTS;
403 // encryption section
404 if (!handler.crypto.haveKey(ownerLabel))
407 auto key_optional = handler.database.getKey(ownerLabel);
409 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
410 got_key = handler.keyProvider.generateDEK(ownerLabel);
411 handler.database.saveKey(ownerLabel, got_key);
413 LogDebug("Key from DB");
414 got_key = *key_optional;
417 got_key = handler.keyProvider.getPureDEK(got_key);
418 handler.crypto.pushKey(ownerLabel, got_key);
421 return CKM_API_SUCCESS;
424 DB::Row CKMLogic::createEncryptedRow(
429 const RawBuffer &data,
430 const Policy &policy) const
432 DB::Row row(name, label, static_cast<int>(policy.extractable), dataType, data, static_cast<int>(data.size()));
433 row.backendId = m_decider.chooseCryptoBackend(dataType, policy.extractable);
435 // do not encrypt data with password during cc_mode on
436 if(m_accessControl.isCCMode()) {
437 crypto.encryptRow("", row);
439 crypto.encryptRow(policy.password, row);
444 int CKMLogic::verifyBinaryData(DataType dataType, RawBuffer &input_data) const
447 return toBinaryData(dataType, input_data, dummy);
450 int CKMLogic::toBinaryData(DataType dataType,
451 const RawBuffer &input_data,
452 RawBuffer &output_data) const
454 // verify the data integrity
455 if (dataType.isKey())
458 if(dataType.isSKey())
459 output_key = CKM::Key::createAES(input_data);
461 output_key = CKM::Key::create(input_data);
462 if(output_key.get() == NULL)
464 LogError("provided binary data is not valid key data");
465 return CKM_API_ERROR_INPUT_PARAM;
467 output_data = output_key->getDER();
469 else if (dataType.isCertificate() || dataType.isChainCert())
471 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
472 if(cert.get() == NULL)
474 LogError("provided binary data is not valid certificate data");
475 return CKM_API_ERROR_INPUT_PARAM;
477 output_data = cert->getDER();
480 output_data = input_data;
481 // TODO: add here BINARY_DATA verification, i.e: max size etc.
482 return CKM_API_SUCCESS;
485 int CKMLogic::verifyAndSaveDataHelper(
486 const Credentials &cred,
489 const RawBuffer &data,
491 const PolicySerializable &policy)
493 int retCode = CKM_API_ERROR_UNKNOWN;
496 // check if data is correct
497 RawBuffer binaryData;
498 retCode = toBinaryData(dataType, data, binaryData);
499 if(retCode == CKM_API_SUCCESS)
501 retCode = saveDataHelper(cred, name, label, dataType, binaryData, policy);
503 } catch (const KeyProvider::Exception::Base &e) {
504 LogError("KeyProvider failed with message: " << e.GetMessage());
505 retCode = CKM_API_ERROR_SERVER_ERROR;
506 } catch (const DB::Crypto::Exception::InternalError &e) {
507 LogError("DB::Crypto failed with message: " << e.GetMessage());
508 retCode = CKM_API_ERROR_DB_ERROR;
509 } catch (const DB::Crypto::Exception::TransactionError &e) {
510 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
511 retCode = CKM_API_ERROR_DB_ERROR;
512 } catch (const Exc::Exception &e) {
514 } catch (const CKM::Exception &e) {
515 LogError("CKM::Exception: " << e.GetMessage());
516 retCode = CKM_API_ERROR_SERVER_ERROR;
521 RawBuffer CKMLogic::saveData(
522 const Credentials &cred,
526 const RawBuffer &data,
528 const PolicySerializable &policy)
530 int retCode = verifyAndSaveDataHelper(cred, name, label, data, dataType, policy);
531 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
534 static_cast<int>(dataType));
535 return response.Pop();
538 int CKMLogic::extractPKCS12Data(
541 const Label &ownerLabel,
542 const PKCS12Serializable &pkcs,
543 const PolicySerializable &keyPolicy,
544 const PolicySerializable &certPolicy,
545 DB::RowVector &output) const
547 // private key is mandatory
549 return CKM_API_ERROR_INVALID_FORMAT;
550 Key* keyPtr = pkcs.getKey().get();
551 DataType keyType = DataType(keyPtr->getType());
552 RawBuffer keyData = keyPtr->getDER();
553 int retCode = verifyBinaryData(keyType, keyData);
554 if(retCode != CKM_API_SUCCESS)
556 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
558 // certificate is mandatory
559 if( !pkcs.getCertificate() )
560 return CKM_API_ERROR_INVALID_FORMAT;
561 RawBuffer certData = pkcs.getCertificate().get()->getDER();
562 retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
563 if(retCode != CKM_API_SUCCESS)
565 output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
568 unsigned int cert_index = 0;
569 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
571 DataType chainDataType = DataType::getChainDatatype(cert_index ++);
572 RawBuffer caCertData = ca->getDER();
573 int retCode = verifyBinaryData(chainDataType, caCertData);
574 if(retCode != CKM_API_SUCCESS)
577 output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
580 return CKM_API_SUCCESS;
583 RawBuffer CKMLogic::savePKCS12(
584 const Credentials &cred,
588 const PKCS12Serializable &pkcs,
589 const PolicySerializable &keyPolicy,
590 const PolicySerializable &certPolicy)
592 int retCode = CKM_API_ERROR_UNKNOWN;
594 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
595 } catch (const KeyProvider::Exception::Base &e) {
596 LogError("KeyProvider failed with message: " << e.GetMessage());
597 retCode = CKM_API_ERROR_SERVER_ERROR;
598 } catch (const DB::Crypto::Exception::InternalError &e) {
599 LogError("DB::Crypto failed with message: " << e.GetMessage());
600 retCode = CKM_API_ERROR_DB_ERROR;
601 } catch (const DB::Crypto::Exception::TransactionError &e) {
602 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
603 retCode = CKM_API_ERROR_DB_ERROR;
604 } catch (const CKM::Exception &e) {
605 LogError("CKM::Exception: " << e.GetMessage());
606 retCode = CKM_API_ERROR_SERVER_ERROR;
609 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
612 return response.Pop();
616 int CKMLogic::removeDataHelper(
617 const Credentials &cred,
621 auto &handler = selectDatabase(cred, label);
623 // use client label if not explicitly provided
624 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
625 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
626 LogError("Invalid label or name format");
627 return CKM_API_ERROR_INPUT_PARAM;
630 DB::Crypto::Transaction transaction(&handler.database);
632 // read and check permissions
633 PermissionMaskOptional permissionRowOpt =
634 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
635 int retCode = m_accessControl.canDelete(cred,
636 PermissionForLabel(cred.smackLabel, permissionRowOpt));
637 if(retCode != CKM_API_SUCCESS)
639 LogWarning("access control check result: " << retCode);
643 auto erased = handler.database.deleteRow(name, ownerLabel);
644 // check if the data existed or not
646 transaction.commit();
648 LogError("No row for given name and label");
649 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
652 return CKM_API_SUCCESS;
655 RawBuffer CKMLogic::removeData(
656 const Credentials &cred,
661 int retCode = CKM_API_ERROR_UNKNOWN;
665 retCode = removeDataHelper(cred, name, label);
667 catch (const Exc::Exception &e)
671 catch (const CKM::Exception &)
673 LogError("Error in deleting row!");
674 retCode = CKM_API_ERROR_DB_ERROR;
677 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
680 return response.Pop();
683 int CKMLogic::readSingleRow(const Name &name,
684 const Label &ownerLabel,
686 DB::Crypto & database,
689 DB::Crypto::RowOptional row_optional;
690 if (dataType.isKey())
692 // read all key types
693 row_optional = database.getRow(name,
695 DataType::DB_KEY_FIRST,
696 DataType::DB_KEY_LAST);
698 // read anything else
699 row_optional = database.getRow(name,
705 LogError("No row for given name, label and type");
706 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
711 return CKM_API_SUCCESS;
715 int CKMLogic::readMultiRow(const Name &name,
716 const Label &ownerLabel,
718 DB::Crypto & database,
719 DB::RowVector &output)
721 if (dataType.isKey())
723 // read all key types
724 database.getRows(name,
726 DataType::DB_KEY_FIRST,
727 DataType::DB_KEY_LAST,
730 else if (dataType.isChainCert())
732 // read all key types
733 database.getRows(name,
735 DataType::DB_CHAIN_FIRST,
736 DataType::DB_CHAIN_LAST,
741 // read anything else
742 database.getRows(name,
749 LogError("No row for given name, label and type");
750 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
753 return CKM_API_SUCCESS;
756 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
758 const Label &ownerLabel,
759 const Label &accessorLabel,
762 DB::Crypto & database)
764 PermissionMaskOptional permissionRowOpt =
765 database.getPermissionRow(name, ownerLabel, accessorLabel);
768 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
769 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
772 int CKMLogic::readDataHelper(
774 const Credentials &cred,
778 const Password &password,
781 auto &handler = selectDatabase(cred, label);
783 // use client label if not explicitly provided
784 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
786 if (!isNameValid(name) || !isLabelValid(ownerLabel))
787 return CKM_API_ERROR_INPUT_PARAM;
790 DB::Crypto::Transaction transaction(&handler.database);
791 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
792 if(CKM_API_SUCCESS != retCode)
795 // all read rows belong to the same owner
796 DB::Row & firstRow = rows.at(0);
798 // check access rights
799 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
800 if(CKM_API_SUCCESS != retCode)
804 if (!handler.crypto.haveKey(firstRow.ownerLabel)) {
806 auto key_optional = handler.database.getKey(firstRow.ownerLabel);
808 LogError("No key for given label in database");
809 return CKM_API_ERROR_DB_ERROR;
812 key = handler.keyProvider.getPureDEK(key);
813 handler.crypto.pushKey(firstRow.ownerLabel, key);
815 for(auto &row : rows)
816 handler.crypto.decryptRow(password, row);
818 return CKM_API_SUCCESS;
821 int CKMLogic::readDataHelper(
823 const Credentials &cred,
827 const Password &password,
830 auto &handler = selectDatabase(cred, label);
832 // use client label if not explicitly provided
833 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
835 if (!isNameValid(name) || !isLabelValid(ownerLabel))
836 return CKM_API_ERROR_INPUT_PARAM;
839 DB::Crypto::Transaction transaction(&handler.database);
840 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
841 if(CKM_API_SUCCESS != retCode)
844 // check access rights
845 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
846 if(CKM_API_SUCCESS != retCode)
850 if (!handler.crypto.haveKey(row.ownerLabel)) {
852 auto key_optional = handler.database.getKey(row.ownerLabel);
854 LogError("No key for given label in database");
855 return CKM_API_ERROR_DB_ERROR;
858 key = handler.keyProvider.getPureDEK(key);
859 handler.crypto.pushKey(row.ownerLabel, key);
861 handler.crypto.decryptRow(password, row);
863 return CKM_API_SUCCESS;
866 RawBuffer CKMLogic::getData(
867 const Credentials &cred,
872 const Password &password)
874 int retCode = CKM_API_SUCCESS;
878 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
879 } catch (const KeyProvider::Exception::Base &e) {
880 LogError("KeyProvider failed with error: " << e.GetMessage());
881 retCode = CKM_API_ERROR_SERVER_ERROR;
882 } catch (const DB::Crypto::Exception::Base &e) {
883 LogError("DB::Crypto failed with message: " << e.GetMessage());
884 retCode = CKM_API_ERROR_DB_ERROR;
885 } catch (const Exc::Exception &e) {
887 } catch (const CKM::Exception &e) {
888 LogError("CKM::Exception: " << e.GetMessage());
889 retCode = CKM_API_ERROR_SERVER_ERROR;
892 if (CKM_API_SUCCESS != retCode) {
894 row.dataType = dataType;
897 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
900 static_cast<int>(row.dataType),
902 return response.Pop();
905 int CKMLogic::getPKCS12Helper(
906 const Credentials &cred,
909 const Password &keyPassword,
910 const Password &certPassword,
912 CertificateShPtr & cert,
913 CertificateShPtrVector & caChain)
917 // read private key (mandatory)
919 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
920 if(retCode != CKM_API_SUCCESS)
922 privKey = CKM::Key::create(privKeyRow.data);
924 // read certificate (mandatory)
926 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
927 if(retCode != CKM_API_SUCCESS)
929 cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
931 // read CA cert chain (optional)
932 DB::RowVector rawCaChain;
933 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
934 if(retCode != CKM_API_SUCCESS &&
935 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
937 for(auto &rawCaCert : rawCaChain)
938 caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
940 // if anything found, return it
941 if(privKey || cert || caChain.size()>0)
942 retCode = CKM_API_SUCCESS;
947 RawBuffer CKMLogic::getPKCS12(
948 const Credentials &cred,
952 const Password &keyPassword,
953 const Password &certPassword)
955 int retCode = CKM_API_ERROR_UNKNOWN;
957 PKCS12Serializable output;
960 CertificateShPtr cert;
961 CertificateShPtrVector caChain;
962 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
965 if(retCode == CKM_API_SUCCESS)
966 output = PKCS12Serializable(privKey, cert, caChain);
968 } catch (const KeyProvider::Exception::Base &e) {
969 LogError("KeyProvider failed with error: " << e.GetMessage());
970 retCode = CKM_API_ERROR_SERVER_ERROR;
971 } catch (const DB::Crypto::Exception::Base &e) {
972 LogError("DB::Crypto failed with message: " << e.GetMessage());
973 retCode = CKM_API_ERROR_DB_ERROR;
974 } catch (const Exc::Exception &e) {
976 } catch (const CKM::Exception &e) {
977 LogError("CKM::Exception: " << e.GetMessage());
978 retCode = CKM_API_ERROR_SERVER_ERROR;
981 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
985 return response.Pop();
988 int CKMLogic::getDataListHelper(const Credentials &cred,
989 const DataType dataType,
990 LabelNameVector &labelNameVector)
992 int retCode = CKM_API_ERROR_DB_LOCKED;
993 if (0 < m_userDataMap.count(cred.clientUid))
995 auto &database = m_userDataMap[cred.clientUid].database;
998 LabelNameVector tmpVector;
999 if (dataType.isKey()) {
1000 // list all key types
1001 database.listNames(cred.smackLabel,
1003 DataType::DB_KEY_FIRST,
1004 DataType::DB_KEY_LAST);
1006 // list anything else
1007 database.listNames(cred.smackLabel,
1011 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
1012 retCode = CKM_API_SUCCESS;
1014 Catch (CKM::Exception) {
1015 LogError("Failed to get names");
1016 retCode = CKM_API_ERROR_DB_ERROR;
1022 RawBuffer CKMLogic::getDataList(
1023 const Credentials &cred,
1027 LabelNameVector systemVector;
1028 LabelNameVector userVector;
1029 LabelNameVector labelNameVector;
1031 int retCode = unlockSystemDB();
1032 if (CKM_API_SUCCESS == retCode)
1035 if (m_accessControl.isSystemService(cred))
1038 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1045 // user - lookup system, then client DB
1046 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1052 if(retCode == CKM_API_SUCCESS)
1054 retCode = getDataListHelper(cred,
1061 if(retCode == CKM_API_SUCCESS)
1063 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1064 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1066 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1069 static_cast<int>(dataType),
1071 return response.Pop();
1074 int CKMLogic::saveDataHelper(
1075 const Credentials &cred,
1079 const RawBuffer &data,
1080 const PolicySerializable &policy)
1082 auto &handler = selectDatabase(cred, label);
1084 // use client label if not explicitly provided
1085 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1086 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1087 return CKM_API_ERROR_INPUT_PARAM;
1089 // check if save is possible
1090 DB::Crypto::Transaction transaction(&handler.database);
1091 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1092 if(retCode != CKM_API_SUCCESS)
1096 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
1097 handler.database.saveRow(encryptedRow);
1099 transaction.commit();
1100 return CKM_API_SUCCESS;
1103 int CKMLogic::saveDataHelper(
1104 const Credentials &cred,
1107 const PKCS12Serializable &pkcs,
1108 const PolicySerializable &keyPolicy,
1109 const PolicySerializable &certPolicy)
1111 auto &handler = selectDatabase(cred, label);
1113 // use client label if not explicitly provided
1114 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1115 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1116 return CKM_API_ERROR_INPUT_PARAM;
1118 // check if save is possible
1119 DB::Crypto::Transaction transaction(&handler.database);
1120 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1121 if(retCode != CKM_API_SUCCESS)
1124 // extract and encrypt the data
1125 DB::RowVector encryptedRows;
1126 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1127 if(retCode != CKM_API_SUCCESS)
1131 handler.database.saveRows(name, ownerLabel, encryptedRows);
1132 transaction.commit();
1134 return CKM_API_SUCCESS;
1138 int CKMLogic::createKeyAESHelper(
1139 const Credentials &cred,
1143 const PolicySerializable &policy)
1145 CryptoAlgorithm keyGenAlgorithm;
1146 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
1147 Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm);
1149 return saveDataHelper(cred,
1158 int CKMLogic::createKeyPairHelper(
1159 const Credentials &cred,
1160 const CryptoAlgorithmSerializable & keyGenParams,
1161 const Name &namePrivate,
1162 const Label &labelPrivate,
1163 const Name &namePublic,
1164 const Label &labelPublic,
1165 const PolicySerializable &policyPrivate,
1166 const PolicySerializable &policyPublic)
1168 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1169 auto &handlerPub = selectDatabase(cred, labelPublic);
1171 AlgoType keyType = AlgoType::RSA_GEN;
1172 if(!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType))
1173 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found.");
1174 DataType dt(keyType);
1176 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
1178 bool exportable = policyPrivate.extractable || policyPublic.extractable;
1179 TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams);
1181 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1182 // in case the same database is used for private and public - the second
1183 // transaction will not be executed
1184 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1186 int retCode = saveDataHelper(cred,
1189 keys.first.dataType,
1192 if (CKM_API_SUCCESS != retCode)
1195 retCode = saveDataHelper(cred,
1198 keys.second.dataType,
1201 if (CKM_API_SUCCESS != retCode)
1204 transactionPub.commit();
1205 transactionPriv.commit();
1206 return CKM_API_SUCCESS;
1209 RawBuffer CKMLogic::createKeyPair(
1210 const Credentials &cred,
1212 const CryptoAlgorithmSerializable & keyGenParams,
1213 const Name &namePrivate,
1214 const Label &labelPrivate,
1215 const Name &namePublic,
1216 const Label &labelPublic,
1217 const PolicySerializable &policyPrivate,
1218 const PolicySerializable &policyPublic)
1220 int retCode = CKM_API_SUCCESS;
1223 retCode = createKeyPairHelper(
1232 } catch(const Exc::Exception &e) {
1233 retCode = e.error();
1234 } catch (DB::Crypto::Exception::TransactionError &e) {
1235 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1236 retCode = CKM_API_ERROR_DB_ERROR;
1237 } catch (DB::Crypto::Exception::InternalError &e) {
1238 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1239 retCode = CKM_API_ERROR_DB_ERROR;
1240 } catch (const CKM::Exception &e) {
1241 LogError("CKM::Exception: " << e.GetMessage());
1242 retCode = CKM_API_ERROR_SERVER_ERROR;
1245 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR),
1246 commandId, retCode).Pop();
1249 RawBuffer CKMLogic::createKeyAES(
1250 const Credentials &cred,
1255 const PolicySerializable &policy)
1257 int retCode = CKM_API_SUCCESS;
1260 retCode = createKeyAESHelper(cred, size, name, label, policy);
1261 } catch (const Exc::Exception &e) {
1262 retCode = e.error();
1263 } catch (std::invalid_argument &e) {
1264 LogDebug("invalid argument error: " << e.what());
1265 retCode = CKM_API_ERROR_INPUT_PARAM;
1266 } catch (DB::Crypto::Exception::TransactionError &e) {
1267 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1268 retCode = CKM_API_ERROR_DB_ERROR;
1269 } catch (DB::Crypto::Exception::InternalError &e) {
1270 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1271 retCode = CKM_API_ERROR_DB_ERROR;
1272 } catch (const CKM::Exception &e) {
1273 LogError("CKM::Exception: " << e.GetMessage());
1274 retCode = CKM_API_ERROR_SERVER_ERROR;
1277 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES),
1278 commandId, retCode).Pop();
1281 int CKMLogic::readCertificateHelper(
1282 const Credentials &cred,
1283 const LabelNameVector &labelNameVector,
1284 CertificateImplVector &certVector)
1287 for (auto &i: labelNameVector) {
1288 int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1289 if (ec != CKM_API_SUCCESS)
1291 certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1293 // try to read chain certificates (if present)
1294 DB::RowVector rawCaChain;
1295 ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1296 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1298 for(auto &rawCaCert : rawCaChain)
1299 certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1301 return CKM_API_SUCCESS;
1304 int CKMLogic::getCertificateChainHelper(
1305 const CertificateImpl &cert,
1306 const RawBufferVector &untrustedCertificates,
1307 const RawBufferVector &trustedCertificates,
1308 bool useTrustedSystemCertificates,
1309 RawBufferVector &chainRawVector)
1311 CertificateImplVector untrustedCertVector;
1312 CertificateImplVector trustedCertVector;
1313 CertificateImplVector chainVector;
1316 return CKM_API_ERROR_INPUT_PARAM;
1318 for (auto &e: untrustedCertificates)
1319 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1320 for (auto &e: trustedCertificates)
1321 trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1323 CertificateStore store;
1324 int retCode = store.verifyCertificate(cert,
1325 untrustedCertVector,
1327 useTrustedSystemCertificates,
1328 m_accessControl.isCCMode(),
1330 if (retCode != CKM_API_SUCCESS)
1333 for (auto &e : chainVector)
1334 chainRawVector.push_back(e.getDER());
1335 return CKM_API_SUCCESS;
1338 int CKMLogic::getCertificateChainHelper(
1339 const Credentials &cred,
1340 const CertificateImpl &cert,
1341 const LabelNameVector &untrusted,
1342 const LabelNameVector &trusted,
1343 bool useTrustedSystemCertificates,
1344 RawBufferVector &chainRawVector)
1346 CertificateImplVector untrustedCertVector;
1347 CertificateImplVector trustedCertVector;
1348 CertificateImplVector chainVector;
1352 return CKM_API_ERROR_INPUT_PARAM;
1354 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1355 if (retCode != CKM_API_SUCCESS)
1357 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1358 if (retCode != CKM_API_SUCCESS)
1361 CertificateStore store;
1362 retCode = store.verifyCertificate(cert,
1363 untrustedCertVector,
1365 useTrustedSystemCertificates,
1366 m_accessControl.isCCMode(),
1368 if (retCode != CKM_API_SUCCESS)
1371 for (auto &i: chainVector)
1372 chainRawVector.push_back(i.getDER());
1374 return CKM_API_SUCCESS;
1377 RawBuffer CKMLogic::getCertificateChain(
1378 const Credentials & /*cred*/,
1380 const RawBuffer &certificate,
1381 const RawBufferVector &untrustedCertificates,
1382 const RawBufferVector &trustedCertificates,
1383 bool useTrustedSystemCertificates)
1385 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1386 RawBufferVector chainRawVector;
1387 int retCode = CKM_API_ERROR_UNKNOWN;
1389 retCode = getCertificateChainHelper(cert,
1390 untrustedCertificates,
1391 trustedCertificates,
1392 useTrustedSystemCertificates,
1394 } catch (const Exc::Exception &e) {
1395 retCode = e.error();
1396 } catch (const DB::Crypto::Exception::Base &e) {
1397 LogError("DB::Crypto failed with message: " << e.GetMessage());
1398 retCode = CKM_API_ERROR_DB_ERROR;
1399 } catch (const std::exception& e) {
1400 LogError("STD exception " << e.what());
1401 retCode = CKM_API_ERROR_SERVER_ERROR;
1403 LogError("Unknown error.");
1406 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1410 return response.Pop();
1413 RawBuffer CKMLogic::getCertificateChain(
1414 const Credentials &cred,
1416 const RawBuffer &certificate,
1417 const LabelNameVector &untrustedCertificates,
1418 const LabelNameVector &trustedCertificates,
1419 bool useTrustedSystemCertificates)
1421 int retCode = CKM_API_ERROR_UNKNOWN;
1422 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1423 RawBufferVector chainRawVector;
1425 retCode = getCertificateChainHelper(cred,
1427 untrustedCertificates,
1428 trustedCertificates,
1429 useTrustedSystemCertificates,
1431 } catch (const DB::Crypto::Exception::Base &e) {
1432 LogError("DB::Crypto failed with message: " << e.GetMessage());
1433 retCode = CKM_API_ERROR_DB_ERROR;
1434 } catch (const Exc::Exception &e) {
1435 retCode = e.error();
1436 } catch (const std::exception& e) {
1437 LogError("STD exception " << e.what());
1438 retCode = CKM_API_ERROR_SERVER_ERROR;
1440 LogError("Unknown error.");
1443 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1447 return response.Pop();
1450 RawBuffer CKMLogic::createSignature(
1451 const Credentials &cred,
1453 const Name &privateKeyName,
1454 const Label & ownerLabel,
1455 const Password &password, // password for private_key
1456 const RawBuffer &message,
1457 const HashAlgorithm hash,
1458 const RSAPaddingAlgorithm padding)
1461 RawBuffer signature;
1462 CryptoAlgorithm cryptoAlg;
1463 cryptoAlg.setParam(ParamName::SV_HASH_ALGO, hash);
1464 cryptoAlg.setParam(ParamName::SV_RSA_PADDING, padding);
1466 int retCode = CKM_API_SUCCESS;
1469 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1470 if(retCode == CKM_API_SUCCESS) {
1471 signature = m_decider.getStore(row).getKey(row)->sign(cryptoAlg, message);
1473 } catch (const KeyProvider::Exception::Base &e) {
1474 LogError("KeyProvider failed with message: " << e.GetMessage());
1475 retCode = CKM_API_ERROR_SERVER_ERROR;
1476 } catch (const DB::Crypto::Exception::Base &e) {
1477 LogError("DB::Crypto failed with message: " << e.GetMessage());
1478 retCode = CKM_API_ERROR_DB_ERROR;
1479 } catch (const Exc::Exception &e) {
1480 retCode = e.error();
1481 } catch (const CKM::Exception &e) {
1482 LogError("Unknown CKM::Exception: " << e.GetMessage());
1483 retCode = CKM_API_ERROR_SERVER_ERROR;
1486 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1490 return response.Pop();
1493 RawBuffer CKMLogic::verifySignature(
1494 const Credentials &cred,
1496 const Name &publicKeyOrCertName,
1497 const Label & ownerLabel,
1498 const Password &password, // password for public_key (optional)
1499 const RawBuffer &message,
1500 const RawBuffer &signature,
1501 const HashAlgorithm hash,
1502 const RSAPaddingAlgorithm padding)
1504 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1509 CryptoAlgorithm params;
1510 params.setParam(ParamName::SV_HASH_ALGO, hash);
1511 params.setParam(ParamName::SV_RSA_PADDING, padding);
1513 // try certificate first - looking for a public key.
1514 // in case of PKCS, pub key from certificate will be found first
1515 // rather than private key from the same PKCS.
1516 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
1517 if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1518 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
1521 if (retCode == CKM_API_SUCCESS) {
1522 retCode = m_decider.getStore(row).getKey(row)->verify(params, message, signature);
1524 } catch (const Exc::Exception &e) {
1525 retCode = e.error();
1526 } catch (const KeyProvider::Exception::Base &e) {
1527 LogError("KeyProvider failed with error: " << e.GetMessage());
1528 retCode = CKM_API_ERROR_SERVER_ERROR;
1529 } catch (const DB::Crypto::Exception::Base &e) {
1530 LogError("DB::Crypto failed with message: " << e.GetMessage());
1531 retCode = CKM_API_ERROR_DB_ERROR;
1532 } catch (const CKM::Exception &e) {
1533 LogError("Unknown CKM::Exception: " << e.GetMessage());
1534 retCode = CKM_API_ERROR_SERVER_ERROR;
1537 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1540 return response.Pop();
1543 int CKMLogic::setPermissionHelper(
1544 const Credentials &cred, // who's the client
1546 const Label &label, // who's the owner
1547 const Label &accessorLabel, // who will get the access
1548 const PermissionMask permissionMask)
1550 auto &handler = selectDatabase(cred, label);
1552 // we don't know the client
1553 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1554 return CKM_API_ERROR_INPUT_PARAM;
1556 // use client label if not explicitly provided
1557 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1559 // verify name and label are correct
1560 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1561 return CKM_API_ERROR_INPUT_PARAM;
1563 // currently we don't support modification of owner's permissions to his own rows
1564 if (ownerLabel==accessorLabel)
1565 return CKM_API_ERROR_INPUT_PARAM;
1567 // system database does not support write/remove permissions
1568 if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
1569 (permissionMask & Permission::REMOVE))
1570 return CKM_API_ERROR_INPUT_PARAM;
1572 // can the client modify permissions to owner's row?
1573 int retCode = m_accessControl.canModify(cred, ownerLabel);
1574 if(retCode != CKM_API_SUCCESS)
1577 DB::Crypto::Transaction transaction(&handler.database);
1579 if( !handler.database.isNameLabelPresent(name, ownerLabel) )
1580 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1582 // removing non-existing permissions: fail
1583 if(permissionMask == Permission::NONE)
1585 if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1586 return CKM_API_ERROR_INPUT_PARAM;
1589 // set permissions to the row owned by ownerLabel for accessorLabel
1590 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1591 transaction.commit();
1593 return CKM_API_SUCCESS;
1596 RawBuffer CKMLogic::setPermission(
1597 const Credentials &cred,
1602 const Label &accessorLabel,
1603 const PermissionMask permissionMask)
1607 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1608 } catch (const Exc::Exception &e) {
1609 retCode = e.error();
1610 } Catch (CKM::Exception) {
1611 LogError("Error in set row!");
1612 retCode = CKM_API_ERROR_DB_ERROR;
1615 return MessageBuffer::Serialize(command, msgID, retCode).Pop();