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 = "/etc/ssl/certs";
39 const char * const SYSTEM_DB_PASSWD = "cAtRugU7";
41 bool isLabelValid(const CKM::Label &label) {
42 // TODO: copy code from libprivilege control (for check smack label)
43 if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
48 bool isNameValid(const CKM::Name &name) {
49 if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
53 } // anonymous namespace
57 const uid_t CKMLogic::SYSTEM_DB_UID = 0;
61 CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
63 m_accessControl.updateCCMode();
66 CKMLogic::~CKMLogic(){}
68 void CKMLogic::loadDKEKFile(uid_t user, const Password &password) {
69 auto &handle = m_userDataMap[user];
73 auto wrappedDKEK = fs.getDKEK();
75 if (wrappedDKEK.empty()) {
76 wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
77 fs.saveDKEK(wrappedDKEK);
80 handle.keyProvider = KeyProvider(wrappedDKEK, password);
83 void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
84 auto &handle = m_userDataMap[user];
87 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
90 int CKMLogic::unlockDatabase(uid_t user, const Password & password)
92 if (0<m_userDataMap.count(user) && m_userDataMap[user].keyProvider.isInitialized())
93 return CKM_API_SUCCESS;
95 int retCode = CKM_API_SUCCESS;
98 auto &handle = m_userDataMap[user];
101 loadDKEKFile(user, password);
103 auto wrappedDatabaseDEK = fs.getDBDEK();
104 if (wrappedDatabaseDEK.empty()) {
105 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
106 fs.saveDBDEK(wrappedDatabaseDEK);
109 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
111 handle.database = DB::Crypto(fs.getDBPath(), key);
112 handle.crypto = CryptoLogic();
114 if ( !m_accessControl.isSystemService(user) )
116 // remove data of removed apps during locked state
117 AppLabelVector removedApps = fs.clearRemovedsApps();
118 for(auto& appSmackLabel : removedApps) {
119 handle.crypto.removeKey(appSmackLabel);
120 handle.database.deleteKey(appSmackLabel);
123 } catch (const Exc::Exception &e) {
125 } catch (const CKM::Exception &e) {
126 LogError("CKM::Exception: " << e.GetMessage());
127 retCode = CKM_API_ERROR_SERVER_ERROR;
130 if (CKM_API_SUCCESS != retCode)
131 m_userDataMap.erase(user);
136 int CKMLogic::unlockSystemDB()
138 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
141 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
143 // if user trying to access system service - check:
144 // * if user database is unlocked [mandatory]
145 // * if not - proceed with regular user database
146 // * if explicit system database label given -> switch to system DB
147 if ( !m_accessControl.isSystemService(cred) )
149 if (0 == m_userDataMap.count(cred.clientUid))
150 ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked");
152 if (0 != incoming_label.compare(OWNER_ID_SYSTEM))
153 return m_userDataMap[cred.clientUid];
156 // system database selected, modify the label
157 if (CKM_API_SUCCESS != unlockSystemDB() )
158 ThrowErr(Exc::DatabaseLocked, "can not unlock system database");
159 return m_userDataMap[SYSTEM_DB_UID];
162 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
164 int retCode = CKM_API_SUCCESS;
166 if( !m_accessControl.isSystemService(user) )
168 retCode = unlockDatabase(user, password);
172 // do not allow lock/unlock operations for system users
173 retCode = CKM_API_ERROR_INPUT_PARAM;
176 return MessageBuffer::Serialize(retCode).Pop();
179 RawBuffer CKMLogic::updateCCMode() {
180 m_accessControl.updateCCMode();
181 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
184 RawBuffer CKMLogic::lockUserKey(uid_t user)
186 int retCode = CKM_API_SUCCESS;
187 if( !m_accessControl.isSystemService(user) )
189 m_userDataMap.erase(user);
193 // do not allow lock/unlock operations for system users
194 retCode = CKM_API_ERROR_INPUT_PARAM;
197 return MessageBuffer::Serialize(retCode).Pop();
201 RawBuffer CKMLogic::removeUserData(uid_t user) {
202 int retCode = CKM_API_SUCCESS;
204 if (m_accessControl.isSystemService(user))
205 user = SYSTEM_DB_UID;
207 m_userDataMap.erase(user);
212 return MessageBuffer::Serialize(retCode).Pop();
215 int CKMLogic::changeUserPasswordHelper(uid_t user,
216 const Password &oldPassword,
217 const Password &newPassword)
219 // do not allow to change system database password
220 if( m_accessControl.isSystemService(user) )
221 return CKM_API_ERROR_INPUT_PARAM;
223 loadDKEKFile(user, oldPassword);
224 saveDKEKFile(user, newPassword);
226 return CKM_API_SUCCESS;
229 RawBuffer CKMLogic::changeUserPassword(
231 const Password &oldPassword,
232 const Password &newPassword)
234 int retCode = CKM_API_SUCCESS;
237 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
238 } catch (const Exc::Exception &e) {
240 } catch (const CKM::Exception &e) {
241 LogError("CKM::Exception: " << e.GetMessage());
242 retCode = CKM_API_ERROR_SERVER_ERROR;
245 return MessageBuffer::Serialize(retCode).Pop();
248 int CKMLogic::resetUserPasswordHelper(
250 const Password &newPassword)
252 // do not allow to reset system database password
253 if( m_accessControl.isSystemService(user) )
254 return CKM_API_ERROR_INPUT_PARAM;
256 int retCode = CKM_API_SUCCESS;
257 if (0 == m_userDataMap.count(user))
259 // Check if key exists. If exists we must return error
261 auto wrappedDKEKMain = fs.getDKEK();
262 if (!wrappedDKEKMain.empty())
263 retCode = CKM_API_ERROR_BAD_REQUEST;
265 saveDKEKFile(user, newPassword);
271 RawBuffer CKMLogic::resetUserPassword(
273 const Password &newPassword)
275 int retCode = CKM_API_SUCCESS;
277 retCode = resetUserPasswordHelper(user, newPassword);
278 } catch (const Exc::Exception &e) {
280 } catch (const CKM::Exception &e) {
281 LogError("CKM::Exception: " << e.GetMessage());
282 retCode = CKM_API_ERROR_SERVER_ERROR;
285 return MessageBuffer::Serialize(retCode).Pop();
288 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
289 int retCode = CKM_API_SUCCESS;
293 if (smackLabel.empty()) {
294 retCode = CKM_API_ERROR_INPUT_PARAM;
296 UidVector uids = FileSystem::getUIDsFromDBFile();
297 for (auto userId : uids) {
298 if (0 == m_userDataMap.count(userId)) {
299 FileSystem fs(userId);
300 fs.addRemovedApp(smackLabel);
302 auto &handle = m_userDataMap[userId];
303 handle.crypto.removeKey(smackLabel);
304 handle.database.deleteKey(smackLabel);
309 } catch (const Exc::Exception &e) {
311 } catch (const CKM::Exception &e) {
312 LogError("CKM::Exception: " << e.GetMessage());
313 retCode = CKM_API_ERROR_SERVER_ERROR;
316 return MessageBuffer::Serialize(retCode).Pop();
319 int CKMLogic::checkSaveConditions(
320 const Credentials &cred,
323 const Label &ownerLabel)
325 // verify name and label are correct
326 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
327 LogDebug("Invalid parameter passed to key-manager");
328 return CKM_API_ERROR_INPUT_PARAM;
331 // check if allowed to save using ownerLabel
332 int access_ec = m_accessControl.canSave(cred, ownerLabel);
333 if( access_ec != CKM_API_SUCCESS)
335 LogDebug("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
339 // check if not a duplicate
340 if( handler.database.isNameLabelPresent(name, ownerLabel))
341 return CKM_API_ERROR_DB_ALIAS_EXISTS;
343 // encryption section
344 if (!handler.crypto.haveKey(ownerLabel))
347 auto key_optional = handler.database.getKey(ownerLabel);
349 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
350 got_key = handler.keyProvider.generateDEK(ownerLabel);
351 handler.database.saveKey(ownerLabel, got_key);
353 LogDebug("Key from DB");
354 got_key = *key_optional;
357 got_key = handler.keyProvider.getPureDEK(got_key);
358 handler.crypto.pushKey(ownerLabel, got_key);
361 return CKM_API_SUCCESS;
364 DB::Row CKMLogic::createEncryptedRow(
368 const Crypto::Data &data,
369 const Policy &policy) const
371 Crypto::GStore& store = m_decider.getStore(data.type, policy.extractable);
373 // do not encrypt data with password during cc_mode on
374 Token token = store.import(data, m_accessControl.isCCMode() ? "" : policy.password);
375 DB::Row row(std::move(token), name, label, static_cast<int>(policy.extractable));
376 crypto.encryptRow(row);
380 int CKMLogic::verifyBinaryData(Crypto::Data &input) const
383 return toBinaryData(input, dummy);
386 int CKMLogic::toBinaryData(const Crypto::Data &input, Crypto::Data &output) const
388 // verify the data integrity
389 if (input.type.isKey())
392 if(input.type.isSKey())
393 output_key = CKM::Key::createAES(input.data);
395 output_key = CKM::Key::create(input.data);
396 if(output_key.get() == NULL)
398 LogDebug("provided binary data is not valid key data");
399 return CKM_API_ERROR_INPUT_PARAM;
401 output = std::move(Crypto::Data(input.type, output_key->getDER()));
403 else if (input.type.isCertificate() || input.type.isChainCert())
405 CertificateShPtr cert = CKM::Certificate::create(input.data, DataFormat::FORM_DER);
406 if(cert.get() == NULL)
408 LogDebug("provided binary data is not valid certificate data");
409 return CKM_API_ERROR_INPUT_PARAM;
411 output = std::move(Crypto::Data(input.type, cert->getDER()));
415 // TODO: add here BINARY_DATA verification, i.e: max size etc.
416 return CKM_API_SUCCESS;
419 int CKMLogic::verifyAndSaveDataHelper(
420 const Credentials &cred,
423 const Crypto::Data &data,
424 const PolicySerializable &policy)
426 int retCode = CKM_API_ERROR_UNKNOWN;
429 // check if data is correct
430 Crypto::Data binaryData;
431 retCode = toBinaryData(data, binaryData);
432 if(retCode == CKM_API_SUCCESS)
434 retCode = saveDataHelper(cred, name, label, binaryData, policy);
436 } catch (const Exc::Exception &e) {
438 } catch (const CKM::Exception &e) {
439 LogError("CKM::Exception: " << e.GetMessage());
440 retCode = CKM_API_ERROR_SERVER_ERROR;
445 int CKMLogic::getKeyForService(
446 const Credentials &cred,
449 const Password &pass,
450 Crypto::GObjShPtr &key)
454 // Key is for internal service use. It won't be exported to the client
455 Crypto::GObjUPtr obj;
456 int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, obj);
457 if (retCode == CKM_API_SUCCESS)
458 key = std::move(obj);
460 } catch (const Exc::Exception &e) {
462 } catch (const CKM::Exception &e) {
463 LogError("CKM::Exception: " << e.GetMessage());
464 return CKM_API_ERROR_SERVER_ERROR;
468 RawBuffer CKMLogic::saveData(
469 const Credentials &cred,
473 const Crypto::Data &data,
474 const PolicySerializable &policy)
476 int retCode = verifyAndSaveDataHelper(cred, name, label, data, policy);
477 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
480 static_cast<int>(data.type));
481 return response.Pop();
484 int CKMLogic::extractPKCS12Data(
487 const Label &ownerLabel,
488 const PKCS12Serializable &pkcs,
489 const PolicySerializable &keyPolicy,
490 const PolicySerializable &certPolicy,
491 DB::RowVector &output) const
493 // private key is mandatory
495 return CKM_API_ERROR_INVALID_FORMAT;
496 Key* keyPtr = pkcs.getKey().get();
497 Crypto::Data keyData(DataType(keyPtr->getType()), keyPtr->getDER());
498 int retCode = verifyBinaryData(keyData);
499 if(retCode != CKM_API_SUCCESS)
501 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyData, keyPolicy));
503 // certificate is mandatory
504 if( !pkcs.getCertificate() )
505 return CKM_API_ERROR_INVALID_FORMAT;
506 Crypto::Data certData(DataType::CERTIFICATE, pkcs.getCertificate().get()->getDER());
507 retCode = verifyBinaryData(certData);
508 if(retCode != CKM_API_SUCCESS)
510 output.push_back(createEncryptedRow(crypto, name, ownerLabel, certData, certPolicy));
513 unsigned int cert_index = 0;
514 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
516 Crypto::Data caCertData(DataType::getChainDatatype(cert_index ++), ca->getDER());
517 int retCode = verifyBinaryData(caCertData);
518 if(retCode != CKM_API_SUCCESS)
521 output.push_back(createEncryptedRow(crypto, name, ownerLabel, caCertData, certPolicy));
524 return CKM_API_SUCCESS;
527 RawBuffer CKMLogic::savePKCS12(
528 const Credentials &cred,
532 const PKCS12Serializable &pkcs,
533 const PolicySerializable &keyPolicy,
534 const PolicySerializable &certPolicy)
536 int retCode = CKM_API_ERROR_UNKNOWN;
538 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
539 } catch (const Exc::Exception &e) {
541 } catch (const CKM::Exception &e) {
542 LogError("CKM::Exception: " << e.GetMessage());
543 retCode = CKM_API_ERROR_SERVER_ERROR;
546 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
549 return response.Pop();
553 int CKMLogic::removeDataHelper(
554 const Credentials &cred,
558 auto &handler = selectDatabase(cred, label);
560 // use client label if not explicitly provided
561 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
562 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
563 LogDebug("Invalid label or name format");
564 return CKM_API_ERROR_INPUT_PARAM;
567 DB::Crypto::Transaction transaction(&handler.database);
569 // read and check permissions
570 PermissionMaskOptional permissionRowOpt =
571 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
572 int retCode = m_accessControl.canDelete(cred,
573 PermissionForLabel(cred.smackLabel, permissionRowOpt));
574 if(retCode != CKM_API_SUCCESS)
576 LogWarning("access control check result: " << retCode);
580 // get all matching rows
582 handler.database.getRows(name, ownerLabel, DataType::DB_FIRST, DataType::DB_LAST, rows);
584 LogDebug("No row for given name and label");
585 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
588 // load app key if needed
589 retCode = loadAppKey(handler, rows.front().ownerLabel);
590 if(CKM_API_SUCCESS != retCode)
593 // destroy it in store
594 for(auto& r : rows) {
596 handler.crypto.decryptRow(Password(), r);
597 m_decider.getStore(r).destroy(r);
598 } catch (const Exc::AuthenticationFailed&) {
599 LogDebug("Authentication failed when removing data. Ignored.");
604 handler.database.deleteRow(name, ownerLabel);
605 transaction.commit();
607 return CKM_API_SUCCESS;
610 RawBuffer CKMLogic::removeData(
611 const Credentials &cred,
616 int retCode = CKM_API_ERROR_UNKNOWN;
620 retCode = removeDataHelper(cred, name, label);
622 catch (const Exc::Exception &e)
626 catch (const CKM::Exception &e)
628 LogError("Error: " << e.GetMessage());
629 retCode = CKM_API_ERROR_DB_ERROR;
632 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
635 return response.Pop();
638 int CKMLogic::readSingleRow(const Name &name,
639 const Label &ownerLabel,
641 DB::Crypto & database,
644 DB::Crypto::RowOptional row_optional;
645 if (dataType.isKey())
647 // read all key types
648 row_optional = database.getRow(name,
650 DataType::DB_KEY_FIRST,
651 DataType::DB_KEY_LAST);
653 // read anything else
654 row_optional = database.getRow(name,
660 LogDebug("No row for given name, label and type");
661 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
666 return CKM_API_SUCCESS;
670 int CKMLogic::readMultiRow(const Name &name,
671 const Label &ownerLabel,
673 DB::Crypto & database,
674 DB::RowVector &output)
676 if (dataType.isKey())
678 // read all key types
679 database.getRows(name,
681 DataType::DB_KEY_FIRST,
682 DataType::DB_KEY_LAST,
685 else if (dataType.isChainCert())
687 // read all key types
688 database.getRows(name,
690 DataType::DB_CHAIN_FIRST,
691 DataType::DB_CHAIN_LAST,
696 // read anything else
697 database.getRows(name,
704 LogDebug("No row for given name, label and type");
705 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
708 return CKM_API_SUCCESS;
711 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
713 const Label &ownerLabel,
714 const Label &accessorLabel,
717 DB::Crypto & database)
719 PermissionMaskOptional permissionRowOpt =
720 database.getPermissionRow(name, ownerLabel, accessorLabel);
723 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
724 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
727 Crypto::GObjUPtr CKMLogic::rowToObject(
730 const Password& password)
732 Crypto::GStore& store = m_decider.getStore(row);
734 Password pass = m_accessControl.isCCMode() ? "" : password;
737 Crypto::GObjUPtr obj;
738 if(CryptoLogic::getSchemeVersion(row.encryptionScheme) == CryptoLogic::ENCRYPTION_V2) {
739 handler.crypto.decryptRow(Password(), row);
741 obj = store.getObject(row, pass);
743 // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data
744 handler.crypto.decryptRow(pass, row);
745 // destroy it in store
748 // import it to store with new scheme: data -> pass(data)
749 Token token = store.import(Crypto::Data(row.dataType, row.data), pass);
751 // get it from the store (it can be different than the data we imported into store)
752 obj = store.getObject(token, pass);
754 // update row with new token
755 *static_cast<Token*>(&row) = std::move(token);
757 // encrypt it with app key: pass(data) -> b64(appkey(pass(data))
758 handler.crypto.encryptRow(row);
761 handler.database.updateRow(row);
766 int CKMLogic::readDataHelper(
768 const Credentials &cred,
772 const Password &password,
773 Crypto::GObjUPtrVector &objs)
775 auto &handler = selectDatabase(cred, label);
777 // use client label if not explicitly provided
778 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
780 if (!isNameValid(name) || !isLabelValid(ownerLabel))
781 return CKM_API_ERROR_INPUT_PARAM;
784 DB::Crypto::Transaction transaction(&handler.database);
786 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
787 if(CKM_API_SUCCESS != retCode)
790 // all read rows belong to the same owner
791 DB::Row & firstRow = rows.at(0);
793 // check access rights
794 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
795 if(CKM_API_SUCCESS != retCode)
798 // load app key if needed
799 retCode = loadAppKey(handler, firstRow.ownerLabel);
800 if(CKM_API_SUCCESS != retCode)
804 for(auto &row : rows)
805 objs.push_back(rowToObject(handler, std::move(row), password));
806 // rowToObject may modify db
807 transaction.commit();
809 return CKM_API_SUCCESS;
812 int CKMLogic::readDataHelper(
814 const Credentials &cred,
818 const Password &password,
819 Crypto::GObjUPtr &obj)
821 DataType objDataType;
822 return readDataHelper(exportFlag, cred, dataType, name, label, password, obj, objDataType);
825 int CKMLogic::readDataHelper(
827 const Credentials &cred,
831 const Password &password,
832 Crypto::GObjUPtr &obj,
833 DataType& objDataType)
835 auto &handler = selectDatabase(cred, label);
837 // use client label if not explicitly provided
838 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
840 if (!isNameValid(name) || !isLabelValid(ownerLabel))
841 return CKM_API_ERROR_INPUT_PARAM;
844 DB::Crypto::Transaction transaction(&handler.database);
846 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
847 if(CKM_API_SUCCESS != retCode)
850 objDataType = row.dataType;
852 // check access rights
853 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
854 if(CKM_API_SUCCESS != retCode)
857 // load app key if needed
858 retCode = loadAppKey(handler, row.ownerLabel);
859 if(CKM_API_SUCCESS != retCode)
862 obj = rowToObject(handler, std::move(row), password);
863 // rowToObject may modify db
864 transaction.commit();
866 return CKM_API_SUCCESS;
869 RawBuffer CKMLogic::getData(
870 const Credentials &cred,
875 const Password &password)
877 int retCode = CKM_API_SUCCESS;
879 DataType objDataType;
882 Crypto::GObjUPtr obj;
883 retCode = readDataHelper(true, cred, dataType, name, label, password, obj, objDataType);
884 if(retCode == CKM_API_SUCCESS)
885 row.data = std::move(obj->getBinary());
886 } catch (const Exc::Exception &e) {
888 } catch (const CKM::Exception &e) {
889 LogError("CKM::Exception: " << e.GetMessage());
890 retCode = CKM_API_ERROR_SERVER_ERROR;
893 if (CKM_API_SUCCESS != retCode) {
895 row.dataType = dataType;
898 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
901 static_cast<int>(objDataType),
903 return response.Pop();
906 int CKMLogic::getPKCS12Helper(
907 const Credentials &cred,
910 const Password &keyPassword,
911 const Password &certPassword,
913 CertificateShPtr & cert,
914 CertificateShPtrVector & caChain)
918 // read private key (mandatory)
919 Crypto::GObjUPtr keyObj;
920 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, keyObj);
921 if(retCode != CKM_API_SUCCESS)
923 privKey = CKM::Key::create(keyObj->getBinary());
925 // read certificate (mandatory)
926 Crypto::GObjUPtr certObj;
927 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certObj);
928 if(retCode != CKM_API_SUCCESS)
930 cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER);
932 // read CA cert chain (optional)
933 Crypto::GObjUPtrVector caChainObjs;
934 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, caChainObjs);
935 if(retCode != CKM_API_SUCCESS &&
936 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
938 for(auto &caCertObj : caChainObjs)
939 caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(), DataFormat::FORM_DER));
941 // if anything found, return it
942 if(privKey || cert || caChain.size()>0)
943 retCode = CKM_API_SUCCESS;
948 RawBuffer CKMLogic::getPKCS12(
949 const Credentials &cred,
953 const Password &keyPassword,
954 const Password &certPassword)
956 int retCode = CKM_API_ERROR_UNKNOWN;
958 PKCS12Serializable output;
961 CertificateShPtr cert;
962 CertificateShPtrVector caChain;
963 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
966 if(retCode == CKM_API_SUCCESS)
967 output = PKCS12Serializable(privKey, cert, caChain);
968 } catch (const Exc::Exception &e) {
970 } catch (const CKM::Exception &e) {
971 LogError("CKM::Exception: " << e.GetMessage());
972 retCode = CKM_API_ERROR_SERVER_ERROR;
975 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
979 return response.Pop();
982 int CKMLogic::getDataListHelper(const Credentials &cred,
983 const DataType dataType,
984 LabelNameVector &labelNameVector)
986 int retCode = CKM_API_ERROR_DB_LOCKED;
987 if (0 < m_userDataMap.count(cred.clientUid))
989 auto &database = m_userDataMap[cred.clientUid].database;
992 LabelNameVector tmpVector;
993 if (dataType.isKey()) {
994 // list all key types
995 database.listNames(cred.smackLabel,
997 DataType::DB_KEY_FIRST,
998 DataType::DB_KEY_LAST);
1000 // list anything else
1001 database.listNames(cred.smackLabel,
1005 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
1006 retCode = CKM_API_SUCCESS;
1007 } catch (const CKM::Exception &e) {
1008 LogError("Error: " << e.GetMessage());
1009 retCode = CKM_API_ERROR_DB_ERROR;
1010 } catch (const Exc::Exception &e) {
1011 retCode = e.error();
1017 RawBuffer CKMLogic::getDataList(
1018 const Credentials &cred,
1022 LabelNameVector systemVector;
1023 LabelNameVector userVector;
1024 LabelNameVector labelNameVector;
1026 int retCode = unlockSystemDB();
1027 if (CKM_API_SUCCESS == retCode)
1030 if (m_accessControl.isSystemService(cred))
1033 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1040 // user - lookup system, then client DB
1041 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1047 if(retCode == CKM_API_SUCCESS)
1049 retCode = getDataListHelper(cred,
1056 if(retCode == CKM_API_SUCCESS)
1058 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1059 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1061 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1064 static_cast<int>(dataType),
1066 return response.Pop();
1069 int CKMLogic::importInitialData(
1071 const Crypto::Data &data,
1072 const Crypto::DataEncryption &enc,
1073 const Policy &policy)
1076 // Inital values are always imported with root credentials. Label is not important.
1077 Credentials rootCred(0,"");
1079 auto &handler = selectDatabase(rootCred, OWNER_ID_SYSTEM);
1081 // check if save is possible
1082 DB::Crypto::Transaction transaction(&handler.database);
1083 int retCode = checkSaveConditions(rootCred, handler, name, OWNER_ID_SYSTEM);
1084 if(retCode != CKM_API_SUCCESS)
1087 Crypto::GStore& store =
1088 m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty());
1092 if (enc.encryptedKey.empty()) {
1093 Crypto::Data binaryData;
1094 if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData)))
1096 token = store.import(binaryData, m_accessControl.isCCMode() ? "" : policy.password);
1098 token = store.importEncrypted(data, m_accessControl.isCCMode() ? "" : policy.password, enc);
1101 DB::Row row(std::move(token), name, OWNER_ID_SYSTEM, static_cast<int>(policy.extractable));
1102 handler.crypto.encryptRow(row);
1104 handler.database.saveRow(row);
1105 transaction.commit();
1106 } catch (const Exc::Exception &e) {
1108 } catch (const CKM::Exception &e) {
1109 LogError("CKM::Exception: " << e.GetMessage());
1110 return CKM_API_ERROR_SERVER_ERROR;
1111 } catch (const std::exception &e) {
1112 LogError("Std::exception: " << e.what());
1113 return CKM_API_ERROR_SERVER_ERROR;
1116 return CKM_API_SUCCESS;
1119 int CKMLogic::saveDataHelper(
1120 const Credentials &cred,
1123 const Crypto::Data &data,
1124 const PolicySerializable &policy)
1126 auto &handler = selectDatabase(cred, label);
1128 // use client label if not explicitly provided
1129 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1130 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
1131 return CKM_API_ERROR_INPUT_PARAM;
1133 // check if save is possible
1134 DB::Crypto::Transaction transaction(&handler.database);
1135 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1136 if(retCode != CKM_API_SUCCESS)
1140 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, data, policy);
1141 handler.database.saveRow(encryptedRow);
1143 transaction.commit();
1144 return CKM_API_SUCCESS;
1147 int CKMLogic::saveDataHelper(
1148 const Credentials &cred,
1151 const PKCS12Serializable &pkcs,
1152 const PolicySerializable &keyPolicy,
1153 const PolicySerializable &certPolicy)
1155 auto &handler = selectDatabase(cred, label);
1157 // use client label if not explicitly provided
1158 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1159 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
1160 return CKM_API_ERROR_INPUT_PARAM;
1162 // check if save is possible
1163 DB::Crypto::Transaction transaction(&handler.database);
1164 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1165 if(retCode != CKM_API_SUCCESS)
1168 // extract and encrypt the data
1169 DB::RowVector encryptedRows;
1170 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1171 if(retCode != CKM_API_SUCCESS)
1175 handler.database.saveRows(name, ownerLabel, encryptedRows);
1176 transaction.commit();
1178 return CKM_API_SUCCESS;
1182 int CKMLogic::createKeyAESHelper(
1183 const Credentials &cred,
1187 const PolicySerializable &policy)
1189 auto &handler = selectDatabase(cred, label);
1191 // use client label if not explicitly provided
1192 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1193 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
1194 return CKM_API_ERROR_INPUT_PARAM;
1196 // check if save is possible
1197 DB::Crypto::Transaction transaction(&handler.database);
1198 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1199 if(retCode != CKM_API_SUCCESS)
1202 // create key in store
1203 CryptoAlgorithm keyGenAlgorithm;
1204 keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN);
1205 keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size);
1206 Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm, policy.password);
1209 DB::Row row(std::move(key), name, ownerLabel, static_cast<int>(policy.extractable));
1210 handler.crypto.encryptRow(row);
1212 handler.database.saveRow(row);
1214 transaction.commit();
1215 return CKM_API_SUCCESS;
1218 int CKMLogic::createKeyPairHelper(
1219 const Credentials &cred,
1220 const CryptoAlgorithmSerializable & keyGenParams,
1221 const Name &namePrivate,
1222 const Label &labelPrivate,
1223 const Name &namePublic,
1224 const Label &labelPublic,
1225 const PolicySerializable &policyPrivate,
1226 const PolicySerializable &policyPublic)
1228 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1229 auto &handlerPub = selectDatabase(cred, labelPublic);
1231 AlgoType keyType = AlgoType::RSA_GEN;
1232 if(!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType))
1233 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found.");
1234 DataType dt(keyType);
1236 ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value.");
1238 // use client label if not explicitly provided
1239 const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel : labelPrivate;
1240 if( m_accessControl.isSystemService(cred) && ownerLabelPrv.compare(OWNER_ID_SYSTEM)!=0)
1241 return CKM_API_ERROR_INPUT_PARAM;
1242 const Label &ownerLabelPub = labelPublic.empty() ? cred.smackLabel : labelPublic;
1243 if( m_accessControl.isSystemService(cred) && ownerLabelPub.compare(OWNER_ID_SYSTEM)!=0)
1244 return CKM_API_ERROR_INPUT_PARAM;
1246 bool exportable = policyPrivate.extractable || policyPublic.extractable;
1247 TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams,
1248 policyPrivate.password,
1249 policyPublic.password);
1251 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1252 // in case the same database is used for private and public - the second
1253 // transaction will not be executed
1254 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1257 retCode = checkSaveConditions(cred, handlerPriv, namePrivate, ownerLabelPrv);
1258 if (CKM_API_SUCCESS != retCode)
1261 retCode = checkSaveConditions(cred, handlerPub, namePublic, ownerLabelPub);
1262 if (CKM_API_SUCCESS != retCode)
1266 DB::Row rowPrv(std::move(keys.first), namePrivate, ownerLabelPrv, static_cast<int>(policyPrivate.extractable));
1267 handlerPriv.crypto.encryptRow(rowPrv);
1268 handlerPriv.database.saveRow(rowPrv);
1270 DB::Row rowPub(std::move(keys.second), namePublic, ownerLabelPub, static_cast<int>(policyPublic.extractable));
1271 handlerPub.crypto.encryptRow(rowPub);
1272 handlerPub.database.saveRow(rowPub);
1274 transactionPub.commit();
1275 transactionPriv.commit();
1276 return CKM_API_SUCCESS;
1279 RawBuffer CKMLogic::createKeyPair(
1280 const Credentials &cred,
1282 const CryptoAlgorithmSerializable & keyGenParams,
1283 const Name &namePrivate,
1284 const Label &labelPrivate,
1285 const Name &namePublic,
1286 const Label &labelPublic,
1287 const PolicySerializable &policyPrivate,
1288 const PolicySerializable &policyPublic)
1290 int retCode = CKM_API_SUCCESS;
1293 retCode = createKeyPairHelper(
1302 } catch(const Exc::Exception &e) {
1303 retCode = e.error();
1304 } catch (const CKM::Exception &e) {
1305 LogError("CKM::Exception: " << e.GetMessage());
1306 retCode = CKM_API_ERROR_SERVER_ERROR;
1309 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR),
1310 commandId, retCode).Pop();
1313 RawBuffer CKMLogic::createKeyAES(
1314 const Credentials &cred,
1319 const PolicySerializable &policy)
1321 int retCode = CKM_API_SUCCESS;
1324 retCode = createKeyAESHelper(cred, size, name, label, policy);
1325 } catch (const Exc::Exception &e) {
1326 retCode = e.error();
1327 } catch (std::invalid_argument &e) {
1328 LogDebug("invalid argument error: " << e.what());
1329 retCode = CKM_API_ERROR_INPUT_PARAM;
1330 } catch (const CKM::Exception &e) {
1331 LogError("CKM::Exception: " << e.GetMessage());
1332 retCode = CKM_API_ERROR_SERVER_ERROR;
1335 return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES),
1336 commandId, retCode).Pop();
1339 int CKMLogic::readCertificateHelper(
1340 const Credentials &cred,
1341 const LabelNameVector &labelNameVector,
1342 CertificateImplVector &certVector)
1345 for (auto &i: labelNameVector) {
1346 // certificates can't be protected with custom user password
1347 Crypto::GObjUPtr obj;
1349 ec = readDataHelper(true,
1351 DataType::CERTIFICATE,
1356 if (ec != CKM_API_SUCCESS)
1359 certVector.emplace_back(obj->getBinary(), DataFormat::FORM_DER);
1361 // try to read chain certificates (if present)
1362 Crypto::GObjUPtrVector caChainObjs;
1363 ec = readDataHelper(true,
1365 DataType::DB_CHAIN_FIRST,
1370 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1372 for(auto &caCertObj : caChainObjs)
1373 certVector.emplace_back(caCertObj->getBinary(), DataFormat::FORM_DER);
1375 return CKM_API_SUCCESS;
1378 int CKMLogic::getCertificateChainHelper(
1379 const CertificateImpl &cert,
1380 const RawBufferVector &untrustedCertificates,
1381 const RawBufferVector &trustedCertificates,
1382 bool useTrustedSystemCertificates,
1383 RawBufferVector &chainRawVector)
1385 CertificateImplVector untrustedCertVector;
1386 CertificateImplVector trustedCertVector;
1387 CertificateImplVector chainVector;
1390 return CKM_API_ERROR_INPUT_PARAM;
1392 for (auto &e: untrustedCertificates) {
1393 CertificateImpl c(e, DataFormat::FORM_DER);
1395 return CKM_API_ERROR_INPUT_PARAM;
1396 untrustedCertVector.push_back(std::move(c));
1398 for (auto &e: trustedCertificates) {
1399 CertificateImpl c(e, DataFormat::FORM_DER);
1401 return CKM_API_ERROR_INPUT_PARAM;
1402 trustedCertVector.push_back(std::move(c));
1405 CertificateStore store;
1406 int retCode = store.verifyCertificate(cert,
1407 untrustedCertVector,
1409 useTrustedSystemCertificates,
1410 m_accessControl.isCCMode(),
1412 if (retCode != CKM_API_SUCCESS)
1415 for (auto &e : chainVector)
1416 chainRawVector.push_back(e.getDER());
1417 return CKM_API_SUCCESS;
1420 int CKMLogic::getCertificateChainHelper(
1421 const Credentials &cred,
1422 const CertificateImpl &cert,
1423 const LabelNameVector &untrusted,
1424 const LabelNameVector &trusted,
1425 bool useTrustedSystemCertificates,
1426 RawBufferVector &chainRawVector)
1428 CertificateImplVector untrustedCertVector;
1429 CertificateImplVector trustedCertVector;
1430 CertificateImplVector chainVector;
1434 return CKM_API_ERROR_INPUT_PARAM;
1436 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1437 if (retCode != CKM_API_SUCCESS)
1439 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1440 if (retCode != CKM_API_SUCCESS)
1443 CertificateStore store;
1444 retCode = store.verifyCertificate(cert,
1445 untrustedCertVector,
1447 useTrustedSystemCertificates,
1448 m_accessControl.isCCMode(),
1450 if (retCode != CKM_API_SUCCESS)
1453 for (auto &i: chainVector)
1454 chainRawVector.push_back(i.getDER());
1456 return CKM_API_SUCCESS;
1459 RawBuffer CKMLogic::getCertificateChain(
1460 const Credentials & /*cred*/,
1462 const RawBuffer &certificate,
1463 const RawBufferVector &untrustedCertificates,
1464 const RawBufferVector &trustedCertificates,
1465 bool useTrustedSystemCertificates)
1467 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1468 RawBufferVector chainRawVector;
1469 int retCode = CKM_API_ERROR_UNKNOWN;
1471 retCode = getCertificateChainHelper(cert,
1472 untrustedCertificates,
1473 trustedCertificates,
1474 useTrustedSystemCertificates,
1476 } catch (const Exc::Exception &e) {
1477 retCode = e.error();
1478 } catch (const std::exception& e) {
1479 LogError("STD exception " << e.what());
1480 retCode = CKM_API_ERROR_SERVER_ERROR;
1482 LogError("Unknown error.");
1485 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1489 return response.Pop();
1492 RawBuffer CKMLogic::getCertificateChain(
1493 const Credentials &cred,
1495 const RawBuffer &certificate,
1496 const LabelNameVector &untrustedCertificates,
1497 const LabelNameVector &trustedCertificates,
1498 bool useTrustedSystemCertificates)
1500 int retCode = CKM_API_ERROR_UNKNOWN;
1501 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1502 RawBufferVector chainRawVector;
1504 retCode = getCertificateChainHelper(cred,
1506 untrustedCertificates,
1507 trustedCertificates,
1508 useTrustedSystemCertificates,
1510 } catch (const Exc::Exception &e) {
1511 retCode = e.error();
1512 } catch (const std::exception& e) {
1513 LogError("STD exception " << e.what());
1514 retCode = CKM_API_ERROR_SERVER_ERROR;
1516 LogError("Unknown error.");
1519 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1523 return response.Pop();
1526 RawBuffer CKMLogic::createSignature(
1527 const Credentials &cred,
1529 const Name &privateKeyName,
1530 const Label & ownerLabel,
1531 const Password &password, // password for private_key
1532 const RawBuffer &message,
1533 const CryptoAlgorithm &cryptoAlg)
1536 RawBuffer signature;
1538 int retCode = CKM_API_SUCCESS;
1541 Crypto::GObjUPtr obj;
1542 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, obj);
1543 if(retCode == CKM_API_SUCCESS) {
1544 signature = obj->sign(cryptoAlg, message);
1546 } catch (const Exc::Exception &e) {
1547 retCode = e.error();
1548 } catch (const CKM::Exception &e) {
1549 LogError("Unknown CKM::Exception: " << e.GetMessage());
1550 retCode = CKM_API_ERROR_SERVER_ERROR;
1551 } catch (const std::exception &e) {
1552 LogError("STD exception " << e.what());
1553 retCode = CKM_API_ERROR_SERVER_ERROR;
1556 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1560 return response.Pop();
1563 RawBuffer CKMLogic::verifySignature(
1564 const Credentials &cred,
1566 const Name &publicKeyOrCertName,
1567 const Label & ownerLabel,
1568 const Password &password, // password for public_key (optional)
1569 const RawBuffer &message,
1570 const RawBuffer &signature,
1571 const CryptoAlgorithm ¶ms)
1573 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1578 // try certificate first - looking for a public key.
1579 // in case of PKCS, pub key from certificate will be found first
1580 // rather than private key from the same PKCS.
1581 Crypto::GObjUPtr obj;
1582 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, obj);
1583 if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1584 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, obj);
1587 if (retCode == CKM_API_SUCCESS) {
1588 retCode = obj->verify(params, message, signature);
1590 } catch (const Exc::Exception &e) {
1591 retCode = e.error();
1592 } catch (const CKM::Exception &e) {
1593 LogError("Unknown CKM::Exception: " << e.GetMessage());
1594 retCode = CKM_API_ERROR_SERVER_ERROR;
1597 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1600 return response.Pop();
1603 int CKMLogic::setPermissionHelper(
1604 const Credentials &cred, // who's the client
1606 const Label &label, // who's the owner
1607 const Label &accessorLabel, // who will get the access
1608 const PermissionMask permissionMask)
1610 auto &handler = selectDatabase(cred, label);
1612 // we don't know the client
1613 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1614 return CKM_API_ERROR_INPUT_PARAM;
1616 // use client label if not explicitly provided
1617 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1619 // verify name and label are correct
1620 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1621 return CKM_API_ERROR_INPUT_PARAM;
1623 // currently we don't support modification of owner's permissions to his own rows
1624 if (ownerLabel==accessorLabel)
1625 return CKM_API_ERROR_INPUT_PARAM;
1627 // system database does not support write/remove permissions
1628 if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) &&
1629 (permissionMask & Permission::REMOVE))
1630 return CKM_API_ERROR_INPUT_PARAM;
1632 // can the client modify permissions to owner's row?
1633 int retCode = m_accessControl.canModify(cred, ownerLabel);
1634 if(retCode != CKM_API_SUCCESS)
1637 DB::Crypto::Transaction transaction(&handler.database);
1639 if( !handler.database.isNameLabelPresent(name, ownerLabel) )
1640 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1642 // removing non-existing permissions: fail
1643 if(permissionMask == Permission::NONE)
1645 if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1646 return CKM_API_ERROR_INPUT_PARAM;
1649 // set permissions to the row owned by ownerLabel for accessorLabel
1650 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1651 transaction.commit();
1653 return CKM_API_SUCCESS;
1656 RawBuffer CKMLogic::setPermission(
1657 const Credentials &cred,
1662 const Label &accessorLabel,
1663 const PermissionMask permissionMask)
1667 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1668 } catch (const Exc::Exception &e) {
1669 retCode = e.error();
1670 } catch (const CKM::Exception &e) {
1671 LogError("Error: " << e.GetMessage());
1672 retCode = CKM_API_ERROR_DB_ERROR;
1675 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
1678 int CKMLogic::loadAppKey(UserData& handle, const Label& appLabel)
1680 if (!handle.crypto.haveKey(appLabel)) {
1682 auto key_optional = handle.database.getKey(appLabel);
1684 LogError("No key for given label in database");
1685 return CKM_API_ERROR_DB_ERROR;
1687 key = *key_optional;
1688 key = handle.keyProvider.getPureDEK(key);
1689 handle.crypto.pushKey(appLabel, key);
1691 return CKM_API_SUCCESS;