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)
49 bool isNameValid(const CKM::Name &name)
51 if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
56 } // anonymous namespace
60 const uid_t CKMLogic::SYSTEM_DB_UID = 0;
64 CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
66 m_accessControl.updateCCMode();
69 CKMLogic::~CKMLogic() {}
71 void CKMLogic::loadDKEKFile(uid_t user, const Password &password)
73 auto &handle = m_userDataMap[user];
77 auto wrappedDKEK = fs.getDKEK();
79 if (wrappedDKEK.empty()) {
80 wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
81 fs.saveDKEK(wrappedDKEK);
84 handle.keyProvider = KeyProvider(wrappedDKEK, password);
87 void CKMLogic::saveDKEKFile(uid_t user, const Password &password)
89 auto &handle = m_userDataMap[user];
92 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
95 int CKMLogic::unlockDatabase(uid_t user, const Password & password)
97 if (0 < m_userDataMap.count(user) && m_userDataMap[user].keyProvider.isInitialized())
98 return CKM_API_SUCCESS;
100 int retCode = CKM_API_SUCCESS;
102 auto &handle = m_userDataMap[user];
105 loadDKEKFile(user, password);
107 auto wrappedDatabaseDEK = fs.getDBDEK();
108 if (wrappedDatabaseDEK.empty()) {
109 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
110 fs.saveDBDEK(wrappedDatabaseDEK);
113 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
115 handle.database = DB::Crypto(fs.getDBPath(), key);
116 handle.crypto = CryptoLogic();
118 if (!m_accessControl.isSystemService(user)) {
119 // remove data of removed apps during locked state
120 AppLabelVector removedApps = fs.clearRemovedsApps();
121 for (auto& appSmackLabel : removedApps) {
122 handle.crypto.removeKey(appSmackLabel);
123 handle.database.deleteKey(appSmackLabel);
126 } catch (const Exc::Exception &e) {
128 } catch (const CKM::Exception &e) {
129 LogError("CKM::Exception: " << e.GetMessage());
130 retCode = CKM_API_ERROR_SERVER_ERROR;
133 if (CKM_API_SUCCESS != retCode)
134 m_userDataMap.erase(user);
139 int CKMLogic::unlockSystemDB()
141 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
144 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
146 // if user trying to access system service - check:
147 // * if user database is unlocked [mandatory]
148 // * if not - proceed with regular user database
149 // * if explicit system database label given -> switch to system DB
150 if (!m_accessControl.isSystemService(cred)) {
151 if (0 == m_userDataMap.count(cred.clientUid))
152 ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked");
154 if (0 != incoming_label.compare(OWNER_ID_SYSTEM))
155 return m_userDataMap[cred.clientUid];
158 // system database selected, modify the label
159 if (CKM_API_SUCCESS != unlockSystemDB() )
160 ThrowErr(Exc::DatabaseLocked, "can not unlock system database");
162 return m_userDataMap[SYSTEM_DB_UID];
165 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
167 int retCode = CKM_API_SUCCESS;
169 if (!m_accessControl.isSystemService(user))
170 retCode = unlockDatabase(user, password);
171 else // do not allow lock/unlock operations for system users
172 retCode = CKM_API_ERROR_INPUT_PARAM;
174 return MessageBuffer::Serialize(retCode).Pop();
177 RawBuffer CKMLogic::updateCCMode()
179 m_accessControl.updateCCMode();
180 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
183 RawBuffer CKMLogic::lockUserKey(uid_t user)
185 int retCode = CKM_API_SUCCESS;
186 if (!m_accessControl.isSystemService(user))
187 m_userDataMap.erase(user);
188 else // do not allow lock/unlock operations for system users
189 retCode = CKM_API_ERROR_INPUT_PARAM;
191 return MessageBuffer::Serialize(retCode).Pop();
194 RawBuffer CKMLogic::removeUserData(uid_t user)
196 int retCode = CKM_API_SUCCESS;
198 if (m_accessControl.isSystemService(user))
199 user = SYSTEM_DB_UID;
201 m_userDataMap.erase(user);
206 return MessageBuffer::Serialize(retCode).Pop();
209 int CKMLogic::changeUserPasswordHelper(uid_t user,
210 const Password &oldPassword,
211 const Password &newPassword)
213 // do not allow to change system database password
214 if (m_accessControl.isSystemService(user))
215 return CKM_API_ERROR_INPUT_PARAM;
217 loadDKEKFile(user, oldPassword);
218 saveDKEKFile(user, newPassword);
220 return CKM_API_SUCCESS;
223 RawBuffer CKMLogic::changeUserPassword(
225 const Password &oldPassword,
226 const Password &newPassword)
228 int retCode = CKM_API_SUCCESS;
230 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
231 } catch (const Exc::Exception &e) {
233 } catch (const CKM::Exception &e) {
234 LogError("CKM::Exception: " << e.GetMessage());
235 retCode = CKM_API_ERROR_SERVER_ERROR;
238 return MessageBuffer::Serialize(retCode).Pop();
241 int CKMLogic::resetUserPasswordHelper(
243 const Password &newPassword)
245 // do not allow to reset system database password
246 if (m_accessControl.isSystemService(user))
247 return CKM_API_ERROR_INPUT_PARAM;
249 int retCode = CKM_API_SUCCESS;
250 if (0 == m_userDataMap.count(user)) {
251 // Check if key exists. If exists we must return error
253 auto wrappedDKEKMain = fs.getDKEK();
254 if (!wrappedDKEKMain.empty())
255 retCode = CKM_API_ERROR_BAD_REQUEST;
257 saveDKEKFile(user, newPassword);
263 RawBuffer CKMLogic::resetUserPassword(
265 const Password &newPassword)
267 int retCode = CKM_API_SUCCESS;
269 retCode = resetUserPasswordHelper(user, newPassword);
270 } catch (const Exc::Exception &e) {
272 } catch (const CKM::Exception &e) {
273 LogError("CKM::Exception: " << e.GetMessage());
274 retCode = CKM_API_ERROR_SERVER_ERROR;
277 return MessageBuffer::Serialize(retCode).Pop();
280 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel)
282 int retCode = CKM_API_SUCCESS;
285 if (smackLabel.empty()) {
286 retCode = CKM_API_ERROR_INPUT_PARAM;
288 UidVector uids = FileSystem::getUIDsFromDBFile();
289 for (auto userId : uids) {
290 if (0 == m_userDataMap.count(userId)) {
291 FileSystem fs(userId);
292 fs.addRemovedApp(smackLabel);
294 auto &handle = m_userDataMap[userId];
295 handle.crypto.removeKey(smackLabel);
296 handle.database.deleteKey(smackLabel);
300 } catch (const Exc::Exception &e) {
302 } catch (const CKM::Exception &e) {
303 LogError("CKM::Exception: " << e.GetMessage());
304 retCode = CKM_API_ERROR_SERVER_ERROR;
307 return MessageBuffer::Serialize(retCode).Pop();
310 int CKMLogic::checkSaveConditions(
311 const Credentials &cred,
314 const Label &ownerLabel)
316 // verify name and label are correct
317 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
318 LogDebug("Invalid parameter passed to key-manager");
319 return CKM_API_ERROR_INPUT_PARAM;
322 // check if allowed to save using ownerLabel
323 int access_ec = m_accessControl.canSave(cred, ownerLabel);
324 if (access_ec != CKM_API_SUCCESS) {
325 LogDebug("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
329 // check if not a duplicate
330 if (handler.database.isNameLabelPresent(name, ownerLabel))
331 return CKM_API_ERROR_DB_ALIAS_EXISTS;
333 // encryption section
334 if (!handler.crypto.haveKey(ownerLabel)) {
336 auto key_optional = handler.database.getKey(ownerLabel);
338 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
339 got_key = handler.keyProvider.generateDEK(ownerLabel);
340 handler.database.saveKey(ownerLabel, got_key);
342 LogDebug("Key from DB");
343 got_key = *key_optional;
346 got_key = handler.keyProvider.getPureDEK(got_key);
347 handler.crypto.pushKey(ownerLabel, got_key);
350 return CKM_API_SUCCESS;
353 DB::Row CKMLogic::createEncryptedRow(
357 const Crypto::Data &data,
358 const Policy &policy) const
360 Crypto::GStore& store = m_decider.getStore(data.type, policy.extractable);
362 // do not encrypt data with password during cc_mode on
363 Token token = store.import(data, m_accessControl.isCCMode() ? "" : policy.password);
364 DB::Row row(std::move(token), name, label, static_cast<int>(policy.extractable));
365 crypto.encryptRow(row);
369 int CKMLogic::verifyBinaryData(Crypto::Data &input) const
372 return toBinaryData(input, dummy);
375 int CKMLogic::toBinaryData(const Crypto::Data &input, Crypto::Data &output) const
377 // verify the data integrity
378 if (input.type.isKey()) {
380 if (input.type.isSKey())
381 output_key = CKM::Key::createAES(input.data);
383 output_key = CKM::Key::create(input.data);
385 if (output_key.get() == NULL) {
386 LogDebug("provided binary data is not valid key data");
387 return CKM_API_ERROR_INPUT_PARAM;
389 output = std::move(Crypto::Data(input.type, output_key->getDER()));
390 } else if (input.type.isCertificate() || input.type.isChainCert()) {
391 CertificateShPtr cert = CKM::Certificate::create(input.data, DataFormat::FORM_DER);
392 if (cert.get() == NULL) {
393 LogDebug("provided binary data is not valid certificate data");
394 return CKM_API_ERROR_INPUT_PARAM;
396 output = std::move(Crypto::Data(input.type, cert->getDER()));
400 // TODO: add here BINARY_DATA verification, i.e: max size etc.
401 return CKM_API_SUCCESS;
404 int CKMLogic::verifyAndSaveDataHelper(
405 const Credentials &cred,
408 const Crypto::Data &data,
409 const PolicySerializable &policy)
411 int retCode = CKM_API_ERROR_UNKNOWN;
414 // check if data is correct
415 Crypto::Data binaryData;
416 retCode = toBinaryData(data, binaryData);
417 if (retCode == CKM_API_SUCCESS)
418 retCode = saveDataHelper(cred, name, label, binaryData, policy);
419 } catch (const Exc::Exception &e) {
421 } catch (const CKM::Exception &e) {
422 LogError("CKM::Exception: " << e.GetMessage());
423 retCode = CKM_API_ERROR_SERVER_ERROR;
428 int CKMLogic::getKeyForService(
429 const Credentials &cred,
432 const Password &pass,
433 Crypto::GObjShPtr &key)
437 // Key is for internal service use. It won't be exported to the client
438 Crypto::GObjUPtr obj;
439 int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, obj);
440 if (retCode == CKM_API_SUCCESS)
441 key = std::move(obj);
443 } catch (const Exc::Exception &e) {
445 } catch (const CKM::Exception &e) {
446 LogError("CKM::Exception: " << e.GetMessage());
447 return CKM_API_ERROR_SERVER_ERROR;
451 RawBuffer CKMLogic::saveData(
452 const Credentials &cred,
456 const Crypto::Data &data,
457 const PolicySerializable &policy)
459 int retCode = verifyAndSaveDataHelper(cred, name, label, data, policy);
460 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
463 static_cast<int>(data.type));
464 return response.Pop();
467 int CKMLogic::extractPKCS12Data(
470 const Label &ownerLabel,
471 const PKCS12Serializable &pkcs,
472 const PolicySerializable &keyPolicy,
473 const PolicySerializable &certPolicy,
474 DB::RowVector &output) const
476 // private key is mandatory
478 return CKM_API_ERROR_INVALID_FORMAT;
479 Key* keyPtr = pkcs.getKey().get();
480 Crypto::Data keyData(DataType(keyPtr->getType()), keyPtr->getDER());
481 int retCode = verifyBinaryData(keyData);
482 if (retCode != CKM_API_SUCCESS)
484 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyData, keyPolicy));
486 // certificate is mandatory
487 if (!pkcs.getCertificate())
488 return CKM_API_ERROR_INVALID_FORMAT;
489 Crypto::Data certData(DataType::CERTIFICATE, pkcs.getCertificate().get()->getDER());
490 retCode = verifyBinaryData(certData);
491 if (retCode != CKM_API_SUCCESS)
493 output.push_back(createEncryptedRow(crypto, name, ownerLabel, certData, certPolicy));
496 unsigned int cert_index = 0;
497 for (const auto & ca : pkcs.getCaCertificateShPtrVector()) {
498 Crypto::Data caCertData(DataType::getChainDatatype(cert_index ++), ca->getDER());
499 int retCode = verifyBinaryData(caCertData);
500 if (retCode != CKM_API_SUCCESS)
503 output.push_back(createEncryptedRow(crypto, name, ownerLabel, caCertData, certPolicy));
506 return CKM_API_SUCCESS;
509 RawBuffer CKMLogic::savePKCS12(
510 const Credentials &cred,
514 const PKCS12Serializable &pkcs,
515 const PolicySerializable &keyPolicy,
516 const PolicySerializable &certPolicy)
518 int retCode = CKM_API_ERROR_UNKNOWN;
520 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
521 } catch (const Exc::Exception &e) {
523 } catch (const CKM::Exception &e) {
524 LogError("CKM::Exception: " << e.GetMessage());
525 retCode = CKM_API_ERROR_SERVER_ERROR;
528 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
531 return response.Pop();
535 int CKMLogic::removeDataHelper(
536 const Credentials &cred,
540 auto &handler = selectDatabase(cred, label);
542 // use client label if not explicitly provided
543 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
544 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
545 LogDebug("Invalid label or name format");
546 return CKM_API_ERROR_INPUT_PARAM;
549 DB::Crypto::Transaction transaction(&handler.database);
551 // read and check permissions
552 PermissionMaskOptional permissionRowOpt =
553 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
554 int retCode = m_accessControl.canDelete(cred,
555 PermissionForLabel(cred.smackLabel, permissionRowOpt));
556 if (retCode != CKM_API_SUCCESS) {
557 LogWarning("access control check result: " << retCode);
561 // get all matching rows
563 handler.database.getRows(name, ownerLabel, DataType::DB_FIRST, DataType::DB_LAST, rows);
565 LogDebug("No row for given name and label");
566 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
569 // load app key if needed
570 retCode = loadAppKey(handler, rows.front().ownerLabel);
571 if (CKM_API_SUCCESS != retCode)
574 // destroy it in store
575 for (auto& r : rows) {
577 handler.crypto.decryptRow(Password(), r);
578 m_decider.getStore(r).destroy(r);
579 } catch (const Exc::AuthenticationFailed&) {
580 LogDebug("Authentication failed when removing data. Ignored.");
585 handler.database.deleteRow(name, ownerLabel);
586 transaction.commit();
588 return CKM_API_SUCCESS;
591 RawBuffer CKMLogic::removeData(
592 const Credentials &cred,
597 int retCode = CKM_API_ERROR_UNKNOWN;
600 retCode = removeDataHelper(cred, name, label);
601 } catch (const Exc::Exception &e) {
603 } catch (const CKM::Exception &e) {
604 LogError("Error: " << e.GetMessage());
605 retCode = CKM_API_ERROR_DB_ERROR;
608 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
611 return response.Pop();
614 int CKMLogic::readSingleRow(const Name &name,
615 const Label &ownerLabel,
617 DB::Crypto & database,
620 DB::Crypto::RowOptional row_optional;
621 if (dataType.isKey()) {
622 // read all key types
623 row_optional = database.getRow(name,
625 DataType::DB_KEY_FIRST,
626 DataType::DB_KEY_LAST);
628 // read anything else
629 row_optional = database.getRow(name,
635 LogDebug("No row for given name, label and type");
636 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
641 return CKM_API_SUCCESS;
645 int CKMLogic::readMultiRow(const Name &name,
646 const Label &ownerLabel,
648 DB::Crypto & database,
649 DB::RowVector &output)
651 if (dataType.isKey())
652 // read all key types
653 database.getRows(name,
655 DataType::DB_KEY_FIRST,
656 DataType::DB_KEY_LAST,
658 else if (dataType.isChainCert())
659 // read all key types
660 database.getRows(name,
662 DataType::DB_CHAIN_FIRST,
663 DataType::DB_CHAIN_LAST,
666 // read anything else
667 database.getRows(name,
672 if (!output.size()) {
673 LogDebug("No row for given name, label and type");
674 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
677 return CKM_API_SUCCESS;
680 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
682 const Label &ownerLabel,
683 const Label &accessorLabel,
686 DB::Crypto & database)
688 PermissionMaskOptional permissionRowOpt =
689 database.getPermissionRow(name, ownerLabel, accessorLabel);
692 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
693 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
696 Crypto::GObjUPtr CKMLogic::rowToObject(
699 const Password& password)
701 Crypto::GStore& store = m_decider.getStore(row);
703 Password pass = m_accessControl.isCCMode() ? "" : password;
706 Crypto::GObjUPtr obj;
707 if (CryptoLogic::getSchemeVersion(row.encryptionScheme) == CryptoLogic::ENCRYPTION_V2) {
708 handler.crypto.decryptRow(Password(), row);
710 obj = store.getObject(row, pass);
712 // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data
713 handler.crypto.decryptRow(pass, row);
714 // destroy it in store
717 // import it to store with new scheme: data -> pass(data)
718 Token token = store.import(Crypto::Data(row.dataType, row.data), pass);
720 // get it from the store (it can be different than the data we imported into store)
721 obj = store.getObject(token, pass);
723 // update row with new token
724 *static_cast<Token*>(&row) = std::move(token);
726 // encrypt it with app key: pass(data) -> b64(appkey(pass(data))
727 handler.crypto.encryptRow(row);
730 handler.database.updateRow(row);
735 int CKMLogic::readDataHelper(
737 const Credentials &cred,
741 const Password &password,
742 Crypto::GObjUPtrVector &objs)
744 auto &handler = selectDatabase(cred, label);
746 // use client label if not explicitly provided
747 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
749 if (!isNameValid(name) || !isLabelValid(ownerLabel))
750 return CKM_API_ERROR_INPUT_PARAM;
753 DB::Crypto::Transaction transaction(&handler.database);
755 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
756 if (CKM_API_SUCCESS != retCode)
759 // all read rows belong to the same owner
760 DB::Row & firstRow = rows.at(0);
762 // check access rights
763 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
764 if (CKM_API_SUCCESS != retCode)
767 // load app key if needed
768 retCode = loadAppKey(handler, firstRow.ownerLabel);
769 if (CKM_API_SUCCESS != retCode)
773 for (auto &row : rows)
774 objs.push_back(rowToObject(handler, std::move(row), password));
775 // rowToObject may modify db
776 transaction.commit();
778 return CKM_API_SUCCESS;
781 int CKMLogic::readDataHelper(
783 const Credentials &cred,
787 const Password &password,
788 Crypto::GObjUPtr &obj)
790 DataType objDataType;
791 return readDataHelper(exportFlag, cred, dataType, name, label, password, obj, objDataType);
794 int CKMLogic::readDataHelper(
796 const Credentials &cred,
800 const Password &password,
801 Crypto::GObjUPtr &obj,
802 DataType& objDataType)
804 auto &handler = selectDatabase(cred, label);
806 // use client label if not explicitly provided
807 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
809 if (!isNameValid(name) || !isLabelValid(ownerLabel))
810 return CKM_API_ERROR_INPUT_PARAM;
813 DB::Crypto::Transaction transaction(&handler.database);
815 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
816 if (CKM_API_SUCCESS != retCode)
819 objDataType = row.dataType;
821 // check access rights
822 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
823 if (CKM_API_SUCCESS != retCode)
826 // load app key if needed
827 retCode = loadAppKey(handler, row.ownerLabel);
828 if (CKM_API_SUCCESS != retCode)
831 obj = rowToObject(handler, std::move(row), password);
832 // rowToObject may modify db
833 transaction.commit();
835 return CKM_API_SUCCESS;
838 RawBuffer CKMLogic::getData(
839 const Credentials &cred,
844 const Password &password)
846 int retCode = CKM_API_SUCCESS;
848 DataType objDataType;
851 Crypto::GObjUPtr obj;
852 retCode = readDataHelper(true, cred, dataType, name, label, password, obj, objDataType);
853 if (retCode == CKM_API_SUCCESS)
854 row.data = std::move(obj->getBinary());
855 } catch (const Exc::Exception &e) {
857 } catch (const CKM::Exception &e) {
858 LogError("CKM::Exception: " << e.GetMessage());
859 retCode = CKM_API_ERROR_SERVER_ERROR;
862 if (CKM_API_SUCCESS != retCode) {
864 row.dataType = dataType;
867 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
870 static_cast<int>(objDataType),
872 return response.Pop();
875 int CKMLogic::getPKCS12Helper(
876 const Credentials &cred,
879 const Password &keyPassword,
880 const Password &certPassword,
882 CertificateShPtr & cert,
883 CertificateShPtrVector & caChain)
887 // read private key (mandatory)
888 Crypto::GObjUPtr keyObj;
889 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, keyObj);
890 if (retCode != CKM_API_SUCCESS)
892 privKey = CKM::Key::create(keyObj->getBinary());
894 // read certificate (mandatory)
895 Crypto::GObjUPtr certObj;
896 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certObj);
897 if (retCode != CKM_API_SUCCESS)
899 cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER);
901 // read CA cert chain (optional)
902 Crypto::GObjUPtrVector caChainObjs;
903 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, caChainObjs);
904 if (retCode != CKM_API_SUCCESS &&
905 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
907 for (auto &caCertObj : caChainObjs)
908 caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(), DataFormat::FORM_DER));
910 // if anything found, return it
911 if (privKey || cert || caChain.size() > 0)
912 retCode = CKM_API_SUCCESS;
917 RawBuffer CKMLogic::getPKCS12(
918 const Credentials &cred,
922 const Password &keyPassword,
923 const Password &certPassword)
925 int retCode = CKM_API_ERROR_UNKNOWN;
927 PKCS12Serializable output;
930 CertificateShPtr cert;
931 CertificateShPtrVector caChain;
932 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
935 if (retCode == CKM_API_SUCCESS)
936 output = PKCS12Serializable(privKey, cert, caChain);
937 } catch (const Exc::Exception &e) {
939 } catch (const CKM::Exception &e) {
940 LogError("CKM::Exception: " << e.GetMessage());
941 retCode = CKM_API_ERROR_SERVER_ERROR;
944 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
948 return response.Pop();
951 int CKMLogic::getDataListHelper(const Credentials &cred,
952 const DataType dataType,
953 LabelNameVector &labelNameVector)
955 int retCode = CKM_API_ERROR_DB_LOCKED;
956 if (0 < m_userDataMap.count(cred.clientUid)) {
957 auto &database = m_userDataMap[cred.clientUid].database;
960 LabelNameVector tmpVector;
961 if (dataType.isKey()) {
962 // list all key types
963 database.listNames(cred.smackLabel,
965 DataType::DB_KEY_FIRST,
966 DataType::DB_KEY_LAST);
968 // list anything else
969 database.listNames(cred.smackLabel,
973 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
974 retCode = CKM_API_SUCCESS;
975 } catch (const CKM::Exception &e) {
976 LogError("Error: " << e.GetMessage());
977 retCode = CKM_API_ERROR_DB_ERROR;
978 } catch (const Exc::Exception &e) {
985 RawBuffer CKMLogic::getDataList(
986 const Credentials &cred,
990 LabelNameVector systemVector;
991 LabelNameVector userVector;
992 LabelNameVector labelNameVector;
994 int retCode = unlockSystemDB();
995 if (CKM_API_SUCCESS == retCode) {
997 if (m_accessControl.isSystemService(cred)) {
999 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1004 // user - lookup system, then client DB
1005 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1011 if (retCode == CKM_API_SUCCESS) {
1012 retCode = getDataListHelper(cred,
1019 if (retCode == CKM_API_SUCCESS) {
1020 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1021 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1024 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1027 static_cast<int>(dataType),
1029 return response.Pop();
1032 int CKMLogic::importInitialData(
1034 const Crypto::Data &data,
1035 const Crypto::DataEncryption &enc,
1036 const Policy &policy)
1039 // Inital values are always imported with root credentials. Label is not important.
1040 Credentials rootCred(0, "");
1042 auto &handler = selectDatabase(rootCred, OWNER_ID_SYSTEM);
1044 // check if save is possible
1045 DB::Crypto::Transaction transaction(&handler.database);
1046 int retCode = checkSaveConditions(rootCred, handler, name, OWNER_ID_SYSTEM);
1047 if (retCode != CKM_API_SUCCESS)
1050 Crypto::GStore& store =
1051 m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty());
1055 if (enc.encryptedKey.empty()) {
1056 Crypto::Data binaryData;
1057 if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData)))
1059 token = store.import(binaryData, m_accessControl.isCCMode() ? "" : policy.password);
1061 token = store.importEncrypted(data, m_accessControl.isCCMode() ? "" : policy.password, enc);
1064 DB::Row row(std::move(token), name, OWNER_ID_SYSTEM, static_cast<int>(policy.extractable));
1065 handler.crypto.encryptRow(row);
1067 handler.database.saveRow(row);
1068 transaction.commit();
1069 } catch (const Exc::Exception &e) {
1071 } catch (const CKM::Exception &e) {
1072 LogError("CKM::Exception: " << e.GetMessage());
1073 return CKM_API_ERROR_SERVER_ERROR;
1074 } catch (const std::exception &e) {
1075 LogError("Std::exception: " << e.what());
1076 return CKM_API_ERROR_SERVER_ERROR;
1079 return CKM_API_SUCCESS;
1082 int CKMLogic::saveDataHelper(
1083 const Credentials &cred,
1086 const Crypto::Data &data,
1087 const PolicySerializable &policy)
1089 auto &handler = selectDatabase(cred, label);
1091 // use client label if not explicitly provided
1092 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1093 if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1094 return CKM_API_ERROR_INPUT_PARAM;
1096 // check if save is possible
1097 DB::Crypto::Transaction transaction(&handler.database);
1098 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1099 if (retCode != CKM_API_SUCCESS)
1103 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, data, policy);
1104 handler.database.saveRow(encryptedRow);
1106 transaction.commit();
1107 return CKM_API_SUCCESS;
1110 int CKMLogic::saveDataHelper(
1111 const Credentials &cred,
1114 const PKCS12Serializable &pkcs,
1115 const PolicySerializable &keyPolicy,
1116 const PolicySerializable &certPolicy)
1118 auto &handler = selectDatabase(cred, label);
1120 // use client label if not explicitly provided
1121 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1122 if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1123 return CKM_API_ERROR_INPUT_PARAM;
1125 // check if save is possible
1126 DB::Crypto::Transaction transaction(&handler.database);
1127 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1128 if (retCode != CKM_API_SUCCESS)
1131 // extract and encrypt the data
1132 DB::RowVector encryptedRows;
1133 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1134 if (retCode != CKM_API_SUCCESS)
1138 handler.database.saveRows(name, ownerLabel, encryptedRows);
1139 transaction.commit();
1141 return CKM_API_SUCCESS;
1145 int CKMLogic::createKeyAESHelper(
1146 const Credentials &cred,
1150 const PolicySerializable &policy)
1152 auto &handler = selectDatabase(cred, label);
1154 // use client label if not explicitly provided
1155 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1156 if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1157 return CKM_API_ERROR_INPUT_PARAM;
1159 // check if save is possible
1160 DB::Crypto::Transaction transaction(&handler.database);
1161 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1162 if (retCode != CKM_API_SUCCESS)
1165 // create key in store
1166 CryptoAlgorithm keyGenAlgorithm;
1167 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
1168 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
1169 Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm, policy.password);
1172 DB::Row row(std::move(key), name, ownerLabel, static_cast<int>(policy.extractable));
1173 handler.crypto.encryptRow(row);
1175 handler.database.saveRow(row);
1177 transaction.commit();
1178 return CKM_API_SUCCESS;
1181 int CKMLogic::createKeyPairHelper(
1182 const Credentials &cred,
1183 const CryptoAlgorithmSerializable & keyGenParams,
1184 const Name &namePrivate,
1185 const Label &labelPrivate,
1186 const Name &namePublic,
1187 const Label &labelPublic,
1188 const PolicySerializable &policyPrivate,
1189 const PolicySerializable &policyPublic)
1191 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1192 auto &handlerPub = selectDatabase(cred, labelPublic);
1194 AlgoType keyType = AlgoType::RSA_GEN;
1195 if (!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType))
1196 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found.");
1198 DataType dt(keyType);
1200 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
1202 // use client label if not explicitly provided
1203 const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel : labelPrivate;
1204 if (m_accessControl.isSystemService(cred) && ownerLabelPrv.compare(OWNER_ID_SYSTEM) != 0)
1205 return CKM_API_ERROR_INPUT_PARAM;
1207 const Label &ownerLabelPub = labelPublic.empty() ? cred.smackLabel : labelPublic;
1208 if (m_accessControl.isSystemService(cred) && ownerLabelPub.compare(OWNER_ID_SYSTEM) != 0)
1209 return CKM_API_ERROR_INPUT_PARAM;
1211 bool exportable = policyPrivate.extractable || policyPublic.extractable;
1212 TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams,
1213 policyPrivate.password,
1214 policyPublic.password);
1216 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1217 // in case the same database is used for private and public - the second
1218 // transaction will not be executed
1219 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1222 retCode = checkSaveConditions(cred, handlerPriv, namePrivate, ownerLabelPrv);
1223 if (CKM_API_SUCCESS != retCode)
1226 retCode = checkSaveConditions(cred, handlerPub, namePublic, ownerLabelPub);
1227 if (CKM_API_SUCCESS != retCode)
1231 DB::Row rowPrv(std::move(keys.first), namePrivate, ownerLabelPrv, static_cast<int>(policyPrivate.extractable));
1232 handlerPriv.crypto.encryptRow(rowPrv);
1233 handlerPriv.database.saveRow(rowPrv);
1235 DB::Row rowPub(std::move(keys.second), namePublic, ownerLabelPub, static_cast<int>(policyPublic.extractable));
1236 handlerPub.crypto.encryptRow(rowPub);
1237 handlerPub.database.saveRow(rowPub);
1239 transactionPub.commit();
1240 transactionPriv.commit();
1241 return CKM_API_SUCCESS;
1244 RawBuffer CKMLogic::createKeyPair(
1245 const Credentials &cred,
1247 const CryptoAlgorithmSerializable & keyGenParams,
1248 const Name &namePrivate,
1249 const Label &labelPrivate,
1250 const Name &namePublic,
1251 const Label &labelPublic,
1252 const PolicySerializable &policyPrivate,
1253 const PolicySerializable &policyPublic)
1255 int retCode = CKM_API_SUCCESS;
1258 retCode = createKeyPairHelper(
1267 } catch(const Exc::Exception &e) {
1268 retCode = e.error();
1269 } catch (const CKM::Exception &e) {
1270 LogError("CKM::Exception: " << e.GetMessage());
1271 retCode = CKM_API_ERROR_SERVER_ERROR;
1274 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR),
1275 commandId, retCode).Pop();
1278 RawBuffer CKMLogic::createKeyAES(
1279 const Credentials &cred,
1284 const PolicySerializable &policy)
1286 int retCode = CKM_API_SUCCESS;
1289 retCode = createKeyAESHelper(cred, size, name, label, policy);
1290 } catch (const Exc::Exception &e) {
1291 retCode = e.error();
1292 } catch (std::invalid_argument &e) {
1293 LogDebug("invalid argument error: " << e.what());
1294 retCode = CKM_API_ERROR_INPUT_PARAM;
1295 } catch (const CKM::Exception &e) {
1296 LogError("CKM::Exception: " << e.GetMessage());
1297 retCode = CKM_API_ERROR_SERVER_ERROR;
1300 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES),
1301 commandId, retCode).Pop();
1304 int CKMLogic::readCertificateHelper(
1305 const Credentials &cred,
1306 const LabelNameVector &labelNameVector,
1307 CertificateImplVector &certVector)
1310 for (auto &i: labelNameVector) {
1311 // certificates can't be protected with custom user password
1312 Crypto::GObjUPtr obj;
1314 ec = readDataHelper(true,
1316 DataType::CERTIFICATE,
1321 if (ec != CKM_API_SUCCESS)
1324 certVector.emplace_back(obj->getBinary(), DataFormat::FORM_DER);
1326 // try to read chain certificates (if present)
1327 Crypto::GObjUPtrVector caChainObjs;
1328 ec = readDataHelper(true,
1330 DataType::DB_CHAIN_FIRST,
1335 if (ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1337 for (auto &caCertObj : caChainObjs)
1338 certVector.emplace_back(caCertObj->getBinary(), DataFormat::FORM_DER);
1340 return CKM_API_SUCCESS;
1343 int CKMLogic::getCertificateChainHelper(
1344 const CertificateImpl &cert,
1345 const RawBufferVector &untrustedCertificates,
1346 const RawBufferVector &trustedCertificates,
1347 bool useTrustedSystemCertificates,
1348 RawBufferVector &chainRawVector)
1350 CertificateImplVector untrustedCertVector;
1351 CertificateImplVector trustedCertVector;
1352 CertificateImplVector chainVector;
1355 return CKM_API_ERROR_INPUT_PARAM;
1357 for (auto &e: untrustedCertificates) {
1358 CertificateImpl c(e, DataFormat::FORM_DER);
1360 return CKM_API_ERROR_INPUT_PARAM;
1361 untrustedCertVector.push_back(std::move(c));
1363 for (auto &e: trustedCertificates) {
1364 CertificateImpl c(e, DataFormat::FORM_DER);
1366 return CKM_API_ERROR_INPUT_PARAM;
1367 trustedCertVector.push_back(std::move(c));
1370 CertificateStore store;
1371 int retCode = store.verifyCertificate(cert,
1372 untrustedCertVector,
1374 useTrustedSystemCertificates,
1375 m_accessControl.isCCMode(),
1377 if (retCode != CKM_API_SUCCESS)
1380 for (auto &e : chainVector)
1381 chainRawVector.push_back(e.getDER());
1382 return CKM_API_SUCCESS;
1385 int CKMLogic::getCertificateChainHelper(
1386 const Credentials &cred,
1387 const CertificateImpl &cert,
1388 const LabelNameVector &untrusted,
1389 const LabelNameVector &trusted,
1390 bool useTrustedSystemCertificates,
1391 RawBufferVector &chainRawVector)
1393 CertificateImplVector untrustedCertVector;
1394 CertificateImplVector trustedCertVector;
1395 CertificateImplVector chainVector;
1399 return CKM_API_ERROR_INPUT_PARAM;
1401 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1402 if (retCode != CKM_API_SUCCESS)
1404 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1405 if (retCode != CKM_API_SUCCESS)
1408 CertificateStore store;
1409 retCode = store.verifyCertificate(cert,
1410 untrustedCertVector,
1412 useTrustedSystemCertificates,
1413 m_accessControl.isCCMode(),
1415 if (retCode != CKM_API_SUCCESS)
1418 for (auto &i: chainVector)
1419 chainRawVector.push_back(i.getDER());
1421 return CKM_API_SUCCESS;
1424 RawBuffer CKMLogic::getCertificateChain(
1425 const Credentials & /*cred*/,
1427 const RawBuffer &certificate,
1428 const RawBufferVector &untrustedCertificates,
1429 const RawBufferVector &trustedCertificates,
1430 bool useTrustedSystemCertificates)
1432 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1433 RawBufferVector chainRawVector;
1434 int retCode = CKM_API_ERROR_UNKNOWN;
1436 retCode = getCertificateChainHelper(cert,
1437 untrustedCertificates,
1438 trustedCertificates,
1439 useTrustedSystemCertificates,
1441 } catch (const Exc::Exception &e) {
1442 retCode = e.error();
1443 } catch (const std::exception& e) {
1444 LogError("STD exception " << e.what());
1445 retCode = CKM_API_ERROR_SERVER_ERROR;
1447 LogError("Unknown error.");
1450 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1454 return response.Pop();
1457 RawBuffer CKMLogic::getCertificateChain(
1458 const Credentials &cred,
1460 const RawBuffer &certificate,
1461 const LabelNameVector &untrustedCertificates,
1462 const LabelNameVector &trustedCertificates,
1463 bool useTrustedSystemCertificates)
1465 int retCode = CKM_API_ERROR_UNKNOWN;
1466 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1467 RawBufferVector chainRawVector;
1469 retCode = getCertificateChainHelper(cred,
1471 untrustedCertificates,
1472 trustedCertificates,
1473 useTrustedSystemCertificates,
1475 } catch (const Exc::Exception &e) {
1476 retCode = e.error();
1477 } catch (const std::exception& e) {
1478 LogError("STD exception " << e.what());
1479 retCode = CKM_API_ERROR_SERVER_ERROR;
1481 LogError("Unknown error.");
1484 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1488 return response.Pop();
1491 RawBuffer CKMLogic::createSignature(
1492 const Credentials &cred,
1494 const Name &privateKeyName,
1495 const Label & ownerLabel,
1496 const Password &password, // password for private_key
1497 const RawBuffer &message,
1498 const CryptoAlgorithm &cryptoAlg)
1501 RawBuffer signature;
1503 int retCode = CKM_API_SUCCESS;
1506 Crypto::GObjUPtr obj;
1507 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, obj);
1508 if (retCode == CKM_API_SUCCESS)
1509 signature = obj->sign(cryptoAlg, message);
1510 } catch (const Exc::Exception &e) {
1511 retCode = e.error();
1512 } catch (const CKM::Exception &e) {
1513 LogError("Unknown CKM::Exception: " << e.GetMessage());
1514 retCode = CKM_API_ERROR_SERVER_ERROR;
1515 } catch (const std::exception &e) {
1516 LogError("STD exception " << e.what());
1517 retCode = CKM_API_ERROR_SERVER_ERROR;
1520 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1524 return response.Pop();
1527 RawBuffer CKMLogic::verifySignature(
1528 const Credentials &cred,
1530 const Name &publicKeyOrCertName,
1531 const Label & ownerLabel,
1532 const Password &password, // password for public_key (optional)
1533 const RawBuffer &message,
1534 const RawBuffer &signature,
1535 const CryptoAlgorithm ¶ms)
1537 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1542 // try certificate first - looking for a public key.
1543 // in case of PKCS, pub key from certificate will be found first
1544 // rather than private key from the same PKCS.
1545 Crypto::GObjUPtr obj;
1546 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, obj);
1547 if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1548 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, obj);
1550 if (retCode == CKM_API_SUCCESS)
1551 retCode = obj->verify(params, message, signature);
1552 } catch (const Exc::Exception &e) {
1553 retCode = e.error();
1554 } catch (const CKM::Exception &e) {
1555 LogError("Unknown CKM::Exception: " << e.GetMessage());
1556 retCode = CKM_API_ERROR_SERVER_ERROR;
1559 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1562 return response.Pop();
1565 int CKMLogic::setPermissionHelper(
1566 const Credentials &cred, // who's the client
1568 const Label &label, // who's the owner
1569 const Label &accessorLabel, // who will get the access
1570 const PermissionMask permissionMask)
1572 auto &handler = selectDatabase(cred, label);
1574 // we don't know the client
1575 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1576 return CKM_API_ERROR_INPUT_PARAM;
1578 // use client label if not explicitly provided
1579 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1581 // verify name and label are correct
1582 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1583 return CKM_API_ERROR_INPUT_PARAM;
1585 // currently we don't support modification of owner's permissions to his own rows
1586 if (ownerLabel == accessorLabel)
1587 return CKM_API_ERROR_INPUT_PARAM;
1589 // system database does not support write/remove permissions
1590 if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) &&
1591 (permissionMask & Permission::REMOVE))
1592 return CKM_API_ERROR_INPUT_PARAM;
1594 // can the client modify permissions to owner's row?
1595 int retCode = m_accessControl.canModify(cred, ownerLabel);
1596 if (retCode != CKM_API_SUCCESS)
1599 DB::Crypto::Transaction transaction(&handler.database);
1601 if (!handler.database.isNameLabelPresent(name, ownerLabel))
1602 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1604 // removing non-existing permissions: fail
1605 if (permissionMask == Permission::NONE) {
1606 if (!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1607 return CKM_API_ERROR_INPUT_PARAM;
1610 // set permissions to the row owned by ownerLabel for accessorLabel
1611 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1612 transaction.commit();
1614 return CKM_API_SUCCESS;
1617 RawBuffer CKMLogic::setPermission(
1618 const Credentials &cred,
1623 const Label &accessorLabel,
1624 const PermissionMask permissionMask)
1628 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1629 } catch (const Exc::Exception &e) {
1630 retCode = e.error();
1631 } catch (const CKM::Exception &e) {
1632 LogError("Error: " << e.GetMessage());
1633 retCode = CKM_API_ERROR_DB_ERROR;
1636 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
1639 int CKMLogic::loadAppKey(UserData& handle, const Label& appLabel)
1641 if (!handle.crypto.haveKey(appLabel)) {
1643 auto key_optional = handle.database.getKey(appLabel);
1644 if (!key_optional) {
1645 LogError("No key for given label in database");
1646 return CKM_API_ERROR_DB_ERROR;
1648 key = *key_optional;
1649 key = handle.keyProvider.getPureDEK(key);
1650 handle.crypto.pushKey(appLabel, key);
1652 return CKM_API_SUCCESS;