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)
420 return saveDataHelper(cred, name, label, binaryData, policy);
421 } catch (const Exc::Exception &e) {
423 } catch (const CKM::Exception &e) {
424 LogError("CKM::Exception: " << e.GetMessage());
425 return CKM_API_ERROR_SERVER_ERROR;
429 int CKMLogic::getKeyForService(
430 const Credentials &cred,
433 const Password &pass,
434 Crypto::GObjShPtr &key)
438 // Key is for internal service use. It won't be exported to the client
439 Crypto::GObjUPtr obj;
440 int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, obj);
441 if (retCode == CKM_API_SUCCESS)
442 key = std::move(obj);
444 } catch (const Exc::Exception &e) {
446 } catch (const CKM::Exception &e) {
447 LogError("CKM::Exception: " << e.GetMessage());
448 return CKM_API_ERROR_SERVER_ERROR;
452 RawBuffer CKMLogic::saveData(
453 const Credentials &cred,
457 const Crypto::Data &data,
458 const PolicySerializable &policy)
460 int retCode = verifyAndSaveDataHelper(cred, name, label, data, policy);
461 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
464 static_cast<int>(data.type));
465 return response.Pop();
468 int CKMLogic::extractPKCS12Data(
471 const Label &ownerLabel,
472 const PKCS12Serializable &pkcs,
473 const PolicySerializable &keyPolicy,
474 const PolicySerializable &certPolicy,
475 DB::RowVector &output) const
477 // private key is mandatory
478 auto key = pkcs.getKey();
480 LogError("Failed to get private key from pkcs");
481 return CKM_API_ERROR_INVALID_FORMAT;
484 Crypto::Data keyData(DataType(key->getType()), key->getDER());
485 int retCode = verifyBinaryData(keyData);
486 if (retCode != CKM_API_SUCCESS)
488 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyData, keyPolicy));
490 // certificate is mandatory
491 auto cert = pkcs.getCertificate();
493 LogError("Failed to get certificate from pkcs");
494 return CKM_API_ERROR_INVALID_FORMAT;
496 Crypto::Data certData(DataType::CERTIFICATE, cert->getDER());
497 retCode = verifyBinaryData(certData);
498 if (retCode != CKM_API_SUCCESS)
500 output.push_back(createEncryptedRow(crypto, name, ownerLabel, certData, certPolicy));
503 unsigned int cert_index = 0;
504 for (const auto & ca : pkcs.getCaCertificateShPtrVector()) {
505 Crypto::Data caCertData(DataType::getChainDatatype(cert_index ++), ca->getDER());
506 int retCode = verifyBinaryData(caCertData);
507 if (retCode != CKM_API_SUCCESS)
510 output.push_back(createEncryptedRow(crypto, name, ownerLabel, caCertData, certPolicy));
513 return CKM_API_SUCCESS;
516 RawBuffer CKMLogic::savePKCS12(
517 const Credentials &cred,
521 const PKCS12Serializable &pkcs,
522 const PolicySerializable &keyPolicy,
523 const PolicySerializable &certPolicy)
525 int retCode = CKM_API_ERROR_UNKNOWN;
527 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
528 } catch (const Exc::Exception &e) {
530 } catch (const CKM::Exception &e) {
531 LogError("CKM::Exception: " << e.GetMessage());
532 retCode = CKM_API_ERROR_SERVER_ERROR;
535 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
538 return response.Pop();
542 int CKMLogic::removeDataHelper(
543 const Credentials &cred,
547 auto &handler = selectDatabase(cred, label);
549 // use client label if not explicitly provided
550 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
551 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
552 LogDebug("Invalid label or name format");
553 return CKM_API_ERROR_INPUT_PARAM;
556 DB::Crypto::Transaction transaction(&handler.database);
558 // read and check permissions
559 PermissionMaskOptional permissionRowOpt =
560 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
561 int retCode = m_accessControl.canDelete(cred,
562 PermissionForLabel(cred.smackLabel, permissionRowOpt));
563 if (retCode != CKM_API_SUCCESS) {
564 LogWarning("access control check result: " << retCode);
568 // get all matching rows
570 handler.database.getRows(name, ownerLabel, DataType::DB_FIRST, DataType::DB_LAST, rows);
572 LogDebug("No row for given name and label");
573 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
576 // load app key if needed
577 retCode = loadAppKey(handler, rows.front().ownerLabel);
578 if (CKM_API_SUCCESS != retCode)
581 // destroy it in store
582 for (auto& r : rows) {
584 handler.crypto.decryptRow(Password(), r);
585 m_decider.getStore(r).destroy(r);
586 } catch (const Exc::AuthenticationFailed&) {
587 LogDebug("Authentication failed when removing data. Ignored.");
592 handler.database.deleteRow(name, ownerLabel);
593 transaction.commit();
595 return CKM_API_SUCCESS;
598 RawBuffer CKMLogic::removeData(
599 const Credentials &cred,
604 int retCode = CKM_API_ERROR_UNKNOWN;
607 retCode = removeDataHelper(cred, name, label);
608 } catch (const Exc::Exception &e) {
610 } catch (const CKM::Exception &e) {
611 LogError("Error: " << e.GetMessage());
612 retCode = CKM_API_ERROR_DB_ERROR;
615 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
618 return response.Pop();
621 int CKMLogic::readSingleRow(const Name &name,
622 const Label &ownerLabel,
624 DB::Crypto & database,
627 DB::Crypto::RowOptional row_optional;
628 if (dataType.isKey()) {
629 // read all key types
630 row_optional = database.getRow(name,
632 DataType::DB_KEY_FIRST,
633 DataType::DB_KEY_LAST);
635 // read anything else
636 row_optional = database.getRow(name,
642 LogDebug("No row for given name, label and type");
643 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
648 return CKM_API_SUCCESS;
652 int CKMLogic::readMultiRow(const Name &name,
653 const Label &ownerLabel,
655 DB::Crypto & database,
656 DB::RowVector &output)
658 if (dataType.isKey())
659 // read all key types
660 database.getRows(name,
662 DataType::DB_KEY_FIRST,
663 DataType::DB_KEY_LAST,
665 else if (dataType.isChainCert())
666 // read all key types
667 database.getRows(name,
669 DataType::DB_CHAIN_FIRST,
670 DataType::DB_CHAIN_LAST,
673 // read anything else
674 database.getRows(name,
679 if (!output.size()) {
680 LogDebug("No row for given name, label and type");
681 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
684 return CKM_API_SUCCESS;
687 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
689 const Label &ownerLabel,
690 const Label &accessorLabel,
693 DB::Crypto & database)
695 PermissionMaskOptional permissionRowOpt =
696 database.getPermissionRow(name, ownerLabel, accessorLabel);
699 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
700 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
703 Crypto::GObjUPtr CKMLogic::rowToObject(
706 const Password& password)
708 Crypto::GStore& store = m_decider.getStore(row);
710 Password pass = m_accessControl.isCCMode() ? "" : password;
713 Crypto::GObjUPtr obj;
714 if (CryptoLogic::getSchemeVersion(row.encryptionScheme) == CryptoLogic::ENCRYPTION_V2) {
715 handler.crypto.decryptRow(Password(), row);
717 obj = store.getObject(row, pass);
719 // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data
720 handler.crypto.decryptRow(pass, row);
721 // destroy it in store
724 // import it to store with new scheme: data -> pass(data)
725 Token token = store.import(Crypto::Data(row.dataType, row.data), pass);
727 // get it from the store (it can be different than the data we imported into store)
728 obj = store.getObject(token, pass);
730 // update row with new token
731 *static_cast<Token*>(&row) = std::move(token);
733 // encrypt it with app key: pass(data) -> b64(appkey(pass(data))
734 handler.crypto.encryptRow(row);
737 handler.database.updateRow(row);
742 int CKMLogic::readDataHelper(
744 const Credentials &cred,
748 const Password &password,
749 Crypto::GObjUPtrVector &objs)
751 auto &handler = selectDatabase(cred, label);
753 // use client label if not explicitly provided
754 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
756 if (!isNameValid(name) || !isLabelValid(ownerLabel))
757 return CKM_API_ERROR_INPUT_PARAM;
760 DB::Crypto::Transaction transaction(&handler.database);
762 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
763 if (CKM_API_SUCCESS != retCode)
766 // all read rows belong to the same owner
767 DB::Row & firstRow = rows.at(0);
769 // check access rights
770 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
771 if (CKM_API_SUCCESS != retCode)
774 // load app key if needed
775 retCode = loadAppKey(handler, firstRow.ownerLabel);
776 if (CKM_API_SUCCESS != retCode)
780 for (auto &row : rows)
781 objs.push_back(rowToObject(handler, std::move(row), password));
782 // rowToObject may modify db
783 transaction.commit();
785 return CKM_API_SUCCESS;
788 int CKMLogic::readDataHelper(
790 const Credentials &cred,
794 const Password &password,
795 Crypto::GObjUPtr &obj)
797 DataType objDataType;
798 return readDataHelper(exportFlag, cred, dataType, name, label, password, obj, objDataType);
801 int CKMLogic::readDataHelper(
803 const Credentials &cred,
807 const Password &password,
808 Crypto::GObjUPtr &obj,
809 DataType& objDataType)
811 auto &handler = selectDatabase(cred, label);
813 // use client label if not explicitly provided
814 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
816 if (!isNameValid(name) || !isLabelValid(ownerLabel))
817 return CKM_API_ERROR_INPUT_PARAM;
820 DB::Crypto::Transaction transaction(&handler.database);
822 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
823 if (CKM_API_SUCCESS != retCode)
826 objDataType = row.dataType;
828 // check access rights
829 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
830 if (CKM_API_SUCCESS != retCode)
833 // load app key if needed
834 retCode = loadAppKey(handler, row.ownerLabel);
835 if (CKM_API_SUCCESS != retCode)
838 obj = rowToObject(handler, std::move(row), password);
839 // rowToObject may modify db
840 transaction.commit();
842 return CKM_API_SUCCESS;
845 RawBuffer CKMLogic::getData(
846 const Credentials &cred,
851 const Password &password)
853 int retCode = CKM_API_SUCCESS;
855 DataType objDataType;
858 Crypto::GObjUPtr obj;
859 retCode = readDataHelper(true, cred, dataType, name, label, password, obj, objDataType);
860 if (retCode == CKM_API_SUCCESS)
861 row.data = std::move(obj->getBinary());
862 } catch (const Exc::Exception &e) {
864 } catch (const CKM::Exception &e) {
865 LogError("CKM::Exception: " << e.GetMessage());
866 retCode = CKM_API_ERROR_SERVER_ERROR;
869 if (CKM_API_SUCCESS != retCode) {
871 row.dataType = dataType;
874 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
877 static_cast<int>(objDataType),
879 return response.Pop();
882 int CKMLogic::getPKCS12Helper(
883 const Credentials &cred,
886 const Password &keyPassword,
887 const Password &certPassword,
889 CertificateShPtr & cert,
890 CertificateShPtrVector & caChain)
894 // read private key (mandatory)
895 Crypto::GObjUPtr keyObj;
896 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, keyObj);
897 if (retCode != CKM_API_SUCCESS)
899 privKey = CKM::Key::create(keyObj->getBinary());
901 // read certificate (mandatory)
902 Crypto::GObjUPtr certObj;
903 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certObj);
904 if (retCode != CKM_API_SUCCESS)
906 cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER);
908 // read CA cert chain (optional)
909 Crypto::GObjUPtrVector caChainObjs;
910 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, caChainObjs);
911 if (retCode != CKM_API_SUCCESS &&
912 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
914 for (auto &caCertObj : caChainObjs)
915 caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(), DataFormat::FORM_DER));
917 // if anything found, return it
918 if (privKey || cert || caChain.size() > 0)
919 retCode = CKM_API_SUCCESS;
924 RawBuffer CKMLogic::getPKCS12(
925 const Credentials &cred,
929 const Password &keyPassword,
930 const Password &certPassword)
932 int retCode = CKM_API_ERROR_UNKNOWN;
934 PKCS12Serializable output;
937 CertificateShPtr cert;
938 CertificateShPtrVector caChain;
939 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
942 if (retCode == CKM_API_SUCCESS)
943 output = PKCS12Serializable(std::move(privKey), std::move(cert), std::move(caChain));
944 } catch (const Exc::Exception &e) {
946 } catch (const CKM::Exception &e) {
947 LogError("CKM::Exception: " << e.GetMessage());
948 retCode = CKM_API_ERROR_SERVER_ERROR;
951 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
955 return response.Pop();
958 int CKMLogic::getDataListHelper(const Credentials &cred,
959 const DataType dataType,
960 LabelNameVector &labelNameVector)
962 int retCode = CKM_API_ERROR_DB_LOCKED;
963 if (0 < m_userDataMap.count(cred.clientUid)) {
964 auto &database = m_userDataMap[cred.clientUid].database;
967 LabelNameVector tmpVector;
968 if (dataType.isKey()) {
969 // list all key types
970 database.listNames(cred.smackLabel,
972 DataType::DB_KEY_FIRST,
973 DataType::DB_KEY_LAST);
975 // list anything else
976 database.listNames(cred.smackLabel,
980 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
981 retCode = CKM_API_SUCCESS;
982 } catch (const CKM::Exception &e) {
983 LogError("Error: " << e.GetMessage());
984 retCode = CKM_API_ERROR_DB_ERROR;
985 } catch (const Exc::Exception &e) {
992 RawBuffer CKMLogic::getDataList(
993 const Credentials &cred,
997 LabelNameVector systemVector;
998 LabelNameVector userVector;
999 LabelNameVector labelNameVector;
1001 int retCode = unlockSystemDB();
1002 if (CKM_API_SUCCESS == retCode) {
1004 if (m_accessControl.isSystemService(cred)) {
1006 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1011 // user - lookup system, then client DB
1012 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1018 if (retCode == CKM_API_SUCCESS) {
1019 retCode = getDataListHelper(cred,
1026 if (retCode == CKM_API_SUCCESS) {
1027 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1028 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1031 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1034 static_cast<int>(dataType),
1036 return response.Pop();
1039 int CKMLogic::importInitialData(
1041 const Crypto::Data &data,
1042 const Crypto::DataEncryption &enc,
1043 const Policy &policy)
1046 // Inital values are always imported with root credentials. Label is not important.
1047 Credentials rootCred(0, "");
1049 auto &handler = selectDatabase(rootCred, OWNER_ID_SYSTEM);
1051 // check if save is possible
1052 DB::Crypto::Transaction transaction(&handler.database);
1053 int retCode = checkSaveConditions(rootCred, handler, name, OWNER_ID_SYSTEM);
1054 if (retCode != CKM_API_SUCCESS)
1057 Crypto::GStore& store =
1058 m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty());
1062 if (enc.encryptedKey.empty()) {
1063 Crypto::Data binaryData;
1064 if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData)))
1066 token = store.import(binaryData, m_accessControl.isCCMode() ? "" : policy.password);
1068 token = store.importEncrypted(data, m_accessControl.isCCMode() ? "" : policy.password, enc);
1071 DB::Row row(std::move(token), name, OWNER_ID_SYSTEM, static_cast<int>(policy.extractable));
1072 handler.crypto.encryptRow(row);
1074 handler.database.saveRow(row);
1075 transaction.commit();
1076 } catch (const Exc::Exception &e) {
1078 } catch (const CKM::Exception &e) {
1079 LogError("CKM::Exception: " << e.GetMessage());
1080 return CKM_API_ERROR_SERVER_ERROR;
1081 } catch (const std::exception &e) {
1082 LogError("Std::exception: " << e.what());
1083 return CKM_API_ERROR_SERVER_ERROR;
1086 return CKM_API_SUCCESS;
1089 int CKMLogic::saveDataHelper(
1090 const Credentials &cred,
1093 const Crypto::Data &data,
1094 const PolicySerializable &policy)
1096 auto &handler = selectDatabase(cred, label);
1098 // use client label if not explicitly provided
1099 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1100 if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1101 return CKM_API_ERROR_INPUT_PARAM;
1103 // check if save is possible
1104 DB::Crypto::Transaction transaction(&handler.database);
1105 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1106 if (retCode != CKM_API_SUCCESS)
1110 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, data, policy);
1111 handler.database.saveRow(encryptedRow);
1113 transaction.commit();
1114 return CKM_API_SUCCESS;
1117 int CKMLogic::saveDataHelper(
1118 const Credentials &cred,
1121 const PKCS12Serializable &pkcs,
1122 const PolicySerializable &keyPolicy,
1123 const PolicySerializable &certPolicy)
1125 auto &handler = selectDatabase(cred, label);
1127 // use client label if not explicitly provided
1128 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1129 if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1130 return CKM_API_ERROR_INPUT_PARAM;
1132 // check if save is possible
1133 DB::Crypto::Transaction transaction(&handler.database);
1134 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1135 if (retCode != CKM_API_SUCCESS)
1138 // extract and encrypt the data
1139 DB::RowVector encryptedRows;
1140 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1141 if (retCode != CKM_API_SUCCESS)
1145 handler.database.saveRows(name, ownerLabel, encryptedRows);
1146 transaction.commit();
1148 return CKM_API_SUCCESS;
1152 int CKMLogic::createKeyAESHelper(
1153 const Credentials &cred,
1157 const PolicySerializable &policy)
1159 auto &handler = selectDatabase(cred, label);
1161 // use client label if not explicitly provided
1162 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1163 if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0)
1164 return CKM_API_ERROR_INPUT_PARAM;
1166 // check if save is possible
1167 DB::Crypto::Transaction transaction(&handler.database);
1168 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1169 if (retCode != CKM_API_SUCCESS)
1172 // create key in store
1173 CryptoAlgorithm keyGenAlgorithm;
1174 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
1175 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
1176 Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm, policy.password);
1179 DB::Row row(std::move(key), name, ownerLabel, static_cast<int>(policy.extractable));
1180 handler.crypto.encryptRow(row);
1182 handler.database.saveRow(row);
1184 transaction.commit();
1185 return CKM_API_SUCCESS;
1188 int CKMLogic::createKeyPairHelper(
1189 const Credentials &cred,
1190 const CryptoAlgorithmSerializable & keyGenParams,
1191 const Name &namePrivate,
1192 const Label &labelPrivate,
1193 const Name &namePublic,
1194 const Label &labelPublic,
1195 const PolicySerializable &policyPrivate,
1196 const PolicySerializable &policyPublic)
1198 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1199 auto &handlerPub = selectDatabase(cred, labelPublic);
1201 AlgoType keyType = AlgoType::RSA_GEN;
1202 if (!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType))
1203 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found.");
1205 DataType dt(keyType);
1207 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
1209 // use client label if not explicitly provided
1210 const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel : labelPrivate;
1211 if (m_accessControl.isSystemService(cred) && ownerLabelPrv.compare(OWNER_ID_SYSTEM) != 0)
1212 return CKM_API_ERROR_INPUT_PARAM;
1214 const Label &ownerLabelPub = labelPublic.empty() ? cred.smackLabel : labelPublic;
1215 if (m_accessControl.isSystemService(cred) && ownerLabelPub.compare(OWNER_ID_SYSTEM) != 0)
1216 return CKM_API_ERROR_INPUT_PARAM;
1218 bool exportable = policyPrivate.extractable || policyPublic.extractable;
1219 TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams,
1220 policyPrivate.password,
1221 policyPublic.password);
1223 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1224 // in case the same database is used for private and public - the second
1225 // transaction will not be executed
1226 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1229 retCode = checkSaveConditions(cred, handlerPriv, namePrivate, ownerLabelPrv);
1230 if (CKM_API_SUCCESS != retCode)
1233 retCode = checkSaveConditions(cred, handlerPub, namePublic, ownerLabelPub);
1234 if (CKM_API_SUCCESS != retCode)
1238 DB::Row rowPrv(std::move(keys.first), namePrivate, ownerLabelPrv, static_cast<int>(policyPrivate.extractable));
1239 handlerPriv.crypto.encryptRow(rowPrv);
1240 handlerPriv.database.saveRow(rowPrv);
1242 DB::Row rowPub(std::move(keys.second), namePublic, ownerLabelPub, static_cast<int>(policyPublic.extractable));
1243 handlerPub.crypto.encryptRow(rowPub);
1244 handlerPub.database.saveRow(rowPub);
1246 transactionPub.commit();
1247 transactionPriv.commit();
1248 return CKM_API_SUCCESS;
1251 RawBuffer CKMLogic::createKeyPair(
1252 const Credentials &cred,
1254 const CryptoAlgorithmSerializable & keyGenParams,
1255 const Name &namePrivate,
1256 const Label &labelPrivate,
1257 const Name &namePublic,
1258 const Label &labelPublic,
1259 const PolicySerializable &policyPrivate,
1260 const PolicySerializable &policyPublic)
1262 int retCode = CKM_API_SUCCESS;
1265 retCode = createKeyPairHelper(
1274 } catch(const Exc::Exception &e) {
1275 retCode = e.error();
1276 } catch (const CKM::Exception &e) {
1277 LogError("CKM::Exception: " << e.GetMessage());
1278 retCode = CKM_API_ERROR_SERVER_ERROR;
1281 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR),
1282 commandId, retCode).Pop();
1285 RawBuffer CKMLogic::createKeyAES(
1286 const Credentials &cred,
1291 const PolicySerializable &policy)
1293 int retCode = CKM_API_SUCCESS;
1296 retCode = createKeyAESHelper(cred, size, name, label, policy);
1297 } catch (const Exc::Exception &e) {
1298 retCode = e.error();
1299 } catch (std::invalid_argument &e) {
1300 LogDebug("invalid argument error: " << e.what());
1301 retCode = CKM_API_ERROR_INPUT_PARAM;
1302 } catch (const CKM::Exception &e) {
1303 LogError("CKM::Exception: " << e.GetMessage());
1304 retCode = CKM_API_ERROR_SERVER_ERROR;
1307 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES),
1308 commandId, retCode).Pop();
1311 int CKMLogic::readCertificateHelper(
1312 const Credentials &cred,
1313 const LabelNameVector &labelNameVector,
1314 CertificateImplVector &certVector)
1317 for (auto &i: labelNameVector) {
1318 // certificates can't be protected with custom user password
1319 Crypto::GObjUPtr obj;
1321 ec = readDataHelper(true,
1323 DataType::CERTIFICATE,
1328 if (ec != CKM_API_SUCCESS)
1331 certVector.emplace_back(obj->getBinary(), DataFormat::FORM_DER);
1333 // try to read chain certificates (if present)
1334 Crypto::GObjUPtrVector caChainObjs;
1335 ec = readDataHelper(true,
1337 DataType::DB_CHAIN_FIRST,
1342 if (ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1344 for (auto &caCertObj : caChainObjs)
1345 certVector.emplace_back(caCertObj->getBinary(), DataFormat::FORM_DER);
1347 return CKM_API_SUCCESS;
1350 int CKMLogic::getCertificateChainHelper(
1351 const CertificateImpl &cert,
1352 const RawBufferVector &untrustedCertificates,
1353 const RawBufferVector &trustedCertificates,
1354 bool useTrustedSystemCertificates,
1355 RawBufferVector &chainRawVector)
1357 CertificateImplVector untrustedCertVector;
1358 CertificateImplVector trustedCertVector;
1359 CertificateImplVector chainVector;
1362 return CKM_API_ERROR_INPUT_PARAM;
1364 for (auto &e: untrustedCertificates) {
1365 CertificateImpl c(e, DataFormat::FORM_DER);
1367 return CKM_API_ERROR_INPUT_PARAM;
1368 untrustedCertVector.push_back(std::move(c));
1370 for (auto &e: trustedCertificates) {
1371 CertificateImpl c(e, DataFormat::FORM_DER);
1373 return CKM_API_ERROR_INPUT_PARAM;
1374 trustedCertVector.push_back(std::move(c));
1377 CertificateStore store;
1378 int retCode = store.verifyCertificate(cert,
1379 untrustedCertVector,
1381 useTrustedSystemCertificates,
1382 m_accessControl.isCCMode(),
1384 if (retCode != CKM_API_SUCCESS)
1387 for (auto &e : chainVector)
1388 chainRawVector.push_back(e.getDER());
1389 return CKM_API_SUCCESS;
1392 int CKMLogic::getCertificateChainHelper(
1393 const Credentials &cred,
1394 const CertificateImpl &cert,
1395 const LabelNameVector &untrusted,
1396 const LabelNameVector &trusted,
1397 bool useTrustedSystemCertificates,
1398 RawBufferVector &chainRawVector)
1400 CertificateImplVector untrustedCertVector;
1401 CertificateImplVector trustedCertVector;
1402 CertificateImplVector chainVector;
1406 return CKM_API_ERROR_INPUT_PARAM;
1408 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1409 if (retCode != CKM_API_SUCCESS)
1411 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1412 if (retCode != CKM_API_SUCCESS)
1415 CertificateStore store;
1416 retCode = store.verifyCertificate(cert,
1417 untrustedCertVector,
1419 useTrustedSystemCertificates,
1420 m_accessControl.isCCMode(),
1422 if (retCode != CKM_API_SUCCESS)
1425 for (auto &i: chainVector)
1426 chainRawVector.push_back(i.getDER());
1428 return CKM_API_SUCCESS;
1431 RawBuffer CKMLogic::getCertificateChain(
1432 const Credentials & /*cred*/,
1434 const RawBuffer &certificate,
1435 const RawBufferVector &untrustedCertificates,
1436 const RawBufferVector &trustedCertificates,
1437 bool useTrustedSystemCertificates)
1439 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1440 RawBufferVector chainRawVector;
1441 int retCode = CKM_API_ERROR_UNKNOWN;
1443 retCode = getCertificateChainHelper(cert,
1444 untrustedCertificates,
1445 trustedCertificates,
1446 useTrustedSystemCertificates,
1448 } catch (const Exc::Exception &e) {
1449 retCode = e.error();
1450 } catch (const std::exception& e) {
1451 LogError("STD exception " << e.what());
1452 retCode = CKM_API_ERROR_SERVER_ERROR;
1454 LogError("Unknown error.");
1457 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1461 return response.Pop();
1464 RawBuffer CKMLogic::getCertificateChain(
1465 const Credentials &cred,
1467 const RawBuffer &certificate,
1468 const LabelNameVector &untrustedCertificates,
1469 const LabelNameVector &trustedCertificates,
1470 bool useTrustedSystemCertificates)
1472 int retCode = CKM_API_ERROR_UNKNOWN;
1473 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1474 RawBufferVector chainRawVector;
1476 retCode = getCertificateChainHelper(cred,
1478 untrustedCertificates,
1479 trustedCertificates,
1480 useTrustedSystemCertificates,
1482 } catch (const Exc::Exception &e) {
1483 retCode = e.error();
1484 } catch (const std::exception& e) {
1485 LogError("STD exception " << e.what());
1486 retCode = CKM_API_ERROR_SERVER_ERROR;
1488 LogError("Unknown error.");
1491 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1495 return response.Pop();
1498 RawBuffer CKMLogic::createSignature(
1499 const Credentials &cred,
1501 const Name &privateKeyName,
1502 const Label & ownerLabel,
1503 const Password &password, // password for private_key
1504 const RawBuffer &message,
1505 const CryptoAlgorithm &cryptoAlg)
1508 RawBuffer signature;
1510 int retCode = CKM_API_SUCCESS;
1513 Crypto::GObjUPtr obj;
1514 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, obj);
1515 if (retCode == CKM_API_SUCCESS)
1516 signature = obj->sign(cryptoAlg, message);
1517 } catch (const Exc::Exception &e) {
1518 retCode = e.error();
1519 } catch (const CKM::Exception &e) {
1520 LogError("Unknown CKM::Exception: " << e.GetMessage());
1521 retCode = CKM_API_ERROR_SERVER_ERROR;
1522 } catch (const std::exception &e) {
1523 LogError("STD exception " << e.what());
1524 retCode = CKM_API_ERROR_SERVER_ERROR;
1527 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1531 return response.Pop();
1534 RawBuffer CKMLogic::verifySignature(
1535 const Credentials &cred,
1537 const Name &publicKeyOrCertName,
1538 const Label & ownerLabel,
1539 const Password &password, // password for public_key (optional)
1540 const RawBuffer &message,
1541 const RawBuffer &signature,
1542 const CryptoAlgorithm ¶ms)
1544 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1549 // try certificate first - looking for a public key.
1550 // in case of PKCS, pub key from certificate will be found first
1551 // rather than private key from the same PKCS.
1552 Crypto::GObjUPtr obj;
1553 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, obj);
1554 if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1555 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, obj);
1557 if (retCode == CKM_API_SUCCESS)
1558 retCode = obj->verify(params, message, signature);
1559 } catch (const Exc::Exception &e) {
1560 retCode = e.error();
1561 } catch (const CKM::Exception &e) {
1562 LogError("Unknown CKM::Exception: " << e.GetMessage());
1563 retCode = CKM_API_ERROR_SERVER_ERROR;
1566 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1569 return response.Pop();
1572 int CKMLogic::setPermissionHelper(
1573 const Credentials &cred, // who's the client
1575 const Label &label, // who's the owner
1576 const Label &accessorLabel, // who will get the access
1577 const PermissionMask permissionMask)
1579 auto &handler = selectDatabase(cred, label);
1581 // we don't know the client
1582 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1583 return CKM_API_ERROR_INPUT_PARAM;
1585 // use client label if not explicitly provided
1586 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1588 // verify name and label are correct
1589 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1590 return CKM_API_ERROR_INPUT_PARAM;
1592 // currently we don't support modification of owner's permissions to his own rows
1593 if (ownerLabel == accessorLabel)
1594 return CKM_API_ERROR_INPUT_PARAM;
1596 // system database does not support write/remove permissions
1597 if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) &&
1598 (permissionMask & Permission::REMOVE))
1599 return CKM_API_ERROR_INPUT_PARAM;
1601 // can the client modify permissions to owner's row?
1602 int retCode = m_accessControl.canModify(cred, ownerLabel);
1603 if (retCode != CKM_API_SUCCESS)
1606 DB::Crypto::Transaction transaction(&handler.database);
1608 if (!handler.database.isNameLabelPresent(name, ownerLabel))
1609 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1611 // removing non-existing permissions: fail
1612 if (permissionMask == Permission::NONE) {
1613 if (!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1614 return CKM_API_ERROR_INPUT_PARAM;
1617 // set permissions to the row owned by ownerLabel for accessorLabel
1618 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1619 transaction.commit();
1621 return CKM_API_SUCCESS;
1624 RawBuffer CKMLogic::setPermission(
1625 const Credentials &cred,
1630 const Label &accessorLabel,
1631 const PermissionMask permissionMask)
1635 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1636 } catch (const Exc::Exception &e) {
1637 retCode = e.error();
1638 } catch (const CKM::Exception &e) {
1639 LogError("Error: " << e.GetMessage());
1640 retCode = CKM_API_ERROR_DB_ERROR;
1643 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
1646 int CKMLogic::loadAppKey(UserData& handle, const Label& appLabel)
1648 if (!handle.crypto.haveKey(appLabel)) {
1650 auto key_optional = handle.database.getKey(appLabel);
1651 if (!key_optional) {
1652 LogError("No key for given label in database");
1653 return CKM_API_ERROR_DB_ERROR;
1655 key = *key_optional;
1656 key = handle.keyProvider.getPureDEK(key);
1657 handle.crypto.pushKey(appLabel, key);
1659 return CKM_API_SUCCESS;