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>
34 #include <sw-backend/store.h>
35 #include <generic-backend/exception.h>
38 const char *const CERT_SYSTEM_DIR = CA_CERTS_DIR;
39 const char *const SYSTEM_DB_PASSWD = "cAtRugU7";
41 bool isLabelValid(const CKM::Label &label)
43 // TODO: copy code from libprivilege control (for check smack label)
44 if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
50 bool isNameValid(const CKM::Name &name)
52 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();
71 CKMLogic::~CKMLogic() {}
73 void CKMLogic::loadDKEKFile(uid_t user, const Password &password)
75 auto &handle = m_userDataMap[user];
79 auto wrappedDKEK = fs.getDKEK();
81 if (wrappedDKEK.empty()) {
82 wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
83 fs.saveDKEK(wrappedDKEK);
86 handle.keyProvider = KeyProvider(wrappedDKEK, password);
89 void CKMLogic::saveDKEKFile(uid_t user, const Password &password)
91 auto &handle = m_userDataMap[user];
94 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
97 int CKMLogic::unlockDatabase(uid_t user, const Password &password)
99 if (0 < m_userDataMap.count(user) &&
100 m_userDataMap[user].keyProvider.isInitialized())
101 return CKM_API_SUCCESS;
103 int retCode = CKM_API_SUCCESS;
106 auto &handle = m_userDataMap[user];
109 loadDKEKFile(user, password);
111 auto wrappedDatabaseDEK = fs.getDBDEK();
113 if (wrappedDatabaseDEK.empty()) {
114 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
115 fs.saveDBDEK(wrappedDatabaseDEK);
118 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
120 handle.database = DB::Crypto(fs.getDBPath(), key);
121 handle.crypto = CryptoLogic();
123 if (!m_accessControl.isSystemService(user)) {
124 // remove data of removed apps during locked state
125 AppLabelVector removedApps = fs.clearRemovedsApps();
127 for (auto &appSmackLabel : removedApps) {
128 handle.crypto.removeKey(appSmackLabel);
129 handle.database.deleteKey(appSmackLabel);
132 } catch (const Exc::Exception &e) {
134 } catch (const CKM::Exception &e) {
135 LogError("CKM::Exception: " << e.GetMessage());
136 retCode = CKM_API_ERROR_SERVER_ERROR;
139 if (CKM_API_SUCCESS != retCode)
140 m_userDataMap.erase(user);
145 int CKMLogic::unlockSystemDB()
147 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
150 UserData &CKMLogic::selectDatabase(const Credentials &cred,
151 const Label &incoming_label)
153 // if user trying to access system service - check:
154 // * if user database is unlocked [mandatory]
155 // * if not - proceed with regular user database
156 // * if explicit system database label given -> switch to system DB
157 if (!m_accessControl.isSystemService(cred)) {
158 if (0 == m_userDataMap.count(cred.clientUid))
159 ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked");
161 if (0 != incoming_label.compare(OWNER_ID_SYSTEM))
162 return m_userDataMap[cred.clientUid];
165 // system database selected, modify the label
166 if (CKM_API_SUCCESS != unlockSystemDB())
167 ThrowErr(Exc::DatabaseLocked, "can not unlock system database");
169 return m_userDataMap[SYSTEM_DB_UID];
172 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
174 int retCode = CKM_API_SUCCESS;
176 if (!m_accessControl.isSystemService(user))
177 retCode = unlockDatabase(user, password);
178 else // do not allow lock/unlock operations for system users
179 retCode = CKM_API_ERROR_INPUT_PARAM;
181 return MessageBuffer::Serialize(retCode).Pop();
184 RawBuffer CKMLogic::updateCCMode()
186 m_accessControl.updateCCMode();
187 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
190 RawBuffer CKMLogic::lockUserKey(uid_t user)
192 int retCode = CKM_API_SUCCESS;
194 if (!m_accessControl.isSystemService(user))
195 m_userDataMap.erase(user);
196 else // do not allow lock/unlock operations for system users
197 retCode = CKM_API_ERROR_INPUT_PARAM;
199 return MessageBuffer::Serialize(retCode).Pop();
202 RawBuffer CKMLogic::removeUserData(uid_t user)
204 int retCode = CKM_API_SUCCESS;
206 if (m_accessControl.isSystemService(user))
207 user = SYSTEM_DB_UID;
209 m_userDataMap.erase(user);
214 return MessageBuffer::Serialize(retCode).Pop();
217 int CKMLogic::changeUserPasswordHelper(uid_t user,
218 const Password &oldPassword,
219 const Password &newPassword)
221 // do not allow to change system database password
222 if (m_accessControl.isSystemService(user))
223 return CKM_API_ERROR_INPUT_PARAM;
225 loadDKEKFile(user, oldPassword);
226 saveDKEKFile(user, newPassword);
228 return CKM_API_SUCCESS;
231 RawBuffer CKMLogic::changeUserPassword(
233 const Password &oldPassword,
234 const Password &newPassword)
236 int retCode = CKM_API_SUCCESS;
239 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
240 } catch (const Exc::Exception &e) {
242 } catch (const CKM::Exception &e) {
243 LogError("CKM::Exception: " << e.GetMessage());
244 retCode = CKM_API_ERROR_SERVER_ERROR;
247 return MessageBuffer::Serialize(retCode).Pop();
250 int CKMLogic::resetUserPasswordHelper(
252 const Password &newPassword)
254 // do not allow to reset system database password
255 if (m_accessControl.isSystemService(user))
256 return CKM_API_ERROR_INPUT_PARAM;
258 int retCode = CKM_API_SUCCESS;
260 if (0 == m_userDataMap.count(user)) {
261 // Check if key exists. If exists we must return error
263 auto wrappedDKEKMain = fs.getDKEK();
265 if (!wrappedDKEKMain.empty())
266 retCode = CKM_API_ERROR_BAD_REQUEST;
268 saveDKEKFile(user, newPassword);
274 RawBuffer CKMLogic::resetUserPassword(
276 const Password &newPassword)
278 int retCode = CKM_API_SUCCESS;
281 retCode = resetUserPasswordHelper(user, newPassword);
282 } catch (const Exc::Exception &e) {
284 } catch (const CKM::Exception &e) {
285 LogError("CKM::Exception: " << e.GetMessage());
286 retCode = CKM_API_ERROR_SERVER_ERROR;
289 return MessageBuffer::Serialize(retCode).Pop();
292 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel)
294 int retCode = CKM_API_SUCCESS;
297 if (smackLabel.empty()) {
298 retCode = CKM_API_ERROR_INPUT_PARAM;
300 UidVector uids = FileSystem::getUIDsFromDBFile();
302 for (auto userId : uids) {
303 if (0 == m_userDataMap.count(userId)) {
304 FileSystem fs(userId);
305 fs.addRemovedApp(smackLabel);
307 auto &handle = m_userDataMap[userId];
308 handle.crypto.removeKey(smackLabel);
309 handle.database.deleteKey(smackLabel);
313 } catch (const Exc::Exception &e) {
315 } catch (const CKM::Exception &e) {
316 LogError("CKM::Exception: " << e.GetMessage());
317 retCode = CKM_API_ERROR_SERVER_ERROR;
320 return MessageBuffer::Serialize(retCode).Pop();
323 int CKMLogic::checkSaveConditions(
324 const Credentials &cred,
327 const Label &ownerLabel)
329 // verify name and label are correct
330 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
331 LogDebug("Invalid parameter passed to key-manager");
332 return CKM_API_ERROR_INPUT_PARAM;
335 // check if allowed to save using ownerLabel
336 int access_ec = m_accessControl.canSave(cred, ownerLabel);
338 if (access_ec != CKM_API_SUCCESS) {
339 LogDebug("label " << cred.smackLabel << " can not save rows using label " <<
344 // check if not a duplicate
345 if (handler.database.isNameLabelPresent(name, ownerLabel))
346 return CKM_API_ERROR_DB_ALIAS_EXISTS;
348 // encryption section
349 if (!handler.crypto.haveKey(ownerLabel)) {
351 auto key_optional = handler.database.getKey(ownerLabel);
354 LogDebug("No Key in database found. Generating new one for label: " <<
356 got_key = handler.keyProvider.generateDEK(ownerLabel);
357 handler.database.saveKey(ownerLabel, got_key);
359 LogDebug("Key from DB");
360 got_key = *key_optional;
363 got_key = handler.keyProvider.getPureDEK(got_key);
364 handler.crypto.pushKey(ownerLabel, got_key);
367 return CKM_API_SUCCESS;
370 DB::Row CKMLogic::createEncryptedRow(
374 const Crypto::Data &data,
375 const Policy &policy) const
377 Crypto::GStore &store = m_decider.getStore(data.type, policy.extractable);
379 // do not encrypt data with password during cc_mode on
380 Token token = store.import(data,
381 m_accessControl.isCCMode() ? "" : policy.password);
382 DB::Row row(std::move(token), name, label,
383 static_cast<int>(policy.extractable));
384 crypto.encryptRow(row);
388 int CKMLogic::verifyBinaryData(Crypto::Data &input) const
391 return toBinaryData(input, dummy);
394 int CKMLogic::toBinaryData(const Crypto::Data &input,
395 Crypto::Data &output) const
397 // verify the data integrity
398 if (input.type.isKey()) {
401 if (input.type.isSKey())
402 output_key = CKM::Key::createAES(input.data);
404 output_key = CKM::Key::create(input.data);
406 if (output_key.get() == NULL) {
407 LogDebug("provided binary data is not valid key data");
408 return CKM_API_ERROR_INPUT_PARAM;
411 output = std::move(Crypto::Data(input.type, output_key->getDER()));
412 } else if (input.type.isCertificate() || input.type.isChainCert()) {
413 CertificateShPtr cert = CKM::Certificate::create(input.data,
414 DataFormat::FORM_DER);
416 if (cert.get() == NULL) {
417 LogDebug("provided binary data is not valid certificate data");
418 return CKM_API_ERROR_INPUT_PARAM;
421 output = std::move(Crypto::Data(input.type, cert->getDER()));
426 // TODO: add here BINARY_DATA verification, i.e: max size etc.
427 return CKM_API_SUCCESS;
430 int CKMLogic::verifyAndSaveDataHelper(
431 const Credentials &cred,
434 const Crypto::Data &data,
435 const PolicySerializable &policy)
437 int retCode = CKM_API_ERROR_UNKNOWN;
440 // check if data is correct
441 Crypto::Data binaryData;
442 retCode = toBinaryData(data, binaryData);
444 if (retCode != CKM_API_SUCCESS)
447 return saveDataHelper(cred, name, label, binaryData, policy);
448 } catch (const Exc::Exception &e) {
450 } catch (const CKM::Exception &e) {
451 LogError("CKM::Exception: " << e.GetMessage());
452 return CKM_API_ERROR_SERVER_ERROR;
456 int CKMLogic::getKeyForService(
457 const Credentials &cred,
460 const Password &pass,
461 Crypto::GObjShPtr &key)
466 // Key is for internal service use. It won't be exported to the client
467 Crypto::GObjUPtr obj;
468 int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label,
471 if (retCode == CKM_API_SUCCESS)
472 key = std::move(obj);
475 } catch (const Exc::Exception &e) {
477 } catch (const CKM::Exception &e) {
478 LogError("CKM::Exception: " << e.GetMessage());
479 return CKM_API_ERROR_SERVER_ERROR;
483 RawBuffer CKMLogic::saveData(
484 const Credentials &cred,
488 const Crypto::Data &data,
489 const PolicySerializable &policy)
491 int retCode = verifyAndSaveDataHelper(cred, name, label, data, policy);
492 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
495 static_cast<int>(data.type));
496 return response.Pop();
499 int CKMLogic::extractPKCS12Data(
502 const Label &ownerLabel,
503 const PKCS12Serializable &pkcs,
504 const PolicySerializable &keyPolicy,
505 const PolicySerializable &certPolicy,
506 DB::RowVector &output) const
508 // private key is mandatory
509 auto key = pkcs.getKey();
512 LogError("Failed to get private key from pkcs");
513 return CKM_API_ERROR_INVALID_FORMAT;
516 Crypto::Data keyData(DataType(key->getType()), key->getDER());
517 int retCode = verifyBinaryData(keyData);
519 if (retCode != CKM_API_SUCCESS)
522 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyData,
525 // certificate is mandatory
526 auto cert = pkcs.getCertificate();
529 LogError("Failed to get certificate from pkcs");
530 return CKM_API_ERROR_INVALID_FORMAT;
533 Crypto::Data certData(DataType::CERTIFICATE, cert->getDER());
534 retCode = verifyBinaryData(certData);
536 if (retCode != CKM_API_SUCCESS)
539 output.push_back(createEncryptedRow(crypto, name, ownerLabel, certData,
543 unsigned int cert_index = 0;
545 for (const auto &ca : pkcs.getCaCertificateShPtrVector()) {
546 Crypto::Data caCertData(DataType::getChainDatatype(cert_index ++),
548 int retCode = verifyBinaryData(caCertData);
550 if (retCode != CKM_API_SUCCESS)
553 output.push_back(createEncryptedRow(crypto, name, ownerLabel, caCertData,
557 return CKM_API_SUCCESS;
560 RawBuffer CKMLogic::savePKCS12(
561 const Credentials &cred,
565 const PKCS12Serializable &pkcs,
566 const PolicySerializable &keyPolicy,
567 const PolicySerializable &certPolicy)
569 int retCode = CKM_API_ERROR_UNKNOWN;
572 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
573 } catch (const Exc::Exception &e) {
575 } catch (const CKM::Exception &e) {
576 LogError("CKM::Exception: " << e.GetMessage());
577 retCode = CKM_API_ERROR_SERVER_ERROR;
580 auto response = MessageBuffer::Serialize(static_cast<int>
581 (LogicCommand::SAVE_PKCS12),
584 return response.Pop();
588 int CKMLogic::removeDataHelper(
589 const Credentials &cred,
593 auto &handler = selectDatabase(cred, label);
595 // use client label if not explicitly provided
596 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
598 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
599 LogDebug("Invalid label or name format");
600 return CKM_API_ERROR_INPUT_PARAM;
603 DB::Crypto::Transaction transaction(&handler.database);
605 // read and check permissions
606 PermissionMaskOptional permissionRowOpt =
607 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
608 int retCode = m_accessControl.canDelete(cred,
609 PermissionForLabel(cred.smackLabel, permissionRowOpt));
611 if (retCode != CKM_API_SUCCESS) {
612 LogWarning("access control check result: " << retCode);
616 // get all matching rows
618 handler.database.getRows(name, ownerLabel, DataType::DB_FIRST,
619 DataType::DB_LAST, rows);
622 LogDebug("No row for given name and label");
623 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
626 // load app key if needed
627 retCode = loadAppKey(handler, rows.front().ownerLabel);
629 if (CKM_API_SUCCESS != retCode)
632 // destroy it in store
633 for (auto &r : rows) {
635 handler.crypto.decryptRow(Password(), r);
636 m_decider.getStore(r).destroy(r);
637 } catch (const Exc::AuthenticationFailed &) {
638 LogDebug("Authentication failed when removing data. Ignored.");
643 handler.database.deleteRow(name, ownerLabel);
644 transaction.commit();
646 return CKM_API_SUCCESS;
649 RawBuffer CKMLogic::removeData(
650 const Credentials &cred,
655 int retCode = CKM_API_ERROR_UNKNOWN;
658 retCode = removeDataHelper(cred, name, label);
659 } catch (const Exc::Exception &e) {
661 } catch (const CKM::Exception &e) {
662 LogError("Error: " << e.GetMessage());
663 retCode = CKM_API_ERROR_DB_ERROR;
666 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
669 return response.Pop();
672 int CKMLogic::readSingleRow(const Name &name,
673 const Label &ownerLabel,
675 DB::Crypto &database,
678 DB::Crypto::RowOptional row_optional;
680 if (dataType.isKey()) {
681 // read all key types
682 row_optional = database.getRow(name,
684 DataType::DB_KEY_FIRST,
685 DataType::DB_KEY_LAST);
687 // read anything else
688 row_optional = database.getRow(name,
694 LogDebug("No row for given name, label and type");
695 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
700 return CKM_API_SUCCESS;
704 int CKMLogic::readMultiRow(const Name &name,
705 const Label &ownerLabel,
707 DB::Crypto &database,
708 DB::RowVector &output)
710 if (dataType.isKey())
711 // read all key types
712 database.getRows(name,
714 DataType::DB_KEY_FIRST,
715 DataType::DB_KEY_LAST,
717 else if (dataType.isChainCert())
718 // read all key types
719 database.getRows(name,
721 DataType::DB_CHAIN_FIRST,
722 DataType::DB_CHAIN_LAST,
725 // read anything else
726 database.getRows(name,
731 if (!output.size()) {
732 LogDebug("No row for given name, label and type");
733 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
736 return CKM_API_SUCCESS;
739 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
741 const Label &ownerLabel,
742 const Label &accessorLabel,
745 DB::Crypto &database)
747 PermissionMaskOptional permissionRowOpt =
748 database.getPermissionRow(name, ownerLabel, accessorLabel);
751 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel,
754 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel,
758 Crypto::GObjUPtr CKMLogic::rowToObject(
761 const Password &password)
763 Crypto::GStore &store = m_decider.getStore(row);
765 Password pass = m_accessControl.isCCMode() ? "" : password;
768 Crypto::GObjUPtr obj;
770 if (CryptoLogic::getSchemeVersion(row.encryptionScheme) ==
771 CryptoLogic::ENCRYPTION_V2) {
772 handler.crypto.decryptRow(Password(), row);
774 obj = store.getObject(row, pass);
776 // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data
777 handler.crypto.decryptRow(pass, row);
778 // destroy it in store
781 // import it to store with new scheme: data -> pass(data)
782 Token token = store.import(Crypto::Data(row.dataType, row.data), pass);
784 // get it from the store (it can be different than the data we imported into store)
785 obj = store.getObject(token, pass);
787 // update row with new token
788 *static_cast<Token *>(&row) = std::move(token);
790 // encrypt it with app key: pass(data) -> b64(appkey(pass(data))
791 handler.crypto.encryptRow(row);
794 handler.database.updateRow(row);
800 int CKMLogic::readDataHelper(
802 const Credentials &cred,
806 const Password &password,
807 Crypto::GObjUPtrVector &objs)
809 auto &handler = selectDatabase(cred, label);
811 // use client label if not explicitly provided
812 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
814 if (!isNameValid(name) || !isLabelValid(ownerLabel))
815 return CKM_API_ERROR_INPUT_PARAM;
818 DB::Crypto::Transaction transaction(&handler.database);
820 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
822 if (CKM_API_SUCCESS != retCode)
825 // all read rows belong to the same owner
826 DB::Row &firstRow = rows.at(0);
828 // check access rights
829 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel,
830 firstRow, exportFlag, handler.database);
832 if (CKM_API_SUCCESS != retCode)
835 // load app key if needed
836 retCode = loadAppKey(handler, firstRow.ownerLabel);
838 if (CKM_API_SUCCESS != retCode)
842 for (auto &row : rows)
843 objs.push_back(rowToObject(handler, std::move(row), password));
845 // rowToObject may modify db
846 transaction.commit();
848 return CKM_API_SUCCESS;
851 int CKMLogic::readDataHelper(
853 const Credentials &cred,
857 const Password &password,
858 Crypto::GObjUPtr &obj)
860 DataType objDataType;
861 return readDataHelper(exportFlag, cred, dataType, name, label, password, obj,
865 int CKMLogic::readDataHelper(
867 const Credentials &cred,
871 const Password &password,
872 Crypto::GObjUPtr &obj,
873 DataType &objDataType)
875 auto &handler = selectDatabase(cred, label);
877 // use client label if not explicitly provided
878 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
880 if (!isNameValid(name) || !isLabelValid(ownerLabel))
881 return CKM_API_ERROR_INPUT_PARAM;
884 DB::Crypto::Transaction transaction(&handler.database);
886 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
888 if (CKM_API_SUCCESS != retCode)
891 objDataType = row.dataType;
893 // check access rights
894 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel,
895 row, exportFlag, handler.database);
897 if (CKM_API_SUCCESS != retCode)
900 // load app key if needed
901 retCode = loadAppKey(handler, row.ownerLabel);
903 if (CKM_API_SUCCESS != retCode)
906 obj = rowToObject(handler, std::move(row), password);
907 // rowToObject may modify db
908 transaction.commit();
910 return CKM_API_SUCCESS;
913 RawBuffer CKMLogic::getData(
914 const Credentials &cred,
919 const Password &password)
921 int retCode = CKM_API_SUCCESS;
923 DataType objDataType;
926 Crypto::GObjUPtr obj;
927 retCode = readDataHelper(true, cred, dataType, name, label, password, obj,
930 if (retCode == CKM_API_SUCCESS)
931 row.data = std::move(obj->getBinary());
932 } catch (const Exc::Exception &e) {
934 } catch (const CKM::Exception &e) {
935 LogError("CKM::Exception: " << e.GetMessage());
936 retCode = CKM_API_ERROR_SERVER_ERROR;
939 if (CKM_API_SUCCESS != retCode) {
941 row.dataType = dataType;
944 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
947 static_cast<int>(objDataType),
949 return response.Pop();
952 int CKMLogic::getPKCS12Helper(
953 const Credentials &cred,
956 const Password &keyPassword,
957 const Password &certPassword,
959 CertificateShPtr &cert,
960 CertificateShPtrVector &caChain)
964 // read private key (mandatory)
965 Crypto::GObjUPtr keyObj;
966 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label,
967 keyPassword, keyObj);
969 if (retCode != CKM_API_SUCCESS)
972 privKey = CKM::Key::create(keyObj->getBinary());
974 // read certificate (mandatory)
975 Crypto::GObjUPtr certObj;
976 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label,
977 certPassword, certObj);
979 if (retCode != CKM_API_SUCCESS)
982 cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER);
984 // read CA cert chain (optional)
985 Crypto::GObjUPtrVector caChainObjs;
986 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label,
987 certPassword, caChainObjs);
989 if (retCode != CKM_API_SUCCESS &&
990 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
993 for (auto &caCertObj : caChainObjs)
994 caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(),
995 DataFormat::FORM_DER));
997 // if anything found, return it
998 if (privKey || cert || caChain.size() > 0)
999 retCode = CKM_API_SUCCESS;
1004 RawBuffer CKMLogic::getPKCS12(
1005 const Credentials &cred,
1009 const Password &keyPassword,
1010 const Password &certPassword)
1012 int retCode = CKM_API_ERROR_UNKNOWN;
1014 PKCS12Serializable output;
1018 CertificateShPtr cert;
1019 CertificateShPtrVector caChain;
1020 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey,
1024 if (retCode == CKM_API_SUCCESS)
1025 output = PKCS12Serializable(std::move(privKey), std::move(cert),
1026 std::move(caChain));
1027 } catch (const Exc::Exception &e) {
1028 retCode = e.error();
1029 } catch (const CKM::Exception &e) {
1030 LogError("CKM::Exception: " << e.GetMessage());
1031 retCode = CKM_API_ERROR_SERVER_ERROR;
1034 auto response = MessageBuffer::Serialize(static_cast<int>
1035 (LogicCommand::GET_PKCS12),
1039 return response.Pop();
1042 int CKMLogic::getDataListHelper(const Credentials &cred,
1043 const DataType dataType,
1044 LabelNameVector &labelNameVector)
1046 int retCode = CKM_API_ERROR_DB_LOCKED;
1048 if (0 < m_userDataMap.count(cred.clientUid)) {
1049 auto &database = m_userDataMap[cred.clientUid].database;
1052 LabelNameVector tmpVector;
1054 if (dataType.isKey()) {
1055 // list all key types
1056 database.listNames(cred.smackLabel,
1058 DataType::DB_KEY_FIRST,
1059 DataType::DB_KEY_LAST);
1061 // list anything else
1062 database.listNames(cred.smackLabel,
1067 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(),
1069 retCode = CKM_API_SUCCESS;
1070 } catch (const CKM::Exception &e) {
1071 LogError("Error: " << e.GetMessage());
1072 retCode = CKM_API_ERROR_DB_ERROR;
1073 } catch (const Exc::Exception &e) {
1074 retCode = e.error();
1081 RawBuffer CKMLogic::getDataList(
1082 const Credentials &cred,
1086 LabelNameVector systemVector;
1087 LabelNameVector userVector;
1088 LabelNameVector labelNameVector;
1090 int retCode = unlockSystemDB();
1092 if (CKM_API_SUCCESS == retCode) {
1094 if (m_accessControl.isSystemService(cred)) {
1096 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1101 // user - lookup system, then client DB
1102 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1108 if (retCode == CKM_API_SUCCESS) {
1109 retCode = getDataListHelper(cred,
1116 if (retCode == CKM_API_SUCCESS) {
1117 labelNameVector.insert(labelNameVector.end(), systemVector.begin(),
1118 systemVector.end());
1119 labelNameVector.insert(labelNameVector.end(), userVector.begin(),
1123 auto response = MessageBuffer::Serialize(static_cast<int>
1124 (LogicCommand::GET_LIST),
1127 static_cast<int>(dataType),
1129 return response.Pop();
1132 int CKMLogic::importInitialData(
1134 const Crypto::Data &data,
1135 const Crypto::DataEncryption &enc,
1136 const Policy &policy)
1139 // Inital values are always imported with root credentials. Label is not important.
1140 Credentials rootCred(0, "");
1142 auto &handler = selectDatabase(rootCred, OWNER_ID_SYSTEM);
1144 // check if save is possible
1145 DB::Crypto::Transaction transaction(&handler.database);
1146 int retCode = checkSaveConditions(rootCred, handler, name, OWNER_ID_SYSTEM);
1148 if (retCode != CKM_API_SUCCESS)
1151 Crypto::GStore &store =
1152 m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty());
1156 if (enc.encryptedKey.empty()) {
1157 Crypto::Data binaryData;
1159 if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData)))
1162 token = store.import(binaryData,
1163 m_accessControl.isCCMode() ? "" : policy.password);
1165 token = store.importEncrypted(data,
1166 m_accessControl.isCCMode() ? "" : policy.password, enc);
1169 DB::Row row(std::move(token), name, OWNER_ID_SYSTEM,
1170 static_cast<int>(policy.extractable));
1171 handler.crypto.encryptRow(row);
1173 handler.database.saveRow(row);
1174 transaction.commit();
1175 } catch (const Exc::Exception &e) {
1177 } catch (const CKM::Exception &e) {
1178 LogError("CKM::Exception: " << e.GetMessage());
1179 return CKM_API_ERROR_SERVER_ERROR;
1180 } catch (const std::exception &e) {
1181 LogError("Std::exception: " << e.what());
1182 return CKM_API_ERROR_SERVER_ERROR;
1185 return CKM_API_SUCCESS;
1188 int CKMLogic::saveDataHelper(
1189 const Credentials &cred,
1192 const Crypto::Data &data,
1193 const PolicySerializable &policy)
1195 auto &handler = selectDatabase(cred, label);
1197 // use client label if not explicitly provided
1198 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1200 if (m_accessControl.isSystemService(cred) &&
1201 ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1202 return CKM_API_ERROR_INPUT_PARAM;
1204 // check if save is possible
1205 DB::Crypto::Transaction transaction(&handler.database);
1206 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1208 if (retCode != CKM_API_SUCCESS)
1212 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel,
1214 handler.database.saveRow(encryptedRow);
1216 transaction.commit();
1217 return CKM_API_SUCCESS;
1220 int CKMLogic::saveDataHelper(
1221 const Credentials &cred,
1224 const PKCS12Serializable &pkcs,
1225 const PolicySerializable &keyPolicy,
1226 const PolicySerializable &certPolicy)
1228 auto &handler = selectDatabase(cred, label);
1230 // use client label if not explicitly provided
1231 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1233 if (m_accessControl.isSystemService(cred) &&
1234 ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1235 return CKM_API_ERROR_INPUT_PARAM;
1237 // check if save is possible
1238 DB::Crypto::Transaction transaction(&handler.database);
1239 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1241 if (retCode != CKM_API_SUCCESS)
1244 // extract and encrypt the data
1245 DB::RowVector encryptedRows;
1246 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy,
1247 certPolicy, encryptedRows);
1249 if (retCode != CKM_API_SUCCESS)
1253 handler.database.saveRows(name, ownerLabel, encryptedRows);
1254 transaction.commit();
1256 return CKM_API_SUCCESS;
1260 int CKMLogic::createKeyAESHelper(
1261 const Credentials &cred,
1265 const PolicySerializable &policy)
1267 auto &handler = selectDatabase(cred, label);
1269 // use client label if not explicitly provided
1270 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1272 if (m_accessControl.isSystemService(cred) &&
1273 ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1274 return CKM_API_ERROR_INPUT_PARAM;
1276 // check if save is possible
1277 DB::Crypto::Transaction transaction(&handler.database);
1278 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1280 if (retCode != CKM_API_SUCCESS)
1283 // create key in store
1284 CryptoAlgorithm keyGenAlgorithm;
1285 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
1286 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
1287 Token key = m_decider.getStore(DataType::KEY_AES,
1288 policy.extractable).generateSKey(keyGenAlgorithm, policy.password);
1291 DB::Row row(std::move(key), name, ownerLabel,
1292 static_cast<int>(policy.extractable));
1293 handler.crypto.encryptRow(row);
1295 handler.database.saveRow(row);
1297 transaction.commit();
1298 return CKM_API_SUCCESS;
1301 int CKMLogic::createKeyPairHelper(
1302 const Credentials &cred,
1303 const CryptoAlgorithmSerializable &keyGenParams,
1304 const Name &namePrivate,
1305 const Label &labelPrivate,
1306 const Name &namePublic,
1307 const Label &labelPublic,
1308 const PolicySerializable &policyPrivate,
1309 const PolicySerializable &policyPublic)
1311 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1312 auto &handlerPub = selectDatabase(cred, labelPublic);
1314 AlgoType keyType = AlgoType::RSA_GEN;
1316 if (!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType))
1317 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found.");
1319 DataType dt(keyType);
1322 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
1324 // use client label if not explicitly provided
1325 const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel :
1328 if (m_accessControl.isSystemService(cred) &&
1329 ownerLabelPrv.compare(OWNER_ID_SYSTEM) != 0)
1330 return CKM_API_ERROR_INPUT_PARAM;
1332 const Label &ownerLabelPub = labelPublic.empty() ? cred.smackLabel :
1335 if (m_accessControl.isSystemService(cred) &&
1336 ownerLabelPub.compare(OWNER_ID_SYSTEM) != 0)
1337 return CKM_API_ERROR_INPUT_PARAM;
1339 bool exportable = policyPrivate.extractable || policyPublic.extractable;
1340 TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams,
1341 policyPrivate.password,
1342 policyPublic.password);
1344 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1345 // in case the same database is used for private and public - the second
1346 // transaction will not be executed
1347 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1350 retCode = checkSaveConditions(cred, handlerPriv, namePrivate, ownerLabelPrv);
1352 if (CKM_API_SUCCESS != retCode)
1355 retCode = checkSaveConditions(cred, handlerPub, namePublic, ownerLabelPub);
1357 if (CKM_API_SUCCESS != retCode)
1361 DB::Row rowPrv(std::move(keys.first), namePrivate, ownerLabelPrv,
1362 static_cast<int>(policyPrivate.extractable));
1363 handlerPriv.crypto.encryptRow(rowPrv);
1364 handlerPriv.database.saveRow(rowPrv);
1366 DB::Row rowPub(std::move(keys.second), namePublic, ownerLabelPub,
1367 static_cast<int>(policyPublic.extractable));
1368 handlerPub.crypto.encryptRow(rowPub);
1369 handlerPub.database.saveRow(rowPub);
1371 transactionPub.commit();
1372 transactionPriv.commit();
1373 return CKM_API_SUCCESS;
1376 RawBuffer CKMLogic::createKeyPair(
1377 const Credentials &cred,
1379 const CryptoAlgorithmSerializable &keyGenParams,
1380 const Name &namePrivate,
1381 const Label &labelPrivate,
1382 const Name &namePublic,
1383 const Label &labelPublic,
1384 const PolicySerializable &policyPrivate,
1385 const PolicySerializable &policyPublic)
1387 int retCode = CKM_API_SUCCESS;
1390 retCode = createKeyPairHelper(
1399 } catch (const Exc::Exception &e) {
1400 retCode = e.error();
1401 } catch (const CKM::Exception &e) {
1402 LogError("CKM::Exception: " << e.GetMessage());
1403 retCode = CKM_API_ERROR_SERVER_ERROR;
1406 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR),
1407 commandId, retCode).Pop();
1410 RawBuffer CKMLogic::createKeyAES(
1411 const Credentials &cred,
1416 const PolicySerializable &policy)
1418 int retCode = CKM_API_SUCCESS;
1421 retCode = createKeyAESHelper(cred, size, name, label, policy);
1422 } catch (const Exc::Exception &e) {
1423 retCode = e.error();
1424 } catch (std::invalid_argument &e) {
1425 LogDebug("invalid argument error: " << e.what());
1426 retCode = CKM_API_ERROR_INPUT_PARAM;
1427 } catch (const CKM::Exception &e) {
1428 LogError("CKM::Exception: " << e.GetMessage());
1429 retCode = CKM_API_ERROR_SERVER_ERROR;
1432 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES),
1433 commandId, retCode).Pop();
1436 int CKMLogic::readCertificateHelper(
1437 const Credentials &cred,
1438 const LabelNameVector &labelNameVector,
1439 CertificateImplVector &certVector)
1443 for (auto &i : labelNameVector) {
1444 // certificates can't be protected with custom user password
1445 Crypto::GObjUPtr obj;
1447 ec = readDataHelper(true,
1449 DataType::CERTIFICATE,
1455 if (ec != CKM_API_SUCCESS)
1458 certVector.emplace_back(obj->getBinary(), DataFormat::FORM_DER);
1460 // try to read chain certificates (if present)
1461 Crypto::GObjUPtrVector caChainObjs;
1462 ec = readDataHelper(true,
1464 DataType::DB_CHAIN_FIRST,
1470 if (ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1473 for (auto &caCertObj : caChainObjs)
1474 certVector.emplace_back(caCertObj->getBinary(), DataFormat::FORM_DER);
1477 return CKM_API_SUCCESS;
1480 int CKMLogic::getCertificateChainHelper(
1481 const CertificateImpl &cert,
1482 const RawBufferVector &untrustedCertificates,
1483 const RawBufferVector &trustedCertificates,
1484 bool useTrustedSystemCertificates,
1485 RawBufferVector &chainRawVector)
1487 CertificateImplVector untrustedCertVector;
1488 CertificateImplVector trustedCertVector;
1489 CertificateImplVector chainVector;
1492 return CKM_API_ERROR_INPUT_PARAM;
1494 for (auto &e : untrustedCertificates) {
1495 CertificateImpl c(e, DataFormat::FORM_DER);
1498 return CKM_API_ERROR_INPUT_PARAM;
1500 untrustedCertVector.push_back(std::move(c));
1503 for (auto &e : trustedCertificates) {
1504 CertificateImpl c(e, DataFormat::FORM_DER);
1507 return CKM_API_ERROR_INPUT_PARAM;
1509 trustedCertVector.push_back(std::move(c));
1512 CertificateStore store;
1513 int retCode = store.verifyCertificate(cert,
1514 untrustedCertVector,
1516 useTrustedSystemCertificates,
1517 m_accessControl.isCCMode(),
1520 if (retCode != CKM_API_SUCCESS)
1523 for (auto &e : chainVector)
1524 chainRawVector.push_back(e.getDER());
1526 return CKM_API_SUCCESS;
1529 int CKMLogic::getCertificateChainHelper(
1530 const Credentials &cred,
1531 const CertificateImpl &cert,
1532 const LabelNameVector &untrusted,
1533 const LabelNameVector &trusted,
1534 bool useTrustedSystemCertificates,
1535 RawBufferVector &chainRawVector)
1537 CertificateImplVector untrustedCertVector;
1538 CertificateImplVector trustedCertVector;
1539 CertificateImplVector chainVector;
1543 return CKM_API_ERROR_INPUT_PARAM;
1545 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1547 if (retCode != CKM_API_SUCCESS)
1550 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1552 if (retCode != CKM_API_SUCCESS)
1555 CertificateStore store;
1556 retCode = store.verifyCertificate(cert,
1557 untrustedCertVector,
1559 useTrustedSystemCertificates,
1560 m_accessControl.isCCMode(),
1563 if (retCode != CKM_API_SUCCESS)
1566 for (auto &i : chainVector)
1567 chainRawVector.push_back(i.getDER());
1569 return CKM_API_SUCCESS;
1572 RawBuffer CKMLogic::getCertificateChain(
1573 const Credentials & /*cred*/,
1575 const RawBuffer &certificate,
1576 const RawBufferVector &untrustedCertificates,
1577 const RawBufferVector &trustedCertificates,
1578 bool useTrustedSystemCertificates)
1580 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1581 RawBufferVector chainRawVector;
1582 int retCode = CKM_API_ERROR_UNKNOWN;
1585 retCode = getCertificateChainHelper(cert,
1586 untrustedCertificates,
1587 trustedCertificates,
1588 useTrustedSystemCertificates,
1590 } catch (const Exc::Exception &e) {
1591 retCode = e.error();
1592 } catch (const std::exception &e) {
1593 LogError("STD exception " << e.what());
1594 retCode = CKM_API_ERROR_SERVER_ERROR;
1596 LogError("Unknown error.");
1599 auto response = MessageBuffer::Serialize(static_cast<int>
1600 (LogicCommand::GET_CHAIN_CERT),
1604 return response.Pop();
1607 RawBuffer CKMLogic::getCertificateChain(
1608 const Credentials &cred,
1610 const RawBuffer &certificate,
1611 const LabelNameVector &untrustedCertificates,
1612 const LabelNameVector &trustedCertificates,
1613 bool useTrustedSystemCertificates)
1615 int retCode = CKM_API_ERROR_UNKNOWN;
1616 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1617 RawBufferVector chainRawVector;
1620 retCode = getCertificateChainHelper(cred,
1622 untrustedCertificates,
1623 trustedCertificates,
1624 useTrustedSystemCertificates,
1626 } catch (const Exc::Exception &e) {
1627 retCode = e.error();
1628 } catch (const std::exception &e) {
1629 LogError("STD exception " << e.what());
1630 retCode = CKM_API_ERROR_SERVER_ERROR;
1632 LogError("Unknown error.");
1635 auto response = MessageBuffer::Serialize(static_cast<int>
1636 (LogicCommand::GET_CHAIN_ALIAS),
1640 return response.Pop();
1643 RawBuffer CKMLogic::createSignature(
1644 const Credentials &cred,
1646 const Name &privateKeyName,
1647 const Label &ownerLabel,
1648 const Password &password, // password for private_key
1649 const RawBuffer &message,
1650 const CryptoAlgorithm &cryptoAlg)
1653 RawBuffer signature;
1655 int retCode = CKM_API_SUCCESS;
1658 Crypto::GObjUPtr obj;
1659 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName,
1660 ownerLabel, password, obj);
1662 if (retCode == CKM_API_SUCCESS)
1663 signature = obj->sign(cryptoAlg, message);
1664 } catch (const Exc::Exception &e) {
1665 retCode = e.error();
1666 } catch (const CKM::Exception &e) {
1667 LogError("Unknown CKM::Exception: " << e.GetMessage());
1668 retCode = CKM_API_ERROR_SERVER_ERROR;
1669 } catch (const std::exception &e) {
1670 LogError("STD exception " << e.what());
1671 retCode = CKM_API_ERROR_SERVER_ERROR;
1674 auto response = MessageBuffer::Serialize(static_cast<int>
1675 (LogicCommand::CREATE_SIGNATURE),
1679 return response.Pop();
1682 RawBuffer CKMLogic::verifySignature(
1683 const Credentials &cred,
1685 const Name &publicKeyOrCertName,
1686 const Label &ownerLabel,
1687 const Password &password, // password for public_key (optional)
1688 const RawBuffer &message,
1689 const RawBuffer &signature,
1690 const CryptoAlgorithm ¶ms)
1692 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1697 // try certificate first - looking for a public key.
1698 // in case of PKCS, pub key from certificate will be found first
1699 // rather than private key from the same PKCS.
1700 Crypto::GObjUPtr obj;
1701 retCode = readDataHelper(false, cred, DataType::CERTIFICATE,
1702 publicKeyOrCertName, ownerLabel, password, obj);
1704 if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1705 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST,
1706 publicKeyOrCertName, ownerLabel, password, obj);
1708 if (retCode == CKM_API_SUCCESS)
1709 retCode = obj->verify(params, message, signature);
1710 } catch (const Exc::Exception &e) {
1711 retCode = e.error();
1712 } catch (const CKM::Exception &e) {
1713 LogError("Unknown CKM::Exception: " << e.GetMessage());
1714 retCode = CKM_API_ERROR_SERVER_ERROR;
1717 auto response = MessageBuffer::Serialize(static_cast<int>
1718 (LogicCommand::VERIFY_SIGNATURE),
1721 return response.Pop();
1724 int CKMLogic::setPermissionHelper(
1725 const Credentials &cred, // who's the client
1727 const Label &label, // who's the owner
1728 const Label &accessorLabel, // who will get the access
1729 const PermissionMask permissionMask)
1731 auto &handler = selectDatabase(cred, label);
1733 // we don't know the client
1734 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1735 return CKM_API_ERROR_INPUT_PARAM;
1737 // use client label if not explicitly provided
1738 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1740 // verify name and label are correct
1741 if (!isNameValid(name) || !isLabelValid(ownerLabel) ||
1742 !isLabelValid(accessorLabel))
1743 return CKM_API_ERROR_INPUT_PARAM;
1745 // currently we don't support modification of owner's permissions to his own rows
1746 if (ownerLabel == accessorLabel)
1747 return CKM_API_ERROR_INPUT_PARAM;
1749 // system database does not support write/remove permissions
1750 if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) &&
1751 (permissionMask & Permission::REMOVE))
1752 return CKM_API_ERROR_INPUT_PARAM;
1754 // can the client modify permissions to owner's row?
1755 int retCode = m_accessControl.canModify(cred, ownerLabel);
1757 if (retCode != CKM_API_SUCCESS)
1760 DB::Crypto::Transaction transaction(&handler.database);
1762 if (!handler.database.isNameLabelPresent(name, ownerLabel))
1763 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1765 // removing non-existing permissions: fail
1766 if (permissionMask == Permission::NONE) {
1767 if (!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1768 return CKM_API_ERROR_INPUT_PARAM;
1771 // set permissions to the row owned by ownerLabel for accessorLabel
1772 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1773 transaction.commit();
1775 return CKM_API_SUCCESS;
1778 RawBuffer CKMLogic::setPermission(
1779 const Credentials &cred,
1784 const Label &accessorLabel,
1785 const PermissionMask permissionMask)
1790 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1791 } catch (const Exc::Exception &e) {
1792 retCode = e.error();
1793 } catch (const CKM::Exception &e) {
1794 LogError("Error: " << e.GetMessage());
1795 retCode = CKM_API_ERROR_DB_ERROR;
1798 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
1801 int CKMLogic::loadAppKey(UserData &handle, const Label &appLabel)
1803 if (!handle.crypto.haveKey(appLabel)) {
1805 auto key_optional = handle.database.getKey(appLabel);
1807 if (!key_optional) {
1808 LogError("No key for given label in database");
1809 return CKM_API_ERROR_DB_ERROR;
1812 key = *key_optional;
1813 key = handle.keyProvider.getPureDEK(key);
1814 handle.crypto.pushKey(appLabel, key);
1817 return CKM_API_SUCCESS;