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 <CryptoService.h>
29 #include <ckm-logic.h>
31 #include <certificate-config.h>
32 #include <certificate-store.h>
35 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
37 bool isLabelValid(const CKM::Label &label) {
38 // TODO: copy code from libprivilege control (for check smack label)
39 if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
44 bool isNameValid(const CKM::Name &name) {
45 if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
50 } // anonymous namespace
56 CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
58 m_accessControl.updateCCMode();
61 CKMLogic::~CKMLogic(){}
63 void CKMLogic::loadDKEKFile(
64 const ClientID &clientID,
65 const Password &password,
68 auto &handle = m_userDataMap[clientID];
70 FileSystem fs(clientID);
72 auto wrappedDKEKMain = fs.getDKEK();
73 auto wrappedDKEKBackup = fs.getDKEKBackup();
75 #ifdef PASSWORD_PROTECTION_DISABLE
76 if (wrappedDKEKMain.empty()) {
77 wrappedDKEKMain = KeyProvider::generateDomainKEK(clientID, Password(""));
78 fs.saveDKEK(wrappedDKEKMain);
82 chooseDKEKFile(handle, Password(""), wrappedDKEKMain, wrappedDKEKBackup);
83 } catch (const KeyProvider::Exception::Base &e) {
84 chooseDKEKFile(handle, password, wrappedDKEKMain, wrappedDKEKBackup);
85 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(Password("")));
86 handle.isMainDKEK = true;
87 LogInfo("Password Protected DB was migrated to Password Protection Disabled DB.");
90 if (wrappedDKEKMain.empty()) {
91 wrappedDKEKMain = KeyProvider::generateDomainKEK(clientID, password);
92 fs.saveDKEK(wrappedDKEKMain);
95 chooseDKEKFile(handle, password, wrappedDKEKMain, wrappedDKEKBackup);
98 if (!password.empty() || apiReq) {
99 handle.isDKEKConfirmed = true;
101 if (true == handle.isMainDKEK)
102 fs.removeDKEKBackup();
108 void CKMLogic::chooseDKEKFile(
110 const Password &password,
111 const RawBuffer &first,
112 const RawBuffer &second)
115 handle.keyProvider = KeyProvider(first, password);
116 handle.isMainDKEK = true;
117 } catch (const KeyProvider::Exception::Base &e) {
118 // Second buffer is empty. Lets rethrow first error
121 handle.keyProvider = KeyProvider(second, password);
122 handle.isMainDKEK = false;
126 void CKMLogic::saveDKEKFile(const ClientID &clientID, const Password &password) {
127 auto &handle = m_userDataMap[clientID];
129 FileSystem fs(clientID);
130 if (handle.isMainDKEK)
131 fs.createDKEKBackup();
133 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
135 handle.isMainDKEK = true;
136 handle.isDKEKConfirmed = false;
139 RawBuffer CKMLogic::unlockUserKey(
140 const ClientID &clientID,
141 const Password &password,
144 int retCode = CKM_API_SUCCESS;
147 if (0 == m_userDataMap.count(clientID) || !(m_userDataMap[clientID].keyProvider.isInitialized())) {
148 auto &handle = m_userDataMap[clientID];
149 FileSystem fs(clientID);
151 loadDKEKFile(clientID, password, apiRequest);
153 auto wrappedDatabaseDEK = fs.getDBDEK();
155 if (wrappedDatabaseDEK.empty()) {
156 wrappedDatabaseDEK = handle.keyProvider.generateDEK(clientID);
157 fs.saveDBDEK(wrappedDatabaseDEK);
160 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
161 handle.database = DB::Crypto(fs.getDBPath(), key);
162 handle.crypto = CryptoLogic();
164 // remove data of removed apps during locked state
165 AppLabelVector removedApps = fs.clearRemovedsApps();
166 for(auto& appSmackLabel : removedApps) {
167 handle.crypto.removeKey(appSmackLabel);
168 handle.database.deleteKey(appSmackLabel);
170 } else if (apiRequest == true && m_userDataMap[clientID].isDKEKConfirmed == false) {
171 // now we will try to choose the DKEK key and remove old one
172 loadDKEKFile(clientID, password, apiRequest);
174 } catch (const KeyProvider::Exception::PassWordError &e) {
175 LogError("Incorrect Password " << e.GetMessage());
176 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
177 } catch (const KeyProvider::Exception::Base &e) {
178 LogError("Error in KeyProvider " << e.GetMessage());
179 retCode = CKM_API_ERROR_SERVER_ERROR;
180 } catch (const CryptoLogic::Exception::Base &e) {
181 LogError("CryptoLogic error: " << e.GetMessage());
182 retCode = CKM_API_ERROR_SERVER_ERROR;
183 } catch (const FileSystem::Exception::Base &e) {
184 LogError("FileSystem error: " << e.GetMessage());
185 retCode = CKM_API_ERROR_FILE_SYSTEM;
186 } catch (const CKM::Exception &e) {
187 LogError("CKM::Exception: " << e.GetMessage());
188 retCode = CKM_API_ERROR_SERVER_ERROR;
191 if(retCode != CKM_API_SUCCESS) {
192 // When not successful, UserData in m_userDataMap should be erased.
193 // Because other operations make decision based on the existence of UserData in m_userDataMap.
194 m_userDataMap.erase(clientID);
197 return MessageBuffer::Serialize(retCode).Pop();
200 RawBuffer CKMLogic::updateCCMode() {
201 m_accessControl.updateCCMode();
202 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
205 RawBuffer CKMLogic::lockUserKey(const ClientID &clientID) {
206 int retCode = CKM_API_SUCCESS;
207 // TODO try catch for all errors that should be supported by error code
209 #ifdef PASSWORD_PROTECTION_DISABLE
212 m_userDataMap.erase(clientID);
215 return MessageBuffer::Serialize(retCode).Pop();
219 RawBuffer CKMLogic::removeUserData(const ClientID &clientID) {
220 int retCode = CKM_API_SUCCESS;
221 // TODO try catch for all errors that should be supported by error code
223 m_userDataMap.erase(clientID);
225 FileSystem fs(clientID);
228 return MessageBuffer::Serialize(retCode).Pop();
231 RawBuffer CKMLogic::changeUserPassword(
232 const ClientID &clientID,
233 const Password &oldPassword,
234 const Password &newPassword)
236 int retCode = CKM_API_SUCCESS;
238 #ifdef PASSWORD_PROTECTION_DISABLE
244 loadDKEKFile(clientID, oldPassword, true);
245 saveDKEKFile(clientID, newPassword);
246 } catch (const KeyProvider::Exception::PassWordError &e) {
247 LogError("Incorrect Password " << e.GetMessage());
248 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
249 } catch (const KeyProvider::Exception::Base &e) {
250 LogError("Error in KeyProvider " << e.GetMessage());
251 retCode = CKM_API_ERROR_SERVER_ERROR;
252 } catch (const FileSystem::Exception::Base &e) {
253 LogError("Error in FileSystem " << e.GetMessage());
254 retCode = CKM_API_ERROR_FILE_SYSTEM;
255 } catch (const CKM::Exception &e) {
256 LogError("CKM::Exception: " << e.GetMessage());
257 retCode = CKM_API_ERROR_SERVER_ERROR;
261 return MessageBuffer::Serialize(retCode).Pop();
264 RawBuffer CKMLogic::resetUserPassword(
265 const ClientID &clientID,
266 const Password &newPassword)
268 int retCode = CKM_API_SUCCESS;
269 #ifdef PASSWORD_PROTECTION_DISABLE
274 if (0 == m_userDataMap.count(clientID)) {
275 // Check if key exists. If exists we must return error
276 FileSystem fs(clientID);
277 auto wrappedDKEKMain = fs.getDKEK();
278 if (!wrappedDKEKMain.empty())
279 retCode = CKM_API_ERROR_BAD_REQUEST;
281 saveDKEKFile(clientID, newPassword);
283 } catch (const FileSystem::Exception::Base &e) {
284 LogError("Error in FileSystem " << e.GetMessage());
285 retCode = CKM_API_ERROR_FILE_SYSTEM;
286 } catch (const CKM::Exception &e) {
287 LogError("CKM::Exception: " << e.GetMessage());
288 retCode = CKM_API_ERROR_SERVER_ERROR;
292 return MessageBuffer::Serialize(retCode).Pop();
295 RawBuffer CKMLogic::removeApplicationData(const std::string &zone, const Label &smackLabel) {
296 int retCode = CKM_API_SUCCESS;
299 if (smackLabel.empty()) {
300 retCode = CKM_API_ERROR_INPUT_PARAM;
302 ClientIDVector clientIDVec = FileSystem::getClientIDsFromDBFile(zone);
303 for (auto clientID : clientIDVec) {
304 if (0 == m_userDataMap.count(clientID)) {
305 FileSystem fs(clientID);
306 fs.addRemovedApp(smackLabel);
308 auto &handle = m_userDataMap[clientID];
309 handle.crypto.removeKey(smackLabel);
310 handle.database.deleteKey(smackLabel);
314 } catch (const DB::Crypto::Exception::InternalError &e) {
315 LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
316 retCode = CKM_API_ERROR_DB_ERROR;
317 } catch (const DB::Crypto::Exception::TransactionError &e) {
318 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
319 retCode = CKM_API_ERROR_DB_ERROR;
320 } catch (const FileSystem::Exception::Base &e) {
321 LogError("Error in FileSystem " << e.GetMessage());
322 retCode = CKM_API_ERROR_FILE_SYSTEM;
323 } catch (const CKM::Exception &e) {
324 LogError("CKM::Exception: " << e.GetMessage());
325 retCode = CKM_API_ERROR_SERVER_ERROR;
328 return MessageBuffer::Serialize(retCode).Pop();
331 int CKMLogic::checkSaveConditions(
332 const Credentials &cred,
335 const Label &ownerLabel)
337 // verify name and label are correct
338 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
339 LogWarning("Invalid parameter passed to key-manager");
340 return CKM_API_ERROR_INPUT_PARAM;
342 // check if allowed to save using ownerLabel
343 int access_ec = m_accessControl.canSave(ownerLabel, cred.smackLabel);
344 if(access_ec != CKM_API_SUCCESS)
346 LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
350 // check if not a duplicate
351 if( handler.database.isNameLabelPresent(name, cred.smackLabel) )
352 return CKM_API_ERROR_DB_ALIAS_EXISTS;
354 // encryption section
355 if (!handler.crypto.haveKey(cred.smackLabel)) {
357 auto key_optional = handler.database.getKey(cred.smackLabel);
359 LogDebug("No Key in database found. Generating new one for label: "
361 got_key = handler.keyProvider.generateDEK(cred.smackLabel);
362 handler.database.saveKey(cred.smackLabel, got_key);
364 LogDebug("Key from DB");
365 got_key = *key_optional;
368 got_key = handler.keyProvider.getPureDEK(got_key);
369 handler.crypto.pushKey(cred.smackLabel, got_key);
372 return CKM_API_SUCCESS;
375 DB::Row CKMLogic::createEncryptedRow(
380 const RawBuffer &data,
381 const Policy &policy) const
383 DB::Row row = { name, label, policy.extractable, dataType, DBCMAlgType::NONE,
384 0, RawBuffer(), static_cast<int>(data.size()), data, RawBuffer() };
386 // do not encrypt data with password during cc_mode on
387 if(m_accessControl.isCCMode()) {
388 crypto.encryptRow("", row);
390 crypto.encryptRow(policy.password, row);
395 int CKMLogic::verifyBinaryData(DataType dataType, const RawBuffer &input_data) const
397 // verify the data integrity
398 if (dataType.isKey())
400 KeyShPtr output_key = CKM::Key::create(input_data);
401 if(output_key.get() == NULL)
403 LogError("provided binary data is not valid key data");
404 return CKM_API_ERROR_INPUT_PARAM;
407 else if (dataType.isCertificate() || dataType.isChainCert())
409 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
410 if(cert.get() == NULL)
412 LogError("provided binary data is not valid certificate data");
413 return CKM_API_ERROR_INPUT_PARAM;
416 // TODO: add here BINARY_DATA verification, i.e: max size etc.
417 return CKM_API_SUCCESS;
420 RawBuffer CKMLogic::saveData(
421 const Credentials &cred,
425 const RawBuffer &data,
427 const PolicySerializable &policy)
430 if (0 == m_userDataMap.count(cred.clientID))
431 retCode = CKM_API_ERROR_DB_LOCKED;
435 // check if data is correct
436 retCode = verifyBinaryData(dataType, data);
437 if(retCode == CKM_API_SUCCESS)
439 retCode = saveDataHelper(cred, name, label, dataType, data, policy);
441 } catch (const KeyProvider::Exception::Base &e) {
442 LogError("KeyProvider failed with message: " << e.GetMessage());
443 retCode = CKM_API_ERROR_SERVER_ERROR;
444 } catch (const CryptoLogic::Exception::Base &e) {
445 LogError("CryptoLogic failed with message: " << e.GetMessage());
446 retCode = CKM_API_ERROR_SERVER_ERROR;
447 } catch (const DB::Crypto::Exception::InternalError &e) {
448 LogError("DB::Crypto failed with message: " << e.GetMessage());
449 retCode = CKM_API_ERROR_DB_ERROR;
450 } catch (const DB::Crypto::Exception::TransactionError &e) {
451 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
452 retCode = CKM_API_ERROR_DB_ERROR;
453 } catch (const FileSystem::Exception::Base &e) {
454 LogError("Error in FileSystem " << e.GetMessage());
455 retCode = CKM_API_ERROR_FILE_SYSTEM;
456 } catch (const CKM::Exception &e) {
457 LogError("CKM::Exception: " << e.GetMessage());
458 retCode = CKM_API_ERROR_SERVER_ERROR;
462 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
465 static_cast<int>(dataType));
466 return response.Pop();
469 int CKMLogic::extractPKCS12Data(
472 const Label &ownerLabel,
473 const PKCS12Serializable &pkcs,
474 const PolicySerializable &keyPolicy,
475 const PolicySerializable &certPolicy,
476 DB::RowVector &output) const
478 // private key is mandatory
480 return CKM_API_ERROR_INVALID_FORMAT;
481 Key* keyPtr = pkcs.getKey().get();
482 DataType keyType = DataType(keyPtr->getType());
483 RawBuffer keyData = keyPtr->getDER();
484 int retCode = verifyBinaryData(keyType, keyData);
485 if(retCode != CKM_API_SUCCESS)
487 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
489 // certificate is mandatory
490 if( !pkcs.getCertificate() )
491 return CKM_API_ERROR_INVALID_FORMAT;
492 RawBuffer certData = pkcs.getCertificate().get()->getDER();
493 retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
494 if(retCode != CKM_API_SUCCESS)
496 output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
499 unsigned int cert_index = 0;
500 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
502 DataType chainDataType = DataType::getChainDatatype(cert_index ++);
503 RawBuffer caCertData = ca->getDER();
504 int retCode = verifyBinaryData(chainDataType, caCertData);
505 if(retCode != CKM_API_SUCCESS)
508 output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
511 return CKM_API_SUCCESS;
514 RawBuffer CKMLogic::savePKCS12(
515 const Credentials &cred,
519 const PKCS12Serializable &pkcs,
520 const PolicySerializable &keyPolicy,
521 const PolicySerializable &certPolicy)
524 if (0 == m_userDataMap.count(cred.clientID))
525 retCode = CKM_API_ERROR_DB_LOCKED;
529 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
530 } catch (const KeyProvider::Exception::Base &e) {
531 LogError("KeyProvider failed with message: " << e.GetMessage());
532 retCode = CKM_API_ERROR_SERVER_ERROR;
533 } catch (const CryptoLogic::Exception::Base &e) {
534 LogError("CryptoLogic failed with message: " << e.GetMessage());
535 retCode = CKM_API_ERROR_SERVER_ERROR;
536 } catch (const DB::Crypto::Exception::InternalError &e) {
537 LogError("DB::Crypto failed with message: " << e.GetMessage());
538 retCode = CKM_API_ERROR_DB_ERROR;
539 } catch (const DB::Crypto::Exception::TransactionError &e) {
540 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
541 retCode = CKM_API_ERROR_DB_ERROR;
542 } catch (const CKM::Exception &e) {
543 LogError("CKM::Exception: " << e.GetMessage());
544 retCode = CKM_API_ERROR_SERVER_ERROR;
548 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
551 return response.Pop();
555 int CKMLogic::removeDataHelper(
556 const Credentials &cred,
558 const Label &ownerLabel)
560 if (0 == m_userDataMap.count(cred.clientID))
561 return CKM_API_ERROR_DB_LOCKED;
563 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
564 LogError("Invalid label or name format");
565 return CKM_API_ERROR_INPUT_PARAM;
568 auto &database = m_userDataMap[cred.clientID].database;
569 DB::Crypto::Transaction transaction(&database);
571 // read and check permissions
572 PermissionMaskOptional permissionRowOpt =
573 database.getPermissionRow(name, ownerLabel, cred.smackLabel);
574 int access_ec = m_accessControl.canDelete(PermissionForLabel(cred.smackLabel, permissionRowOpt));
575 if(access_ec != CKM_API_SUCCESS)
577 LogWarning("access control check result: " << access_ec);
581 auto erased = database.deleteRow(name, ownerLabel);
582 // check if the data existed or not
584 transaction.commit();
586 LogError("No row for given name and label");
587 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
590 return CKM_API_SUCCESS;
593 RawBuffer CKMLogic::removeData(
594 const Credentials &cred,
601 // use client label if not explicitly provided
602 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
604 retCode = removeDataHelper(cred, name, ownerLabel);
605 } Catch (CKM::Exception) {
606 LogError("Error in deleting row!");
607 retCode = CKM_API_ERROR_DB_ERROR;
610 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
613 return response.Pop();
616 int CKMLogic::readSingleRow(const Name &name,
617 const Label &ownerLabel,
619 DB::Crypto & database,
622 DB::Crypto::RowOptional row_optional;
623 if (dataType.isKey())
625 // read all key types
626 row_optional = database.getRow(name,
628 DataType::DB_KEY_FIRST,
629 DataType::DB_KEY_LAST);
631 // read anything else
632 row_optional = database.getRow(name,
638 LogError("No row for given name, label and type");
639 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
644 return CKM_API_SUCCESS;
647 int CKMLogic::readMultiRow(const Name &name,
648 const Label &ownerLabel,
650 DB::Crypto & database,
651 DB::RowVector &output)
653 if (dataType.isKey())
655 // read all key types
656 database.getRows(name,
658 DataType::DB_KEY_FIRST,
659 DataType::DB_KEY_LAST,
662 else if (dataType.isChainCert())
664 // read all key types
665 database.getRows(name,
667 DataType::DB_CHAIN_FIRST,
668 DataType::DB_CHAIN_LAST,
673 // read anything else
674 database.getRows(name,
682 * readMultiRow is only used to get row which cannot exist
683 * So, it shouldn't print error log
685 LogDebug("No row for given name, label and type");
686 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
689 return CKM_API_SUCCESS;
692 int CKMLogic::checkDataPermissionsHelper(const Name &name,
693 const Label &ownerLabel,
694 const Label &accessorLabel,
697 DB::Crypto & database)
699 PermissionMaskOptional permissionRowOpt =
700 database.getPermissionRow(name, ownerLabel, accessorLabel);
703 return m_accessControl.canExport(row, PermissionForLabel(accessorLabel, permissionRowOpt));
704 return m_accessControl.canRead(PermissionForLabel(accessorLabel, permissionRowOpt));
707 int CKMLogic::readDataHelper(
709 const Credentials &cred,
713 const Password &password,
716 if (0 == m_userDataMap.count(cred.clientID))
717 return CKM_API_ERROR_DB_LOCKED;
719 // use client label if not explicitly provided
720 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
722 if (!isNameValid(name) || !isLabelValid(ownerLabel))
723 return CKM_API_ERROR_INPUT_PARAM;
725 auto &handler = m_userDataMap[cred.clientID];
728 DB::Crypto::Transaction transaction(&handler.database);
729 int ec = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
730 if(CKM_API_SUCCESS != ec)
733 // all read rows belong to the same owner
734 DB::Row & firstRow = rows.at(0);
736 // check access rights
737 ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
738 if(CKM_API_SUCCESS != ec)
742 if (!handler.crypto.haveKey(firstRow.ownerLabel)) {
744 auto key_optional = handler.database.getKey(firstRow.ownerLabel);
746 LogError("No key for given label in database");
747 return CKM_API_ERROR_DB_ERROR;
750 key = handler.keyProvider.getPureDEK(key);
751 handler.crypto.pushKey(firstRow.ownerLabel, key);
753 for(auto &row : rows)
754 handler.crypto.decryptRow(password, row);
756 return CKM_API_SUCCESS;
759 int CKMLogic::readDataHelper(
761 const Credentials &cred,
765 const Password &password,
768 if (0 == m_userDataMap.count(cred.clientID))
769 return CKM_API_ERROR_DB_LOCKED;
771 // use client label if not explicitly provided
772 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
774 if (!isNameValid(name) || !isLabelValid(ownerLabel))
775 return CKM_API_ERROR_INPUT_PARAM;
777 auto &handler = m_userDataMap[cred.clientID];
780 DB::Crypto::Transaction transaction(&handler.database);
781 int ec = readSingleRow(name, ownerLabel, dataType, handler.database, row);
782 if(CKM_API_SUCCESS != ec)
786 // check access rights
787 ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
788 if(CKM_API_SUCCESS != ec)
792 if (!handler.crypto.haveKey(row.ownerLabel)) {
794 auto key_optional = handler.database.getKey(row.ownerLabel);
796 LogError("No key for given label in database");
797 return CKM_API_ERROR_DB_ERROR;
800 key = handler.keyProvider.getPureDEK(key);
801 handler.crypto.pushKey(row.ownerLabel, key);
803 handler.crypto.decryptRow(password, row);
805 return CKM_API_SUCCESS;
808 RawBuffer CKMLogic::getData(
809 const Credentials &cred,
814 const Password &password)
816 int retCode = CKM_API_SUCCESS;
820 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
821 } catch (const KeyProvider::Exception::Base &e) {
822 LogError("KeyProvider failed with error: " << e.GetMessage());
823 retCode = CKM_API_ERROR_SERVER_ERROR;
824 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
825 LogError("CryptoLogic failed with message: " << e.GetMessage());
826 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
827 } catch (const CryptoLogic::Exception::Base &e) {
828 LogError("CryptoLogic failed with message: " << e.GetMessage());
829 retCode = CKM_API_ERROR_SERVER_ERROR;
830 } catch (const DB::Crypto::Exception::Base &e) {
831 LogError("DB::Crypto failed with message: " << e.GetMessage());
832 retCode = CKM_API_ERROR_DB_ERROR;
833 } catch (const CKM::Exception &e) {
834 LogError("CKM::Exception: " << e.GetMessage());
835 retCode = CKM_API_ERROR_SERVER_ERROR;
838 if (CKM_API_SUCCESS != retCode) {
840 row.dataType = dataType;
843 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
846 static_cast<int>(row.dataType),
848 return response.Pop();
851 int CKMLogic::getPKCS12Helper(
852 const Credentials &cred,
855 const Password &keyPassword,
856 const Password &certPassword,
858 CertificateShPtr & cert,
859 CertificateShPtrVector & caChain)
863 // read private key (mandatory)
865 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
866 if(retCode != CKM_API_SUCCESS)
868 privKey = CKM::Key::create(privKeyRow.data);
870 // read certificate (mandatory)
872 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
873 if(retCode != CKM_API_SUCCESS)
875 cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
877 // read CA cert chain (optional)
878 DB::RowVector rawCaChain;
879 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
880 if(retCode != CKM_API_SUCCESS &&
881 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
883 for(auto &rawCaCert : rawCaChain)
884 caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
886 // if anything found, return it
887 if(privKey || cert || caChain.size()>0)
888 retCode = CKM_API_SUCCESS;
893 RawBuffer CKMLogic::getPKCS12(
894 const Credentials &cred,
898 const Password &keyPassword,
899 const Password &certPassword)
902 PKCS12Serializable output;
906 CertificateShPtr cert;
907 CertificateShPtrVector caChain;
908 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
911 if(retCode == CKM_API_SUCCESS)
912 output = PKCS12Serializable(privKey, cert, caChain);
914 } catch (const KeyProvider::Exception::Base &e) {
915 LogError("KeyProvider failed with error: " << e.GetMessage());
916 retCode = CKM_API_ERROR_SERVER_ERROR;
917 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
918 LogError("CryptoLogic failed with message: " << e.GetMessage());
919 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
920 } catch (const CryptoLogic::Exception::Base &e) {
921 LogError("CryptoLogic failed with message: " << e.GetMessage());
922 retCode = CKM_API_ERROR_SERVER_ERROR;
923 } catch (const DB::Crypto::Exception::Base &e) {
924 LogError("DB::Crypto failed with message: " << e.GetMessage());
925 retCode = CKM_API_ERROR_DB_ERROR;
926 } catch (const CKM::Exception &e) {
927 LogError("CKM::Exception: " << e.GetMessage());
928 retCode = CKM_API_ERROR_SERVER_ERROR;
931 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
935 return response.Pop();
938 RawBuffer CKMLogic::getDataList(
939 const Credentials &cred,
943 int retCode = CKM_API_SUCCESS;
944 LabelNameVector labelNameVector;
946 if (0 < m_userDataMap.count(cred.clientID)) {
947 auto &database = m_userDataMap[cred.clientID].database;
950 if (dataType.isKey()) {
951 // list all key types
952 database.listNames(cred.smackLabel,
954 DataType::DB_KEY_FIRST,
955 DataType::DB_KEY_LAST);
957 // list anything else
958 database.listNames(cred.smackLabel,
963 Catch (CKM::Exception) {
964 LogError("Failed to get names");
965 retCode = CKM_API_ERROR_DB_ERROR;
968 retCode = CKM_API_ERROR_DB_LOCKED;
971 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
974 static_cast<int>(dataType),
976 return response.Pop();
979 int CKMLogic::saveDataHelper(
980 const Credentials &cred,
984 const RawBuffer &data,
985 const PolicySerializable &policy)
987 auto &handler = m_userDataMap[cred.clientID];
989 // use client label if not explicitly provided
990 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
992 // check if save is possible
993 DB::Crypto::Transaction transaction(&handler.database);
994 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
995 if(retCode != CKM_API_SUCCESS)
999 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
1000 handler.database.saveRow(encryptedRow);
1002 transaction.commit();
1003 return CKM_API_SUCCESS;
1006 int CKMLogic::saveDataHelper(
1007 const Credentials &cred,
1010 const PKCS12Serializable &pkcs,
1011 const PolicySerializable &keyPolicy,
1012 const PolicySerializable &certPolicy)
1014 auto &handler = m_userDataMap[cred.clientID];
1016 // use client label if not explicitly provided
1017 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1019 // check if save is possible
1020 DB::Crypto::Transaction transaction(&handler.database);
1021 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1022 if(retCode != CKM_API_SUCCESS)
1025 // extract and encrypt the data
1026 DB::RowVector encryptedRows;
1027 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1028 if(retCode != CKM_API_SUCCESS)
1032 handler.database.saveRows(name, ownerLabel, encryptedRows);
1033 transaction.commit();
1035 return CKM_API_SUCCESS;
1039 int CKMLogic::createKeyPairHelper(
1040 const Credentials &cred,
1041 const KeyType key_type,
1042 const int additional_param,
1043 const Name &namePrivate,
1044 const Label &labelPrivate,
1045 const Name &namePublic,
1046 const Label &labelPublic,
1047 const PolicySerializable &policyPrivate,
1048 const PolicySerializable &policyPublic)
1050 if (0 == m_userDataMap.count(cred.clientID))
1051 return CKM_API_ERROR_DB_LOCKED;
1057 case KeyType::KEY_RSA_PUBLIC:
1058 case KeyType::KEY_RSA_PRIVATE:
1059 retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
1062 case KeyType::KEY_DSA_PUBLIC:
1063 case KeyType::KEY_DSA_PRIVATE:
1064 retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
1067 case KeyType::KEY_ECDSA_PUBLIC:
1068 case KeyType::KEY_ECDSA_PRIVATE:
1069 retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
1073 return CKM_API_ERROR_INPUT_PARAM;
1076 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
1078 LogDebug("CryptoService error with code: " << retCode);
1079 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
1082 auto &database = m_userDataMap[cred.clientID].database;
1083 DB::Crypto::Transaction transaction(&database);
1085 retCode = saveDataHelper(cred,
1088 DataType(prv.getType()),
1091 if (CKM_API_SUCCESS != retCode)
1094 retCode = saveDataHelper(cred,
1097 DataType(pub.getType()),
1100 if (CKM_API_SUCCESS != retCode)
1103 transaction.commit();
1108 RawBuffer CKMLogic::createKeyPair(
1109 const Credentials &cred,
1110 LogicCommand protocol_cmd,
1112 const int additional_param,
1113 const Name &namePrivate,
1114 const Label &labelPrivate,
1115 const Name &namePublic,
1116 const Label &labelPublic,
1117 const PolicySerializable &policyPrivate,
1118 const PolicySerializable &policyPublic)
1120 int retCode = CKM_API_SUCCESS;
1122 KeyType key_type = KeyType::KEY_NONE;
1123 switch(protocol_cmd)
1125 case LogicCommand::CREATE_KEY_PAIR_RSA:
1126 key_type = KeyType::KEY_RSA_PUBLIC;
1128 case LogicCommand::CREATE_KEY_PAIR_DSA:
1129 key_type = KeyType::KEY_DSA_PUBLIC;
1131 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
1132 key_type = KeyType::KEY_ECDSA_PUBLIC;
1139 retCode = createKeyPairHelper(
1149 } catch (DB::Crypto::Exception::TransactionError &e) {
1150 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1151 retCode = CKM_API_ERROR_DB_ERROR;
1152 } catch (CKM::CryptoLogic::Exception::Base &e) {
1153 LogDebug("CryptoLogic error: " << e.GetMessage());
1154 retCode = CKM_API_ERROR_SERVER_ERROR;
1155 } catch (DB::Crypto::Exception::InternalError &e) {
1156 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1157 retCode = CKM_API_ERROR_DB_ERROR;
1158 } catch (const CKM::Exception &e) {
1159 LogError("CKM::Exception: " << e.GetMessage());
1160 retCode = CKM_API_ERROR_SERVER_ERROR;
1163 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
1166 int CKMLogic::readCertificateHelper(
1167 const Credentials &cred,
1168 const LabelNameVector &labelNameVector,
1169 CertificateImplVector &certVector)
1172 for (auto &i: labelNameVector) {
1173 int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1174 if (ec != CKM_API_SUCCESS)
1176 certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1178 // try to read chain certificates (if present)
1179 DB::RowVector rawCaChain;
1180 ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1181 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1183 for(auto &rawCaCert : rawCaChain)
1184 certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1186 return CKM_API_SUCCESS;
1189 int CKMLogic::getCertificateChainHelper(
1190 const CertificateImpl &cert,
1191 const RawBufferVector &untrustedCertificates,
1192 const RawBufferVector &trustedCertificates,
1193 bool useTrustedSystemCertificates,
1194 RawBufferVector &chainRawVector)
1196 CertificateImplVector untrustedCertVector;
1197 CertificateImplVector trustedCertVector;
1198 CertificateImplVector chainVector;
1201 return CKM_API_ERROR_INPUT_PARAM;
1203 for (auto &e: untrustedCertificates)
1204 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1205 for (auto &e: trustedCertificates)
1206 trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1208 CertificateStore store;
1209 int retCode = store.verifyCertificate(cert,
1210 untrustedCertVector,
1212 useTrustedSystemCertificates,
1213 m_accessControl.isCCMode(),
1215 if (retCode != CKM_API_SUCCESS)
1218 for (auto &e : chainVector)
1219 chainRawVector.push_back(e.getDER());
1220 return CKM_API_SUCCESS;
1223 int CKMLogic::getCertificateChainHelper(
1224 const Credentials &cred,
1225 const CertificateImpl &cert,
1226 const LabelNameVector &untrusted,
1227 const LabelNameVector &trusted,
1228 bool useTrustedSystemCertificates,
1229 RawBufferVector &chainRawVector)
1231 CertificateImplVector untrustedCertVector;
1232 CertificateImplVector trustedCertVector;
1233 CertificateImplVector chainVector;
1237 return CKM_API_ERROR_INPUT_PARAM;
1239 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1240 if (retCode != CKM_API_SUCCESS)
1242 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1243 if (retCode != CKM_API_SUCCESS)
1246 CertificateStore store;
1247 retCode = store.verifyCertificate(cert,
1248 untrustedCertVector,
1250 useTrustedSystemCertificates,
1251 m_accessControl.isCCMode(),
1253 if (retCode != CKM_API_SUCCESS)
1256 for (auto &i: chainVector)
1257 chainRawVector.push_back(i.getDER());
1259 return CKM_API_SUCCESS;
1262 RawBuffer CKMLogic::getCertificateChain(
1263 const Credentials & /*cred*/,
1265 const RawBuffer &certificate,
1266 const RawBufferVector &untrustedCertificates,
1267 const RawBufferVector &trustedCertificates,
1268 bool useTrustedSystemCertificates)
1270 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1271 RawBufferVector chainRawVector;
1272 int retCode = CKM_API_ERROR_UNKNOWN;
1274 retCode = getCertificateChainHelper(cert,
1275 untrustedCertificates,
1276 trustedCertificates,
1277 useTrustedSystemCertificates,
1279 } catch (const CryptoLogic::Exception::Base &e) {
1280 LogError("CryptoLogic failed with message: " << e.GetMessage());
1281 retCode = CKM_API_ERROR_SERVER_ERROR;
1282 } catch (const DB::Crypto::Exception::Base &e) {
1283 LogError("DB::Crypto failed with message: " << e.GetMessage());
1284 retCode = CKM_API_ERROR_DB_ERROR;
1285 } catch (const std::exception& e) {
1286 LogError("STD exception " << e.what());
1287 retCode = CKM_API_ERROR_SERVER_ERROR;
1289 LogError("Unknown error.");
1292 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1296 m_accessControl.isCCMode());
1297 return response.Pop();
1300 RawBuffer CKMLogic::getCertificateChain(
1301 const Credentials &cred,
1303 const RawBuffer &certificate,
1304 const LabelNameVector &untrustedCertificates,
1305 const LabelNameVector &trustedCertificates,
1306 bool useTrustedSystemCertificates)
1308 int retCode = CKM_API_ERROR_UNKNOWN;
1309 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1310 RawBufferVector chainRawVector;
1312 retCode = getCertificateChainHelper(cred,
1314 untrustedCertificates,
1315 trustedCertificates,
1316 useTrustedSystemCertificates,
1318 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1319 LogError("CryptoLogic failed with message: " << e.GetMessage());
1320 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1321 } catch (const CryptoLogic::Exception::Base &e) {
1322 LogError("CryptoLogic failed with message: " << e.GetMessage());
1323 retCode = CKM_API_ERROR_SERVER_ERROR;
1324 } catch (const DB::Crypto::Exception::Base &e) {
1325 LogError("DB::Crypto failed with message: " << e.GetMessage());
1326 retCode = CKM_API_ERROR_DB_ERROR;
1327 } catch (const std::exception& e) {
1328 LogError("STD exception " << e.what());
1329 retCode = CKM_API_ERROR_SERVER_ERROR;
1331 LogError("Unknown error.");
1334 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1338 m_accessControl.isCCMode());
1339 return response.Pop();
1342 RawBuffer CKMLogic::createSignature(
1343 const Credentials &cred,
1345 const Name &privateKeyName,
1346 const Label & ownerLabel,
1347 const Password &password, // password for private_key
1348 const RawBuffer &message,
1349 const HashAlgorithm hash,
1350 const RSAPaddingAlgorithm padding)
1354 RawBuffer signature;
1356 int retCode = CKM_API_SUCCESS;
1359 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1360 if(retCode == CKM_API_SUCCESS)
1362 KeyImpl keyParsed(row.data, Password());
1363 if (keyParsed.empty())
1364 retCode = CKM_API_ERROR_SERVER_ERROR;
1366 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
1368 } catch (const KeyProvider::Exception::Base &e) {
1369 LogError("KeyProvider failed with message: " << e.GetMessage());
1370 retCode = CKM_API_ERROR_SERVER_ERROR;
1371 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1372 LogError("CryptoLogic failed with message: " << e.GetMessage());
1373 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1374 } catch (const CryptoLogic::Exception::Base &e) {
1375 LogError("CryptoLogic failed with message: " << e.GetMessage());
1376 retCode = CKM_API_ERROR_SERVER_ERROR;
1377 } catch (const DB::Crypto::Exception::Base &e) {
1378 LogError("DB::Crypto failed with message: " << e.GetMessage());
1379 retCode = CKM_API_ERROR_DB_ERROR;
1380 } catch (const CKM::Exception &e) {
1381 LogError("Unknown CKM::Exception: " << e.GetMessage());
1382 retCode = CKM_API_ERROR_SERVER_ERROR;
1385 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1389 return response.Pop();
1392 RawBuffer CKMLogic::verifySignature(
1393 const Credentials &cred,
1395 const Name &publicKeyOrCertName,
1396 const Label & ownerLabel,
1397 const Password &password, // password for public_key (optional)
1398 const RawBuffer &message,
1399 const RawBuffer &signature,
1400 const HashAlgorithm hash,
1401 const RSAPaddingAlgorithm padding)
1403 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1408 DB::RowVector rowVec;
1412 // try certificate first - looking for a public key.
1413 // in case of PKCS, pub key from certificate will be found first
1414 // rather than private key from the same PKCS.
1415 retCode = readDataHelper(
1418 DataType::CERTIFICATE,
1419 publicKeyOrCertName,
1424 // output cannot be more than 1
1425 if (rowVec.size() > 1) {
1426 ThrowMsg(CKM::Exception,
1427 "More than one certificate mapped to a label[" << ownerLabel << "]");
1429 else if (retCode == CKM_API_SUCCESS && rowVec.size() == 1) {
1430 CertificateImpl cert(rowVec[0].data, DataFormat::FORM_DER);
1431 key = cert.getKeyImpl();
1433 else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN && rowVec.size() == 0) {
1434 retCode = readDataHelper(
1437 DataType::DB_KEY_FIRST,
1438 publicKeyOrCertName,
1443 if (retCode != CKM_API_SUCCESS)
1445 key = KeyImpl(row.data);
1452 retCode = CKM_API_ERROR_SERVER_ERROR;
1456 retCode = cs.verifySignature(key, message, signature, hash, padding);
1458 } catch (const CryptoService::Exception::Crypto_internal &e) {
1459 LogError("KeyProvider failed with message: " << e.GetMessage());
1460 retCode = CKM_API_ERROR_SERVER_ERROR;
1461 } catch (const CryptoService::Exception::opensslError &e) {
1462 LogError("KeyProvider failed with message: " << e.GetMessage());
1463 retCode = CKM_API_ERROR_SERVER_ERROR;
1464 } catch (const KeyProvider::Exception::Base &e) {
1465 LogError("KeyProvider failed with error: " << e.GetMessage());
1466 retCode = CKM_API_ERROR_SERVER_ERROR;
1467 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1468 LogError("CryptoLogic failed with message: " << e.GetMessage());
1469 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1470 } catch (const CryptoLogic::Exception::Base &e) {
1471 LogError("CryptoLogic failed with message: " << e.GetMessage());
1472 retCode = CKM_API_ERROR_SERVER_ERROR;
1473 } catch (const DB::Crypto::Exception::Base &e) {
1474 LogError("DB::Crypto failed with message: " << e.GetMessage());
1475 retCode = CKM_API_ERROR_DB_ERROR;
1476 } catch (const CKM::Exception &e) {
1477 LogError("Unknown CKM::Exception: " << e.GetMessage());
1478 retCode = CKM_API_ERROR_SERVER_ERROR;
1481 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1484 return response.Pop();
1487 int CKMLogic::setPermissionHelper(
1488 const Credentials &cred, // who's the client
1490 const Label &label, // who's the owner
1491 const Label &accessorLabel, // who will get the access
1492 const PermissionMask permissionMask)
1494 // we don't know the client
1495 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1496 return CKM_API_ERROR_INPUT_PARAM;
1498 // use client label if not explicitly provided
1499 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1501 // verify name and label are correct
1502 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1503 return CKM_API_ERROR_INPUT_PARAM;
1505 // currently we don't support modification of owner's permissions to his own rows
1506 if (ownerLabel==accessorLabel)
1507 return CKM_API_ERROR_INPUT_PARAM;
1509 // can the client modify permissions to owner's row?
1510 int access_ec = m_accessControl.canModify(ownerLabel, cred.smackLabel);
1511 if(access_ec != CKM_API_SUCCESS)
1513 if (0 == m_userDataMap.count(cred.clientID))
1514 return CKM_API_ERROR_DB_LOCKED;
1516 auto &database = m_userDataMap[cred.clientID].database;
1517 DB::Crypto::Transaction transaction(&database);
1519 if( !database.isNameLabelPresent(name, ownerLabel) )
1520 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1522 // removing non-existing permissions: fail
1523 if(permissionMask == Permission::NONE)
1525 if(!database.getPermissionRow(name, ownerLabel, accessorLabel))
1526 return CKM_API_ERROR_INPUT_PARAM;
1529 // set permissions to the row owned by ownerLabel for accessorLabel
1530 database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1531 transaction.commit();
1533 return CKM_API_SUCCESS;
1536 RawBuffer CKMLogic::setPermission(
1537 const Credentials &cred,
1542 const Label &accessorLabel,
1543 const PermissionMask permissionMask)
1547 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1548 } Catch (CKM::Exception) {
1549 LogError("Error in set row!");
1550 retCode = CKM_API_ERROR_DB_ERROR;
1553 return MessageBuffer::Serialize(command, msgID, retCode).Pop();