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 Exc::Exception &e) {
167 } catch (const CKM::Exception &e) {
168 LogError("CKM::Exception: " << e.GetMessage());
169 retCode = CKM_API_ERROR_SERVER_ERROR;
172 if (CKM_API_SUCCESS != retCode)
173 m_userDataMap.erase(user);
178 int CKMLogic::unlockSystemDB()
180 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
183 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
185 // if user trying to access system service - check:
186 // * if user database is unlocked [mandatory]
187 // * if not - proceed with regular user database
188 // * if explicit system database label given -> switch to system DB
189 if ( !m_accessControl.isSystemService(cred) )
191 if (0 == m_userDataMap.count(cred.clientUid))
192 ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked");
194 if (0 != incoming_label.compare(OWNER_ID_SYSTEM))
195 return m_userDataMap[cred.clientUid];
198 // system database selected, modify the label
199 if (CKM_API_SUCCESS != unlockSystemDB() )
200 ThrowErr(Exc::DatabaseLocked, "can not unlock system database");
201 return m_userDataMap[SYSTEM_DB_UID];
204 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
206 int retCode = CKM_API_SUCCESS;
208 if( !m_accessControl.isSystemService(user) )
210 retCode = unlockDatabase(user, password);
214 // do not allow lock/unlock operations for system users
215 retCode = CKM_API_ERROR_INPUT_PARAM;
218 return MessageBuffer::Serialize(retCode).Pop();
221 RawBuffer CKMLogic::updateCCMode() {
222 m_accessControl.updateCCMode();
223 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
226 RawBuffer CKMLogic::lockUserKey(uid_t user)
228 int retCode = CKM_API_SUCCESS;
229 if( !m_accessControl.isSystemService(user) )
231 m_userDataMap.erase(user);
235 // do not allow lock/unlock operations for system users
236 retCode = CKM_API_ERROR_INPUT_PARAM;
239 return MessageBuffer::Serialize(retCode).Pop();
243 RawBuffer CKMLogic::removeUserData(uid_t user) {
244 int retCode = CKM_API_SUCCESS;
246 if (m_accessControl.isSystemService(user))
247 user = SYSTEM_DB_UID;
249 m_userDataMap.erase(user);
254 return MessageBuffer::Serialize(retCode).Pop();
257 int CKMLogic::changeUserPasswordHelper(uid_t user,
258 const Password &oldPassword,
259 const Password &newPassword)
261 // do not allow to change system database password
262 if( m_accessControl.isSystemService(user) )
263 return CKM_API_ERROR_INPUT_PARAM;
265 loadDKEKFile(user, oldPassword);
266 saveDKEKFile(user, newPassword);
268 return CKM_API_SUCCESS;
271 RawBuffer CKMLogic::changeUserPassword(
273 const Password &oldPassword,
274 const Password &newPassword)
276 int retCode = CKM_API_SUCCESS;
279 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
280 } catch (const Exc::Exception &e) {
282 } catch (const CKM::Exception &e) {
283 LogError("CKM::Exception: " << e.GetMessage());
284 retCode = CKM_API_ERROR_SERVER_ERROR;
287 return MessageBuffer::Serialize(retCode).Pop();
290 int CKMLogic::resetUserPasswordHelper(
292 const Password &newPassword)
294 // do not allow to reset system database password
295 if( m_accessControl.isSystemService(user) )
296 return CKM_API_ERROR_INPUT_PARAM;
298 int retCode = CKM_API_SUCCESS;
299 if (0 == m_userDataMap.count(user))
301 // Check if key exists. If exists we must return error
303 auto wrappedDKEKMain = fs.getDKEK();
304 if (!wrappedDKEKMain.empty())
305 retCode = CKM_API_ERROR_BAD_REQUEST;
307 saveDKEKFile(user, newPassword);
313 RawBuffer CKMLogic::resetUserPassword(
315 const Password &newPassword)
317 int retCode = CKM_API_SUCCESS;
319 retCode = resetUserPasswordHelper(user, newPassword);
320 } catch (const Exc::Exception &e) {
322 } catch (const CKM::Exception &e) {
323 LogError("CKM::Exception: " << e.GetMessage());
324 retCode = CKM_API_ERROR_SERVER_ERROR;
327 return MessageBuffer::Serialize(retCode).Pop();
330 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
331 int retCode = CKM_API_SUCCESS;
335 if (smackLabel.empty()) {
336 retCode = CKM_API_ERROR_INPUT_PARAM;
338 UidVector uids = FileSystem::getUIDsFromDBFile();
339 for (auto userId : uids) {
340 if (0 == m_userDataMap.count(userId)) {
341 FileSystem fs(userId);
342 fs.addRemovedApp(smackLabel);
344 auto &handle = m_userDataMap[userId];
345 handle.crypto.removeKey(smackLabel);
346 handle.database.deleteKey(smackLabel);
351 } catch (const DB::Crypto::Exception::InternalError &e) {
352 LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
353 retCode = CKM_API_ERROR_DB_ERROR;
354 } catch (const DB::Crypto::Exception::TransactionError &e) {
355 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
356 retCode = CKM_API_ERROR_DB_ERROR;
357 } catch (const Exc::Exception &e) {
359 } catch (const CKM::Exception &e) {
360 LogError("CKM::Exception: " << e.GetMessage());
361 retCode = CKM_API_ERROR_SERVER_ERROR;
364 return MessageBuffer::Serialize(retCode).Pop();
367 int CKMLogic::checkSaveConditions(
368 const Credentials &cred,
371 const Label &ownerLabel)
373 // verify name and label are correct
374 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
375 LogDebug("Invalid parameter passed to key-manager");
376 return CKM_API_ERROR_INPUT_PARAM;
379 // check if allowed to save using ownerLabel
380 int access_ec = m_accessControl.canSave(cred, ownerLabel);
381 if( access_ec != CKM_API_SUCCESS)
383 LogDebug("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
387 // check if not a duplicate
388 if( handler.database.isNameLabelPresent(name, ownerLabel))
389 return CKM_API_ERROR_DB_ALIAS_EXISTS;
391 // encryption section
392 if (!handler.crypto.haveKey(ownerLabel))
395 auto key_optional = handler.database.getKey(ownerLabel);
397 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
398 got_key = handler.keyProvider.generateDEK(ownerLabel);
399 handler.database.saveKey(ownerLabel, got_key);
401 LogDebug("Key from DB");
402 got_key = *key_optional;
405 got_key = handler.keyProvider.getPureDEK(got_key);
406 handler.crypto.pushKey(ownerLabel, got_key);
409 return CKM_API_SUCCESS;
412 DB::Row CKMLogic::createEncryptedRow(
417 const RawBuffer &data,
418 const Policy &policy) const
420 Crypto::GStore& store = m_decider.getStore(dataType, policy.extractable);
421 Token token = store.import(dataType, data);
423 DB::Row row(std::move(token), name, label, static_cast<int>(policy.extractable));
425 // do not encrypt data with password during cc_mode on
426 if(m_accessControl.isCCMode()) {
427 crypto.encryptRow("", row);
429 crypto.encryptRow(policy.password, row);
434 int CKMLogic::verifyBinaryData(DataType dataType, RawBuffer &input_data) const
437 return toBinaryData(dataType, input_data, dummy);
440 int CKMLogic::toBinaryData(DataType dataType,
441 const RawBuffer &input_data,
442 RawBuffer &output_data) const
444 // verify the data integrity
445 if (dataType.isKey())
448 if(dataType.isSKey())
449 output_key = CKM::Key::createAES(input_data);
451 output_key = CKM::Key::create(input_data);
452 if(output_key.get() == NULL)
454 LogDebug("provided binary data is not valid key data");
455 return CKM_API_ERROR_INPUT_PARAM;
457 output_data = output_key->getDER();
459 else if (dataType.isCertificate() || dataType.isChainCert())
461 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
462 if(cert.get() == NULL)
464 LogDebug("provided binary data is not valid certificate data");
465 return CKM_API_ERROR_INPUT_PARAM;
467 output_data = cert->getDER();
470 output_data = input_data;
471 // TODO: add here BINARY_DATA verification, i.e: max size etc.
472 return CKM_API_SUCCESS;
475 int CKMLogic::verifyAndSaveDataHelper(
476 const Credentials &cred,
479 const RawBuffer &data,
481 const PolicySerializable &policy)
483 int retCode = CKM_API_ERROR_UNKNOWN;
486 // check if data is correct
487 RawBuffer binaryData;
488 retCode = toBinaryData(dataType, data, binaryData);
489 if(retCode == CKM_API_SUCCESS)
491 retCode = saveDataHelper(cred, name, label, dataType, binaryData, policy);
493 } catch (const DB::Crypto::Exception::InternalError &e) {
494 LogError("DB::Crypto failed with message: " << e.GetMessage());
495 retCode = CKM_API_ERROR_DB_ERROR;
496 } catch (const DB::Crypto::Exception::TransactionError &e) {
497 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
498 retCode = CKM_API_ERROR_DB_ERROR;
499 } catch (const Exc::Exception &e) {
501 } catch (const CKM::Exception &e) {
502 LogError("CKM::Exception: " << e.GetMessage());
503 retCode = CKM_API_ERROR_SERVER_ERROR;
508 int CKMLogic::getKeyForService(
509 const Credentials &cred,
512 const Password &pass,
513 Crypto::GKeyShPtr &key)
517 // Key is for internal service use. It won't be exported to the client
518 int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, row);
519 if (retCode == CKM_API_SUCCESS)
520 key = m_decider.getStore(row).getKey(row);
522 } catch (const DB::Crypto::Exception::Base &e) {
523 LogError("DB::Crypto failed with message: " << e.GetMessage());
524 return CKM_API_ERROR_DB_ERROR;
525 } catch (const Exc::Exception &e) {
527 } catch (const CKM::Exception &e) {
528 LogError("CKM::Exception: " << e.GetMessage());
529 return CKM_API_ERROR_SERVER_ERROR;
533 RawBuffer CKMLogic::saveData(
534 const Credentials &cred,
538 const RawBuffer &data,
540 const PolicySerializable &policy)
542 int retCode = verifyAndSaveDataHelper(cred, name, label, data, dataType, policy);
543 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
546 static_cast<int>(dataType));
547 return response.Pop();
550 int CKMLogic::extractPKCS12Data(
553 const Label &ownerLabel,
554 const PKCS12Serializable &pkcs,
555 const PolicySerializable &keyPolicy,
556 const PolicySerializable &certPolicy,
557 DB::RowVector &output) const
559 // private key is mandatory
561 return CKM_API_ERROR_INVALID_FORMAT;
562 Key* keyPtr = pkcs.getKey().get();
563 DataType keyType = DataType(keyPtr->getType());
564 RawBuffer keyData = keyPtr->getDER();
565 int retCode = verifyBinaryData(keyType, keyData);
566 if(retCode != CKM_API_SUCCESS)
568 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
570 // certificate is mandatory
571 if( !pkcs.getCertificate() )
572 return CKM_API_ERROR_INVALID_FORMAT;
573 RawBuffer certData = pkcs.getCertificate().get()->getDER();
574 retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
575 if(retCode != CKM_API_SUCCESS)
577 output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
580 unsigned int cert_index = 0;
581 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
583 DataType chainDataType = DataType::getChainDatatype(cert_index ++);
584 RawBuffer caCertData = ca->getDER();
585 int retCode = verifyBinaryData(chainDataType, caCertData);
586 if(retCode != CKM_API_SUCCESS)
589 output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
592 return CKM_API_SUCCESS;
595 RawBuffer CKMLogic::savePKCS12(
596 const Credentials &cred,
600 const PKCS12Serializable &pkcs,
601 const PolicySerializable &keyPolicy,
602 const PolicySerializable &certPolicy)
604 int retCode = CKM_API_ERROR_UNKNOWN;
606 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
607 } catch (const Exc::Exception &e) {
609 } catch (const DB::Crypto::Exception::InternalError &e) {
610 LogError("DB::Crypto failed with message: " << e.GetMessage());
611 retCode = CKM_API_ERROR_DB_ERROR;
612 } catch (const DB::Crypto::Exception::TransactionError &e) {
613 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
614 retCode = CKM_API_ERROR_DB_ERROR;
615 } catch (const CKM::Exception &e) {
616 LogError("CKM::Exception: " << e.GetMessage());
617 retCode = CKM_API_ERROR_SERVER_ERROR;
620 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
623 return response.Pop();
627 int CKMLogic::removeDataHelper(
628 const Credentials &cred,
632 auto &handler = selectDatabase(cred, label);
634 // use client label if not explicitly provided
635 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
636 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
637 LogDebug("Invalid label or name format");
638 return CKM_API_ERROR_INPUT_PARAM;
641 DB::Crypto::Transaction transaction(&handler.database);
643 // read and check permissions
644 PermissionMaskOptional permissionRowOpt =
645 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
646 int retCode = m_accessControl.canDelete(cred,
647 PermissionForLabel(cred.smackLabel, permissionRowOpt));
648 if(retCode != CKM_API_SUCCESS)
650 LogWarning("access control check result: " << retCode);
654 // get all matching rows
656 handler.database.getRows(name, ownerLabel, DataType::DB_FIRST, DataType::DB_LAST, rows);
658 LogDebug("No row for given name and label");
659 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
662 // load app key if needed
663 retCode = loadAppKey(handler, rows.front().ownerLabel);
664 if(CKM_API_SUCCESS != retCode)
667 // destroy it in store
668 for(auto& r : rows) {
670 * TODO: If row is encrypted with user password we won't be able to decrypt it (tz id).
671 * Encryption/decryption with user password and with app key should both be done inside the
672 * store (import, getKey and generateXKey).
675 handler.crypto.decryptRow(Password(), r);
676 } catch (const Exc::AuthenticationFailed&) {
677 LogDebug("Authentication failed when removing data. Ignored.");
679 m_decider.getStore(r.dataType, r.exportable).destroy(r);
683 handler.database.deleteRow(name, ownerLabel);
684 transaction.commit();
686 return CKM_API_SUCCESS;
689 RawBuffer CKMLogic::removeData(
690 const Credentials &cred,
695 int retCode = CKM_API_ERROR_UNKNOWN;
699 retCode = removeDataHelper(cred, name, label);
701 catch (const Exc::Exception &e)
705 catch (const CKM::Exception &)
707 LogError("Error in deleting row!");
708 retCode = CKM_API_ERROR_DB_ERROR;
711 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
714 return response.Pop();
717 int CKMLogic::readSingleRow(const Name &name,
718 const Label &ownerLabel,
720 DB::Crypto & database,
723 DB::Crypto::RowOptional row_optional;
724 if (dataType.isKey())
726 // read all key types
727 row_optional = database.getRow(name,
729 DataType::DB_KEY_FIRST,
730 DataType::DB_KEY_LAST);
732 // read anything else
733 row_optional = database.getRow(name,
739 LogDebug("No row for given name, label and type");
740 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
745 return CKM_API_SUCCESS;
749 int CKMLogic::readMultiRow(const Name &name,
750 const Label &ownerLabel,
752 DB::Crypto & database,
753 DB::RowVector &output)
755 if (dataType.isKey())
757 // read all key types
758 database.getRows(name,
760 DataType::DB_KEY_FIRST,
761 DataType::DB_KEY_LAST,
764 else if (dataType.isChainCert())
766 // read all key types
767 database.getRows(name,
769 DataType::DB_CHAIN_FIRST,
770 DataType::DB_CHAIN_LAST,
775 // read anything else
776 database.getRows(name,
783 LogDebug("No row for given name, label and type");
784 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
787 return CKM_API_SUCCESS;
790 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
792 const Label &ownerLabel,
793 const Label &accessorLabel,
796 DB::Crypto & database)
798 PermissionMaskOptional permissionRowOpt =
799 database.getPermissionRow(name, ownerLabel, accessorLabel);
802 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
803 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
806 int CKMLogic::readDataHelper(
808 const Credentials &cred,
812 const Password &password,
815 auto &handler = selectDatabase(cred, label);
817 // use client label if not explicitly provided
818 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
820 if (!isNameValid(name) || !isLabelValid(ownerLabel))
821 return CKM_API_ERROR_INPUT_PARAM;
824 DB::Crypto::Transaction transaction(&handler.database);
825 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
826 if(CKM_API_SUCCESS != retCode)
829 // all read rows belong to the same owner
830 DB::Row & firstRow = rows.at(0);
832 // check access rights
833 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
834 if(CKM_API_SUCCESS != retCode)
837 // load app key if needed
838 retCode = loadAppKey(handler, firstRow.ownerLabel);
839 if(CKM_API_SUCCESS != retCode)
843 for(auto &row : rows)
844 handler.crypto.decryptRow(password, row);
846 return CKM_API_SUCCESS;
849 int CKMLogic::readDataHelper(
851 const Credentials &cred,
855 const Password &password,
858 auto &handler = selectDatabase(cred, label);
860 // use client label if not explicitly provided
861 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
863 if (!isNameValid(name) || !isLabelValid(ownerLabel))
864 return CKM_API_ERROR_INPUT_PARAM;
867 DB::Crypto::Transaction transaction(&handler.database);
868 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
869 if(CKM_API_SUCCESS != retCode)
872 // check access rights
873 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
874 if(CKM_API_SUCCESS != retCode)
877 // load app key if needed
878 retCode = loadAppKey(handler, row.ownerLabel);
879 if(CKM_API_SUCCESS != retCode)
883 handler.crypto.decryptRow(password, row);
885 return CKM_API_SUCCESS;
888 RawBuffer CKMLogic::getData(
889 const Credentials &cred,
894 const Password &password)
896 int retCode = CKM_API_SUCCESS;
900 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
901 } catch (const DB::Crypto::Exception::Base &e) {
902 LogError("DB::Crypto failed with message: " << e.GetMessage());
903 retCode = CKM_API_ERROR_DB_ERROR;
904 } catch (const Exc::Exception &e) {
906 } catch (const CKM::Exception &e) {
907 LogError("CKM::Exception: " << e.GetMessage());
908 retCode = CKM_API_ERROR_SERVER_ERROR;
911 if (CKM_API_SUCCESS != retCode) {
913 row.dataType = dataType;
916 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
919 static_cast<int>(row.dataType),
921 return response.Pop();
924 int CKMLogic::getPKCS12Helper(
925 const Credentials &cred,
928 const Password &keyPassword,
929 const Password &certPassword,
931 CertificateShPtr & cert,
932 CertificateShPtrVector & caChain)
936 // read private key (mandatory)
938 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
939 if(retCode != CKM_API_SUCCESS)
941 privKey = CKM::Key::create(privKeyRow.data);
943 // read certificate (mandatory)
945 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
946 if(retCode != CKM_API_SUCCESS)
948 cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
950 // read CA cert chain (optional)
951 DB::RowVector rawCaChain;
952 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
953 if(retCode != CKM_API_SUCCESS &&
954 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
956 for(auto &rawCaCert : rawCaChain)
957 caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
959 // if anything found, return it
960 if(privKey || cert || caChain.size()>0)
961 retCode = CKM_API_SUCCESS;
966 RawBuffer CKMLogic::getPKCS12(
967 const Credentials &cred,
971 const Password &keyPassword,
972 const Password &certPassword)
974 int retCode = CKM_API_ERROR_UNKNOWN;
976 PKCS12Serializable output;
979 CertificateShPtr cert;
980 CertificateShPtrVector caChain;
981 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
984 if(retCode == CKM_API_SUCCESS)
985 output = PKCS12Serializable(privKey, cert, caChain);
986 } catch (const DB::Crypto::Exception::Base &e) {
987 LogError("DB::Crypto failed with message: " << e.GetMessage());
988 retCode = CKM_API_ERROR_DB_ERROR;
989 } catch (const Exc::Exception &e) {
991 } catch (const CKM::Exception &e) {
992 LogError("CKM::Exception: " << e.GetMessage());
993 retCode = CKM_API_ERROR_SERVER_ERROR;
996 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
1000 return response.Pop();
1003 int CKMLogic::getDataListHelper(const Credentials &cred,
1004 const DataType dataType,
1005 LabelNameVector &labelNameVector)
1007 int retCode = CKM_API_ERROR_DB_LOCKED;
1008 if (0 < m_userDataMap.count(cred.clientUid))
1010 auto &database = m_userDataMap[cred.clientUid].database;
1013 LabelNameVector tmpVector;
1014 if (dataType.isKey()) {
1015 // list all key types
1016 database.listNames(cred.smackLabel,
1018 DataType::DB_KEY_FIRST,
1019 DataType::DB_KEY_LAST);
1021 // list anything else
1022 database.listNames(cred.smackLabel,
1026 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
1027 retCode = CKM_API_SUCCESS;
1029 Catch (CKM::Exception) {
1030 LogError("Failed to get names");
1031 retCode = CKM_API_ERROR_DB_ERROR;
1037 RawBuffer CKMLogic::getDataList(
1038 const Credentials &cred,
1042 LabelNameVector systemVector;
1043 LabelNameVector userVector;
1044 LabelNameVector labelNameVector;
1046 int retCode = unlockSystemDB();
1047 if (CKM_API_SUCCESS == retCode)
1050 if (m_accessControl.isSystemService(cred))
1053 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1060 // user - lookup system, then client DB
1061 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1067 if(retCode == CKM_API_SUCCESS)
1069 retCode = getDataListHelper(cred,
1076 if(retCode == CKM_API_SUCCESS)
1078 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1079 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1081 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1084 static_cast<int>(dataType),
1086 return response.Pop();
1089 int CKMLogic::saveDataHelper(
1090 const Credentials &cred,
1094 const RawBuffer &data,
1095 const PolicySerializable &policy)
1097 auto &handler = selectDatabase(cred, label);
1099 // use client label if not explicitly provided
1100 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1101 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
1102 return CKM_API_ERROR_INPUT_PARAM;
1104 // check if save is possible
1105 DB::Crypto::Transaction transaction(&handler.database);
1106 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1107 if(retCode != CKM_API_SUCCESS)
1111 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
1112 handler.database.saveRow(encryptedRow);
1114 transaction.commit();
1115 return CKM_API_SUCCESS;
1118 int CKMLogic::saveDataHelper(
1119 const Credentials &cred,
1122 const PKCS12Serializable &pkcs,
1123 const PolicySerializable &keyPolicy,
1124 const PolicySerializable &certPolicy)
1126 auto &handler = selectDatabase(cred, label);
1128 // use client label if not explicitly provided
1129 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1130 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
1131 return CKM_API_ERROR_INPUT_PARAM;
1133 // check if save is possible
1134 DB::Crypto::Transaction transaction(&handler.database);
1135 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1136 if(retCode != CKM_API_SUCCESS)
1139 // extract and encrypt the data
1140 DB::RowVector encryptedRows;
1141 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1142 if(retCode != CKM_API_SUCCESS)
1146 handler.database.saveRows(name, ownerLabel, encryptedRows);
1147 transaction.commit();
1149 return CKM_API_SUCCESS;
1153 int CKMLogic::createKeyAESHelper(
1154 const Credentials &cred,
1158 const PolicySerializable &policy)
1160 CryptoAlgorithm keyGenAlgorithm;
1161 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
1162 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
1163 Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm);
1165 return saveDataHelper(cred,
1174 int CKMLogic::createKeyPairHelper(
1175 const Credentials &cred,
1176 const CryptoAlgorithmSerializable & keyGenParams,
1177 const Name &namePrivate,
1178 const Label &labelPrivate,
1179 const Name &namePublic,
1180 const Label &labelPublic,
1181 const PolicySerializable &policyPrivate,
1182 const PolicySerializable &policyPublic)
1184 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1185 auto &handlerPub = selectDatabase(cred, labelPublic);
1187 AlgoType keyType = AlgoType::RSA_GEN;
1188 if(!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType))
1189 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found.");
1190 DataType dt(keyType);
1192 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
1194 bool exportable = policyPrivate.extractable || policyPublic.extractable;
1195 TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams);
1197 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1198 // in case the same database is used for private and public - the second
1199 // transaction will not be executed
1200 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1202 int retCode = saveDataHelper(cred,
1205 keys.first.dataType,
1208 if (CKM_API_SUCCESS != retCode)
1211 retCode = saveDataHelper(cred,
1214 keys.second.dataType,
1217 if (CKM_API_SUCCESS != retCode)
1220 transactionPub.commit();
1221 transactionPriv.commit();
1222 return CKM_API_SUCCESS;
1225 RawBuffer CKMLogic::createKeyPair(
1226 const Credentials &cred,
1228 const CryptoAlgorithmSerializable & keyGenParams,
1229 const Name &namePrivate,
1230 const Label &labelPrivate,
1231 const Name &namePublic,
1232 const Label &labelPublic,
1233 const PolicySerializable &policyPrivate,
1234 const PolicySerializable &policyPublic)
1236 int retCode = CKM_API_SUCCESS;
1239 retCode = createKeyPairHelper(
1248 } catch(const Exc::Exception &e) {
1249 retCode = e.error();
1250 } catch (DB::Crypto::Exception::TransactionError &e) {
1251 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1252 retCode = CKM_API_ERROR_DB_ERROR;
1253 } catch (DB::Crypto::Exception::InternalError &e) {
1254 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1255 retCode = CKM_API_ERROR_DB_ERROR;
1256 } catch (const CKM::Exception &e) {
1257 LogError("CKM::Exception: " << e.GetMessage());
1258 retCode = CKM_API_ERROR_SERVER_ERROR;
1261 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR),
1262 commandId, retCode).Pop();
1265 RawBuffer CKMLogic::createKeyAES(
1266 const Credentials &cred,
1271 const PolicySerializable &policy)
1273 int retCode = CKM_API_SUCCESS;
1276 retCode = createKeyAESHelper(cred, size, name, label, policy);
1277 } catch (const Exc::Exception &e) {
1278 retCode = e.error();
1279 } catch (std::invalid_argument &e) {
1280 LogDebug("invalid argument error: " << e.what());
1281 retCode = CKM_API_ERROR_INPUT_PARAM;
1282 } catch (DB::Crypto::Exception::TransactionError &e) {
1283 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1284 retCode = CKM_API_ERROR_DB_ERROR;
1285 } catch (DB::Crypto::Exception::InternalError &e) {
1286 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1287 retCode = CKM_API_ERROR_DB_ERROR;
1288 } catch (const CKM::Exception &e) {
1289 LogError("CKM::Exception: " << e.GetMessage());
1290 retCode = CKM_API_ERROR_SERVER_ERROR;
1293 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES),
1294 commandId, retCode).Pop();
1297 int CKMLogic::readCertificateHelper(
1298 const Credentials &cred,
1299 const LabelNameVector &labelNameVector,
1300 CertificateImplVector &certVector)
1303 for (auto &i: labelNameVector) {
1304 int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1305 if (ec != CKM_API_SUCCESS)
1307 certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1309 // try to read chain certificates (if present)
1310 DB::RowVector rawCaChain;
1311 ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1312 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1314 for(auto &rawCaCert : rawCaChain)
1315 certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1317 return CKM_API_SUCCESS;
1320 int CKMLogic::getCertificateChainHelper(
1321 const CertificateImpl &cert,
1322 const RawBufferVector &untrustedCertificates,
1323 const RawBufferVector &trustedCertificates,
1324 bool useTrustedSystemCertificates,
1325 RawBufferVector &chainRawVector)
1327 CertificateImplVector untrustedCertVector;
1328 CertificateImplVector trustedCertVector;
1329 CertificateImplVector chainVector;
1332 return CKM_API_ERROR_INPUT_PARAM;
1334 for (auto &e: untrustedCertificates) {
1335 CertificateImpl c(e, DataFormat::FORM_DER);
1337 return CKM_API_ERROR_INPUT_PARAM;
1338 untrustedCertVector.push_back(std::move(c));
1340 for (auto &e: trustedCertificates) {
1341 CertificateImpl c(e, DataFormat::FORM_DER);
1343 return CKM_API_ERROR_INPUT_PARAM;
1344 trustedCertVector.push_back(std::move(c));
1347 CertificateStore store;
1348 int retCode = store.verifyCertificate(cert,
1349 untrustedCertVector,
1351 useTrustedSystemCertificates,
1352 m_accessControl.isCCMode(),
1354 if (retCode != CKM_API_SUCCESS)
1357 for (auto &e : chainVector)
1358 chainRawVector.push_back(e.getDER());
1359 return CKM_API_SUCCESS;
1362 int CKMLogic::getCertificateChainHelper(
1363 const Credentials &cred,
1364 const CertificateImpl &cert,
1365 const LabelNameVector &untrusted,
1366 const LabelNameVector &trusted,
1367 bool useTrustedSystemCertificates,
1368 RawBufferVector &chainRawVector)
1370 CertificateImplVector untrustedCertVector;
1371 CertificateImplVector trustedCertVector;
1372 CertificateImplVector chainVector;
1376 return CKM_API_ERROR_INPUT_PARAM;
1378 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1379 if (retCode != CKM_API_SUCCESS)
1381 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1382 if (retCode != CKM_API_SUCCESS)
1385 CertificateStore store;
1386 retCode = store.verifyCertificate(cert,
1387 untrustedCertVector,
1389 useTrustedSystemCertificates,
1390 m_accessControl.isCCMode(),
1392 if (retCode != CKM_API_SUCCESS)
1395 for (auto &i: chainVector)
1396 chainRawVector.push_back(i.getDER());
1398 return CKM_API_SUCCESS;
1401 RawBuffer CKMLogic::getCertificateChain(
1402 const Credentials & /*cred*/,
1404 const RawBuffer &certificate,
1405 const RawBufferVector &untrustedCertificates,
1406 const RawBufferVector &trustedCertificates,
1407 bool useTrustedSystemCertificates)
1409 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1410 RawBufferVector chainRawVector;
1411 int retCode = CKM_API_ERROR_UNKNOWN;
1413 retCode = getCertificateChainHelper(cert,
1414 untrustedCertificates,
1415 trustedCertificates,
1416 useTrustedSystemCertificates,
1418 } catch (const Exc::Exception &e) {
1419 retCode = e.error();
1420 } catch (const DB::Crypto::Exception::Base &e) {
1421 LogError("DB::Crypto failed with message: " << e.GetMessage());
1422 retCode = CKM_API_ERROR_DB_ERROR;
1423 } catch (const std::exception& e) {
1424 LogError("STD exception " << e.what());
1425 retCode = CKM_API_ERROR_SERVER_ERROR;
1427 LogError("Unknown error.");
1430 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1434 return response.Pop();
1437 RawBuffer CKMLogic::getCertificateChain(
1438 const Credentials &cred,
1440 const RawBuffer &certificate,
1441 const LabelNameVector &untrustedCertificates,
1442 const LabelNameVector &trustedCertificates,
1443 bool useTrustedSystemCertificates)
1445 int retCode = CKM_API_ERROR_UNKNOWN;
1446 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1447 RawBufferVector chainRawVector;
1449 retCode = getCertificateChainHelper(cred,
1451 untrustedCertificates,
1452 trustedCertificates,
1453 useTrustedSystemCertificates,
1455 } catch (const DB::Crypto::Exception::Base &e) {
1456 LogError("DB::Crypto failed with message: " << e.GetMessage());
1457 retCode = CKM_API_ERROR_DB_ERROR;
1458 } catch (const Exc::Exception &e) {
1459 retCode = e.error();
1460 } catch (const std::exception& e) {
1461 LogError("STD exception " << e.what());
1462 retCode = CKM_API_ERROR_SERVER_ERROR;
1464 LogError("Unknown error.");
1467 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1471 return response.Pop();
1474 RawBuffer CKMLogic::createSignature(
1475 const Credentials &cred,
1477 const Name &privateKeyName,
1478 const Label & ownerLabel,
1479 const Password &password, // password for private_key
1480 const RawBuffer &message,
1481 const HashAlgorithm hash,
1482 const RSAPaddingAlgorithm padding)
1485 RawBuffer signature;
1486 CryptoAlgorithm cryptoAlg;
1487 cryptoAlg.setParam(ParamName::SV_HASH_ALGO, hash);
1488 cryptoAlg.setParam(ParamName::SV_RSA_PADDING, padding);
1490 int retCode = CKM_API_SUCCESS;
1493 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1494 if(retCode == CKM_API_SUCCESS) {
1495 signature = m_decider.getStore(row).getKey(row)->sign(cryptoAlg, message);
1497 } catch (const DB::Crypto::Exception::Base &e) {
1498 LogError("DB::Crypto failed with message: " << e.GetMessage());
1499 retCode = CKM_API_ERROR_DB_ERROR;
1500 } catch (const Exc::Exception &e) {
1501 retCode = e.error();
1502 } catch (const CKM::Exception &e) {
1503 LogError("Unknown CKM::Exception: " << e.GetMessage());
1504 retCode = CKM_API_ERROR_SERVER_ERROR;
1507 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1511 return response.Pop();
1514 RawBuffer CKMLogic::verifySignature(
1515 const Credentials &cred,
1517 const Name &publicKeyOrCertName,
1518 const Label & ownerLabel,
1519 const Password &password, // password for public_key (optional)
1520 const RawBuffer &message,
1521 const RawBuffer &signature,
1522 const HashAlgorithm hash,
1523 const RSAPaddingAlgorithm padding)
1525 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1530 CryptoAlgorithm params;
1531 params.setParam(ParamName::SV_HASH_ALGO, hash);
1532 params.setParam(ParamName::SV_RSA_PADDING, padding);
1534 // try certificate first - looking for a public key.
1535 // in case of PKCS, pub key from certificate will be found first
1536 // rather than private key from the same PKCS.
1537 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
1538 if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1539 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
1542 if (retCode == CKM_API_SUCCESS) {
1543 retCode = m_decider.getStore(row).getKey(row)->verify(params, message, signature);
1545 } catch (const Exc::Exception &e) {
1546 retCode = e.error();
1547 } catch (const DB::Crypto::Exception::Base &e) {
1548 LogError("DB::Crypto failed with message: " << e.GetMessage());
1549 retCode = CKM_API_ERROR_DB_ERROR;
1550 } catch (const CKM::Exception &e) {
1551 LogError("Unknown CKM::Exception: " << e.GetMessage());
1552 retCode = CKM_API_ERROR_SERVER_ERROR;
1555 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1558 return response.Pop();
1561 int CKMLogic::setPermissionHelper(
1562 const Credentials &cred, // who's the client
1564 const Label &label, // who's the owner
1565 const Label &accessorLabel, // who will get the access
1566 const PermissionMask permissionMask)
1568 auto &handler = selectDatabase(cred, label);
1570 // we don't know the client
1571 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1572 return CKM_API_ERROR_INPUT_PARAM;
1574 // use client label if not explicitly provided
1575 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1577 // verify name and label are correct
1578 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1579 return CKM_API_ERROR_INPUT_PARAM;
1581 // currently we don't support modification of owner's permissions to his own rows
1582 if (ownerLabel==accessorLabel)
1583 return CKM_API_ERROR_INPUT_PARAM;
1585 // system database does not support write/remove permissions
1586 if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) &&
1587 (permissionMask & Permission::REMOVE))
1588 return CKM_API_ERROR_INPUT_PARAM;
1590 // can the client modify permissions to owner's row?
1591 int retCode = m_accessControl.canModify(cred, ownerLabel);
1592 if(retCode != CKM_API_SUCCESS)
1595 DB::Crypto::Transaction transaction(&handler.database);
1597 if( !handler.database.isNameLabelPresent(name, ownerLabel) )
1598 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1600 // removing non-existing permissions: fail
1601 if(permissionMask == Permission::NONE)
1603 if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1604 return CKM_API_ERROR_INPUT_PARAM;
1607 // set permissions to the row owned by ownerLabel for accessorLabel
1608 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1609 transaction.commit();
1611 return CKM_API_SUCCESS;
1614 RawBuffer CKMLogic::setPermission(
1615 const Credentials &cred,
1620 const Label &accessorLabel,
1621 const PermissionMask permissionMask)
1625 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1626 } catch (const Exc::Exception &e) {
1627 retCode = e.error();
1628 } Catch (CKM::Exception) {
1629 LogError("Error in set row!");
1630 retCode = CKM_API_ERROR_DB_ERROR;
1633 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
1636 int CKMLogic::loadAppKey(UserData& handle, const Label& appLabel)
1638 if (!handle.crypto.haveKey(appLabel)) {
1640 auto key_optional = handle.database.getKey(appLabel);
1642 LogError("No key for given label in database");
1643 return CKM_API_ERROR_DB_ERROR;
1645 key = *key_optional;
1646 key = handle.keyProvider.getPureDEK(key);
1647 handle.crypto.pushKey(appLabel, key);
1649 return CKM_API_SUCCESS;