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 <certificate-config.h>
31 #include <certificate-store.h>
33 #include <sw-backend/crypto-service.h>
36 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
37 const uid_t SYSTEM_DB_UID = 0;
38 const char * const SYSTEM_DB_PASSWD = "cAtRugU7";
40 bool isLabelValid(const CKM::Label &label) {
41 // TODO: copy code from libprivilege control (for check smack label)
42 if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
47 bool isNameValid(const CKM::Name &name) {
48 if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
52 } // anonymous namespace
58 CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
60 m_accessControl.updateCCMode();
63 CKMLogic::~CKMLogic(){}
65 void CKMLogic::loadDKEKFile(uid_t user, const Password &password) {
66 auto &handle = m_userDataMap[user];
70 auto wrappedDKEK = fs.getDKEK();
72 if (wrappedDKEK.empty()) {
73 wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
74 fs.saveDKEK(wrappedDKEK);
77 handle.keyProvider = KeyProvider(wrappedDKEK, password);
80 void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
81 auto &handle = m_userDataMap[user];
84 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
87 int CKMLogic::unlockDatabase(uid_t user, const Password & password)
89 if (0<m_userDataMap.count(user) && m_userDataMap[user].keyProvider.isInitialized())
90 return CKM_API_SUCCESS;
92 int retCode = CKM_API_SUCCESS;
95 auto &handle = m_userDataMap[user];
98 loadDKEKFile(user, password);
100 auto wrappedDatabaseDEK = fs.getDBDEK();
101 if (wrappedDatabaseDEK.empty()) {
102 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
103 fs.saveDBDEK(wrappedDatabaseDEK);
106 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
108 handle.database = DB::Crypto(fs.getDBPath(), key);
109 handle.crypto = CryptoLogic();
111 if ( !m_accessControl.isSystemService(user) )
113 // remove data of removed apps during locked state
114 AppLabelVector removedApps = fs.clearRemovedsApps();
115 for(auto& appSmackLabel : removedApps) {
116 handle.database.deleteKey(appSmackLabel);
119 } catch (const KeyProvider::Exception::PassWordError &e) {
120 LogError("Incorrect Password " << e.GetMessage());
121 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
122 } catch (const KeyProvider::Exception::Base &e) {
123 LogError("Error in KeyProvider " << e.GetMessage());
124 retCode = CKM_API_ERROR_SERVER_ERROR;
125 } catch (const CryptoLogic::Exception::Base &e) {
126 LogError("CryptoLogic error: " << e.GetMessage());
127 retCode = CKM_API_ERROR_SERVER_ERROR;
128 } catch (const FileSystem::Exception::Base &e) {
129 LogError("FileSystem error: " << e.GetMessage());
130 retCode = CKM_API_ERROR_FILE_SYSTEM;
131 } catch (const CKM::Exception &e) {
132 LogError("CKM::Exception: " << e.GetMessage());
133 retCode = CKM_API_ERROR_SERVER_ERROR;
136 if (CKM_API_SUCCESS != retCode)
137 m_userDataMap.erase(user);
142 int CKMLogic::unlockSystemDB()
144 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
147 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
149 // if user trying to access system service - check:
150 // * if user database is unlocked [mandatory]
151 // * if not - proceed with regular user database
152 // * if explicit system database label given -> switch to system DB
153 if ( !m_accessControl.isSystemService(cred) )
155 if (0 == m_userDataMap.count(cred.clientUid))
156 ThrowMsg(Exception::DatabaseLocked, "database with UID: " << cred.clientUid << " locked");
158 if (0 != incoming_label.compare(LABEL_SYSTEM_DB))
159 return m_userDataMap[cred.clientUid];
162 // system database selected, modify the label
163 if (CKM_API_SUCCESS != unlockSystemDB() )
164 ThrowMsg(Exception::DatabaseLocked, "can not unlock system database");
165 return m_userDataMap[SYSTEM_DB_UID];
168 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
170 int retCode = CKM_API_SUCCESS;
172 if( !m_accessControl.isSystemService(user) )
174 retCode = unlockDatabase(user, password);
178 // do not allow lock/unlock operations for system users
179 retCode = CKM_API_ERROR_INPUT_PARAM;
182 return MessageBuffer::Serialize(retCode).Pop();
185 RawBuffer CKMLogic::updateCCMode() {
186 m_accessControl.updateCCMode();
187 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
190 RawBuffer CKMLogic::lockUserKey(uid_t user)
192 int retCode = CKM_API_SUCCESS;
193 if( !m_accessControl.isSystemService(user) )
195 m_userDataMap.erase(user);
199 // do not allow lock/unlock operations for system users
200 retCode = CKM_API_ERROR_INPUT_PARAM;
203 return MessageBuffer::Serialize(retCode).Pop();
207 RawBuffer CKMLogic::removeUserData(uid_t user) {
208 int retCode = CKM_API_SUCCESS;
210 if (m_accessControl.isSystemService(user))
211 user = SYSTEM_DB_UID;
213 m_userDataMap.erase(user);
218 return MessageBuffer::Serialize(retCode).Pop();
221 int CKMLogic::changeUserPasswordHelper(uid_t user,
222 const Password &oldPassword,
223 const Password &newPassword)
225 // do not allow to change system database password
226 if( m_accessControl.isSystemService(user) )
227 return CKM_API_ERROR_INPUT_PARAM;
229 loadDKEKFile(user, oldPassword);
230 saveDKEKFile(user, newPassword);
232 return CKM_API_SUCCESS;
235 RawBuffer CKMLogic::changeUserPassword(
237 const Password &oldPassword,
238 const Password &newPassword)
240 int retCode = CKM_API_SUCCESS;
243 retCode = changeUserPasswordHelper(user, oldPassword, newPassword);
244 } catch (const KeyProvider::Exception::PassWordError &e) {
245 LogError("Incorrect Password " << e.GetMessage());
246 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
247 } catch (const KeyProvider::Exception::Base &e) {
248 LogError("Error in KeyProvider " << e.GetMessage());
249 retCode = CKM_API_ERROR_SERVER_ERROR;
250 } catch (const FileSystem::Exception::Base &e) {
251 LogError("Error in FileSystem " << e.GetMessage());
252 retCode = CKM_API_ERROR_FILE_SYSTEM;
253 } catch (const CKM::Exception &e) {
254 LogError("CKM::Exception: " << e.GetMessage());
255 retCode = CKM_API_ERROR_SERVER_ERROR;
258 return MessageBuffer::Serialize(retCode).Pop();
261 int CKMLogic::resetUserPasswordHelper(
263 const Password &newPassword)
265 // do not allow to reset system database password
266 if( m_accessControl.isSystemService(user) )
267 return CKM_API_ERROR_INPUT_PARAM;
269 int retCode = CKM_API_SUCCESS;
270 if (0 == m_userDataMap.count(user))
272 // Check if key exists. If exists we must return error
274 auto wrappedDKEKMain = fs.getDKEK();
275 if (!wrappedDKEKMain.empty())
276 retCode = CKM_API_ERROR_BAD_REQUEST;
278 saveDKEKFile(user, newPassword);
284 RawBuffer CKMLogic::resetUserPassword(
286 const Password &newPassword)
288 int retCode = CKM_API_SUCCESS;
290 retCode = resetUserPasswordHelper(user, newPassword);
291 } catch (const FileSystem::Exception::Base &e) {
292 LogError("Error in FileSystem " << e.GetMessage());
293 retCode = CKM_API_ERROR_FILE_SYSTEM;
294 } catch (const CKM::Exception &e) {
295 LogError("CKM::Exception: " << e.GetMessage());
296 retCode = CKM_API_ERROR_SERVER_ERROR;
299 return MessageBuffer::Serialize(retCode).Pop();
302 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
303 int retCode = CKM_API_SUCCESS;
307 if (smackLabel.empty()) {
308 retCode = CKM_API_ERROR_INPUT_PARAM;
310 UidVector uids = FileSystem::getUIDsFromDBFile();
311 for (auto userId : uids) {
312 if (0 == m_userDataMap.count(userId)) {
313 FileSystem fs(userId);
314 fs.addRemovedApp(smackLabel);
316 auto &handle = m_userDataMap[userId];
317 handle.database.deleteKey(smackLabel);
322 } catch (const DB::Crypto::Exception::InternalError &e) {
323 LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
324 retCode = CKM_API_ERROR_DB_ERROR;
325 } catch (const DB::Crypto::Exception::TransactionError &e) {
326 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
327 retCode = CKM_API_ERROR_DB_ERROR;
328 } catch (const FileSystem::Exception::Base &e) {
329 LogError("Error in FileSystem " << e.GetMessage());
330 retCode = CKM_API_ERROR_FILE_SYSTEM;
331 } catch (const CKM::Exception &e) {
332 LogError("CKM::Exception: " << e.GetMessage());
333 retCode = CKM_API_ERROR_SERVER_ERROR;
336 return MessageBuffer::Serialize(retCode).Pop();
339 int CKMLogic::checkSaveConditions(
340 const Credentials &cred,
343 const Label &ownerLabel)
345 // verify name and label are correct
346 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
347 LogWarning("Invalid parameter passed to key-manager");
348 return CKM_API_ERROR_INPUT_PARAM;
351 // check if allowed to save using ownerLabel
352 int access_ec = m_accessControl.canSave(cred, ownerLabel);
353 if( access_ec != CKM_API_SUCCESS)
355 LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
359 // check if not a duplicate
360 if( handler.database.isNameLabelPresent(name, ownerLabel))
361 return CKM_API_ERROR_DB_ALIAS_EXISTS;
363 // encryption section
364 if (!handler.crypto.haveKey(ownerLabel))
367 auto key_optional = handler.database.getKey(ownerLabel);
369 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
370 got_key = handler.keyProvider.generateDEK(ownerLabel);
371 handler.database.saveKey(ownerLabel, got_key);
373 LogDebug("Key from DB");
374 got_key = *key_optional;
377 got_key = handler.keyProvider.getPureDEK(got_key);
378 handler.crypto.pushKey(ownerLabel, got_key);
381 return CKM_API_SUCCESS;
384 DB::Row CKMLogic::createEncryptedRow(
389 const RawBuffer &data,
390 const Policy &policy) const
392 DB::Row row = { name, label, policy.extractable, dataType, DBCMAlgType::NONE,
393 0, RawBuffer(), static_cast<int>(data.size()), data, RawBuffer() };
395 // do not encrypt data with password during cc_mode on
396 if(m_accessControl.isCCMode()) {
397 crypto.encryptRow("", row);
399 crypto.encryptRow(policy.password, row);
404 int CKMLogic::verifyBinaryData(DataType dataType, const RawBuffer &input_data) const
406 // verify the data integrity
407 if (dataType.isKey())
409 KeyShPtr output_key = CKM::Key::create(input_data);
410 if(output_key.get() == NULL)
412 LogError("provided binary data is not valid key data");
413 return CKM_API_ERROR_INPUT_PARAM;
416 else if (dataType.isCertificate() || dataType.isChainCert())
418 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
419 if(cert.get() == NULL)
421 LogError("provided binary data is not valid certificate data");
422 return CKM_API_ERROR_INPUT_PARAM;
425 // TODO: add here BINARY_DATA verification, i.e: max size etc.
426 return CKM_API_SUCCESS;
429 RawBuffer CKMLogic::saveData(
430 const Credentials &cred,
434 const RawBuffer &data,
436 const PolicySerializable &policy)
438 int retCode = CKM_API_ERROR_UNKNOWN;
441 // check if data is correct
442 retCode = verifyBinaryData(dataType, data);
443 if(retCode == CKM_API_SUCCESS)
445 retCode = saveDataHelper(cred, name, label, dataType, data, policy);
447 } catch (const KeyProvider::Exception::Base &e) {
448 LogError("KeyProvider failed with message: " << e.GetMessage());
449 retCode = CKM_API_ERROR_SERVER_ERROR;
450 } catch (const CryptoLogic::Exception::Base &e) {
451 LogError("CryptoLogic failed with message: " << e.GetMessage());
452 retCode = CKM_API_ERROR_SERVER_ERROR;
453 } catch (const DB::Crypto::Exception::InternalError &e) {
454 LogError("DB::Crypto failed with message: " << e.GetMessage());
455 retCode = CKM_API_ERROR_DB_ERROR;
456 } catch (const DB::Crypto::Exception::TransactionError &e) {
457 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
458 retCode = CKM_API_ERROR_DB_ERROR;
459 } catch (const FileSystem::Exception::Base &e) {
460 LogError("Error in FileSystem " << e.GetMessage());
461 retCode = CKM_API_ERROR_FILE_SYSTEM;
462 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
463 LogError("Error " << e.GetMessage());
464 retCode = CKM_API_ERROR_DB_LOCKED;
465 } catch (const CKM::Exception &e) {
466 LogError("CKM::Exception: " << e.GetMessage());
467 retCode = CKM_API_ERROR_SERVER_ERROR;
470 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
473 static_cast<int>(dataType));
474 return response.Pop();
477 int CKMLogic::extractPKCS12Data(
480 const Label &ownerLabel,
481 const PKCS12Serializable &pkcs,
482 const PolicySerializable &keyPolicy,
483 const PolicySerializable &certPolicy,
484 DB::RowVector &output) const
486 // private key is mandatory
488 return CKM_API_ERROR_INVALID_FORMAT;
489 Key* keyPtr = pkcs.getKey().get();
490 DataType keyType = DataType(keyPtr->getType());
491 RawBuffer keyData = keyPtr->getDER();
492 int retCode = verifyBinaryData(keyType, keyData);
493 if(retCode != CKM_API_SUCCESS)
495 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
497 // certificate is mandatory
498 if( !pkcs.getCertificate() )
499 return CKM_API_ERROR_INVALID_FORMAT;
500 RawBuffer certData = pkcs.getCertificate().get()->getDER();
501 retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
502 if(retCode != CKM_API_SUCCESS)
504 output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
507 unsigned int cert_index = 0;
508 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
510 DataType chainDataType = DataType::getChainDatatype(cert_index ++);
511 RawBuffer caCertData = ca->getDER();
512 int retCode = verifyBinaryData(chainDataType, caCertData);
513 if(retCode != CKM_API_SUCCESS)
516 output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
519 return CKM_API_SUCCESS;
522 RawBuffer CKMLogic::savePKCS12(
523 const Credentials &cred,
527 const PKCS12Serializable &pkcs,
528 const PolicySerializable &keyPolicy,
529 const PolicySerializable &certPolicy)
531 int retCode = CKM_API_ERROR_UNKNOWN;
533 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
534 } catch (const KeyProvider::Exception::Base &e) {
535 LogError("KeyProvider failed with message: " << e.GetMessage());
536 retCode = CKM_API_ERROR_SERVER_ERROR;
537 } catch (const CryptoLogic::Exception::Base &e) {
538 LogError("CryptoLogic failed with message: " << e.GetMessage());
539 retCode = CKM_API_ERROR_SERVER_ERROR;
540 } catch (const DB::Crypto::Exception::InternalError &e) {
541 LogError("DB::Crypto failed with message: " << e.GetMessage());
542 retCode = CKM_API_ERROR_DB_ERROR;
543 } catch (const DB::Crypto::Exception::TransactionError &e) {
544 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
545 retCode = CKM_API_ERROR_DB_ERROR;
546 } catch (const CKM::Exception &e) {
547 LogError("CKM::Exception: " << e.GetMessage());
548 retCode = CKM_API_ERROR_SERVER_ERROR;
551 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
554 return response.Pop();
558 int CKMLogic::removeDataHelper(
559 const Credentials &cred,
563 auto &handler = selectDatabase(cred, label);
565 // use client label if not explicitly provided
566 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
567 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
568 LogError("Invalid label or name format");
569 return CKM_API_ERROR_INPUT_PARAM;
572 DB::Crypto::Transaction transaction(&handler.database);
574 // read and check permissions
575 PermissionMaskOptional permissionRowOpt =
576 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
577 int retCode = m_accessControl.canDelete(cred,
578 PermissionForLabel(cred.smackLabel, permissionRowOpt));
579 if(retCode != CKM_API_SUCCESS)
581 LogWarning("access control check result: " << retCode);
585 auto erased = handler.database.deleteRow(name, ownerLabel);
586 // check if the data existed or not
588 transaction.commit();
590 LogError("No row for given name and label");
591 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
594 return CKM_API_SUCCESS;
597 RawBuffer CKMLogic::removeData(
598 const Credentials &cred,
603 int retCode = CKM_API_ERROR_UNKNOWN;
607 retCode = removeDataHelper(cred, name, label);
609 catch (const CKMLogic::Exception::DatabaseLocked &e)
611 LogError("Error " << e.GetMessage());
612 retCode = CKM_API_ERROR_DB_LOCKED;
614 catch (const CKM::Exception &)
616 LogError("Error in deleting row!");
617 retCode = CKM_API_ERROR_DB_ERROR;
620 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
623 return response.Pop();
626 int CKMLogic::readSingleRow(const Name &name,
627 const Label &ownerLabel,
629 DB::Crypto & database,
632 DB::Crypto::RowOptional row_optional;
633 if (dataType.isKey())
635 // read all key types
636 row_optional = database.getRow(name,
638 DataType::DB_KEY_FIRST,
639 DataType::DB_KEY_LAST);
641 // read anything else
642 row_optional = database.getRow(name,
648 LogError("No row for given name, label and type");
649 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
654 return CKM_API_SUCCESS;
658 int CKMLogic::readMultiRow(const Name &name,
659 const Label &ownerLabel,
661 DB::Crypto & database,
662 DB::RowVector &output)
664 if (dataType.isKey())
666 // read all key types
667 database.getRows(name,
669 DataType::DB_KEY_FIRST,
670 DataType::DB_KEY_LAST,
673 else if (dataType.isChainCert())
675 // read all key types
676 database.getRows(name,
678 DataType::DB_CHAIN_FIRST,
679 DataType::DB_CHAIN_LAST,
684 // read anything else
685 database.getRows(name,
692 LogError("No row for given name, label and type");
693 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
696 return CKM_API_SUCCESS;
699 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
701 const Label &ownerLabel,
702 const Label &accessorLabel,
705 DB::Crypto & database)
707 PermissionMaskOptional permissionRowOpt =
708 database.getPermissionRow(name, ownerLabel, accessorLabel);
711 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
712 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
715 int CKMLogic::readDataHelper(
717 const Credentials &cred,
721 const Password &password,
724 auto &handler = selectDatabase(cred, label);
726 // use client label if not explicitly provided
727 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
729 if (!isNameValid(name) || !isLabelValid(ownerLabel))
730 return CKM_API_ERROR_INPUT_PARAM;
733 DB::Crypto::Transaction transaction(&handler.database);
734 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
735 if(CKM_API_SUCCESS != retCode)
738 // all read rows belong to the same owner
739 DB::Row & firstRow = rows.at(0);
741 // check access rights
742 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
743 if(CKM_API_SUCCESS != retCode)
747 if (!handler.crypto.haveKey(firstRow.ownerLabel)) {
749 auto key_optional = handler.database.getKey(firstRow.ownerLabel);
751 LogError("No key for given label in database");
752 return CKM_API_ERROR_DB_ERROR;
755 key = handler.keyProvider.getPureDEK(key);
756 handler.crypto.pushKey(firstRow.ownerLabel, key);
758 for(auto &row : rows)
759 handler.crypto.decryptRow(password, row);
761 return CKM_API_SUCCESS;
764 int CKMLogic::readDataHelper(
766 const Credentials &cred,
770 const Password &password,
773 auto &handler = selectDatabase(cred, label);
775 // use client label if not explicitly provided
776 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
778 if (!isNameValid(name) || !isLabelValid(ownerLabel))
779 return CKM_API_ERROR_INPUT_PARAM;
782 DB::Crypto::Transaction transaction(&handler.database);
783 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
784 if(CKM_API_SUCCESS != retCode)
787 // check access rights
788 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
789 if(CKM_API_SUCCESS != retCode)
793 if (!handler.crypto.haveKey(row.ownerLabel)) {
795 auto key_optional = handler.database.getKey(row.ownerLabel);
797 LogError("No key for given label in database");
798 return CKM_API_ERROR_DB_ERROR;
801 key = handler.keyProvider.getPureDEK(key);
802 handler.crypto.pushKey(row.ownerLabel, key);
804 handler.crypto.decryptRow(password, row);
806 return CKM_API_SUCCESS;
809 RawBuffer CKMLogic::getData(
810 const Credentials &cred,
815 const Password &password)
817 int retCode = CKM_API_SUCCESS;
821 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
822 } catch (const KeyProvider::Exception::Base &e) {
823 LogError("KeyProvider failed with error: " << e.GetMessage());
824 retCode = CKM_API_ERROR_SERVER_ERROR;
825 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
826 LogError("CryptoLogic failed with message: " << e.GetMessage());
827 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
828 } catch (const CryptoLogic::Exception::Base &e) {
829 LogError("CryptoLogic failed with message: " << e.GetMessage());
830 retCode = CKM_API_ERROR_SERVER_ERROR;
831 } catch (const DB::Crypto::Exception::Base &e) {
832 LogError("DB::Crypto failed with message: " << e.GetMessage());
833 retCode = CKM_API_ERROR_DB_ERROR;
834 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
835 LogError("Error " << e.GetMessage());
836 retCode = CKM_API_ERROR_DB_LOCKED;
837 } catch (const CKM::Exception &e) {
838 LogError("CKM::Exception: " << e.GetMessage());
839 retCode = CKM_API_ERROR_SERVER_ERROR;
842 if (CKM_API_SUCCESS != retCode) {
844 row.dataType = dataType;
847 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
850 static_cast<int>(row.dataType),
852 return response.Pop();
855 int CKMLogic::getPKCS12Helper(
856 const Credentials &cred,
859 const Password &keyPassword,
860 const Password &certPassword,
862 CertificateShPtr & cert,
863 CertificateShPtrVector & caChain)
867 // read private key (mandatory)
869 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
870 if(retCode != CKM_API_SUCCESS)
872 privKey = CKM::Key::create(privKeyRow.data);
874 // read certificate (mandatory)
876 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
877 if(retCode != CKM_API_SUCCESS)
879 cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
881 // read CA cert chain (optional)
882 DB::RowVector rawCaChain;
883 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
884 if(retCode != CKM_API_SUCCESS &&
885 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
887 for(auto &rawCaCert : rawCaChain)
888 caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
890 // if anything found, return it
891 if(privKey || cert || caChain.size()>0)
892 retCode = CKM_API_SUCCESS;
897 RawBuffer CKMLogic::getPKCS12(
898 const Credentials &cred,
902 const Password &keyPassword,
903 const Password &certPassword)
905 int retCode = CKM_API_ERROR_UNKNOWN;
907 PKCS12Serializable output;
910 CertificateShPtr cert;
911 CertificateShPtrVector caChain;
912 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
915 if(retCode == CKM_API_SUCCESS)
916 output = PKCS12Serializable(privKey, cert, caChain);
918 } catch (const KeyProvider::Exception::Base &e) {
919 LogError("KeyProvider failed with error: " << e.GetMessage());
920 retCode = CKM_API_ERROR_SERVER_ERROR;
921 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
922 LogError("CryptoLogic failed with message: " << e.GetMessage());
923 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
924 } catch (const CryptoLogic::Exception::Base &e) {
925 LogError("CryptoLogic failed with message: " << e.GetMessage());
926 retCode = CKM_API_ERROR_SERVER_ERROR;
927 } catch (const DB::Crypto::Exception::Base &e) {
928 LogError("DB::Crypto failed with message: " << e.GetMessage());
929 retCode = CKM_API_ERROR_DB_ERROR;
930 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
931 LogError("Error " << e.GetMessage());
932 retCode = CKM_API_ERROR_DB_LOCKED;
933 } catch (const CKM::Exception &e) {
934 LogError("CKM::Exception: " << e.GetMessage());
935 retCode = CKM_API_ERROR_SERVER_ERROR;
938 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
942 return response.Pop();
945 int CKMLogic::getDataListHelper(const Credentials &cred,
946 const DataType dataType,
947 LabelNameVector &labelNameVector)
949 int retCode = CKM_API_ERROR_DB_LOCKED;
950 if (0 < m_userDataMap.count(cred.clientUid))
952 auto &database = m_userDataMap[cred.clientUid].database;
955 LabelNameVector tmpVector;
956 if (dataType.isKey()) {
957 // list all key types
958 database.listNames(cred.smackLabel,
960 DataType::DB_KEY_FIRST,
961 DataType::DB_KEY_LAST);
963 // list anything else
964 database.listNames(cred.smackLabel,
968 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
969 retCode = CKM_API_SUCCESS;
971 Catch (CKM::Exception) {
972 LogError("Failed to get names");
973 retCode = CKM_API_ERROR_DB_ERROR;
979 RawBuffer CKMLogic::getDataList(
980 const Credentials &cred,
984 LabelNameVector systemVector;
985 LabelNameVector userVector;
986 LabelNameVector labelNameVector;
988 int retCode = unlockSystemDB();
989 if (CKM_API_SUCCESS == retCode)
992 if (m_accessControl.isSystemService(cred))
995 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1002 // user - lookup system, then client DB
1003 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1009 if(retCode == CKM_API_SUCCESS)
1011 retCode = getDataListHelper(cred,
1018 if(retCode == CKM_API_SUCCESS)
1020 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1021 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1023 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1026 static_cast<int>(dataType),
1028 return response.Pop();
1031 int CKMLogic::saveDataHelper(
1032 const Credentials &cred,
1036 const RawBuffer &data,
1037 const PolicySerializable &policy)
1039 auto &handler = selectDatabase(cred, label);
1041 // use client label if not explicitly provided
1042 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1043 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1044 return CKM_API_ERROR_INPUT_PARAM;
1046 // check if save is possible
1047 DB::Crypto::Transaction transaction(&handler.database);
1048 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1049 if(retCode != CKM_API_SUCCESS)
1053 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
1054 handler.database.saveRow(encryptedRow);
1056 transaction.commit();
1057 return CKM_API_SUCCESS;
1060 int CKMLogic::saveDataHelper(
1061 const Credentials &cred,
1064 const PKCS12Serializable &pkcs,
1065 const PolicySerializable &keyPolicy,
1066 const PolicySerializable &certPolicy)
1068 auto &handler = selectDatabase(cred, label);
1070 // use client label if not explicitly provided
1071 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1072 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1073 return CKM_API_ERROR_INPUT_PARAM;
1075 // check if save is possible
1076 DB::Crypto::Transaction transaction(&handler.database);
1077 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1078 if(retCode != CKM_API_SUCCESS)
1081 // extract and encrypt the data
1082 DB::RowVector encryptedRows;
1083 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1084 if(retCode != CKM_API_SUCCESS)
1088 handler.database.saveRows(name, ownerLabel, encryptedRows);
1089 transaction.commit();
1091 return CKM_API_SUCCESS;
1095 int CKMLogic::createKeyPairHelper(
1096 const Credentials &cred,
1097 const KeyType key_type,
1098 const int additional_param,
1099 const Name &namePrivate,
1100 const Label &labelPrivate,
1101 const Name &namePublic,
1102 const Label &labelPublic,
1103 const PolicySerializable &policyPrivate,
1104 const PolicySerializable &policyPublic)
1106 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1107 auto &handlerPub = selectDatabase(cred, labelPublic);
1114 case KeyType::KEY_RSA_PUBLIC:
1115 case KeyType::KEY_RSA_PRIVATE:
1116 retCode = Crypto::SW::CryptoService::createKeyPairRSA(additional_param, prv, pub);
1119 case KeyType::KEY_DSA_PUBLIC:
1120 case KeyType::KEY_DSA_PRIVATE:
1121 retCode = Crypto::SW::CryptoService::createKeyPairDSA(additional_param, prv, pub);
1124 case KeyType::KEY_ECDSA_PUBLIC:
1125 case KeyType::KEY_ECDSA_PRIVATE:
1126 retCode = Crypto::SW::CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
1130 return CKM_API_ERROR_INPUT_PARAM;
1133 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
1135 LogDebug("CryptoService error with code: " << retCode);
1136 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
1139 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1140 // in case the same database is used for private and public - the second
1141 // transaction will not be executed
1142 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1144 retCode = saveDataHelper(cred,
1147 DataType(prv.getType()),
1150 if (CKM_API_SUCCESS != retCode)
1153 retCode = saveDataHelper(cred,
1156 DataType(pub.getType()),
1159 if (CKM_API_SUCCESS != retCode)
1162 transactionPub.commit();
1163 transactionPriv.commit();
1168 RawBuffer CKMLogic::createKeyPair(
1169 const Credentials &cred,
1170 LogicCommand protocol_cmd,
1172 const int additional_param,
1173 const Name &namePrivate,
1174 const Label &labelPrivate,
1175 const Name &namePublic,
1176 const Label &labelPublic,
1177 const PolicySerializable &policyPrivate,
1178 const PolicySerializable &policyPublic)
1180 int retCode = CKM_API_SUCCESS;
1182 KeyType key_type = KeyType::KEY_NONE;
1183 switch(protocol_cmd)
1185 case LogicCommand::CREATE_KEY_PAIR_RSA:
1186 key_type = KeyType::KEY_RSA_PUBLIC;
1188 case LogicCommand::CREATE_KEY_PAIR_DSA:
1189 key_type = KeyType::KEY_DSA_PUBLIC;
1191 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
1192 key_type = KeyType::KEY_ECDSA_PUBLIC;
1199 retCode = createKeyPairHelper(
1209 } catch (DB::Crypto::Exception::TransactionError &e) {
1210 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1211 retCode = CKM_API_ERROR_DB_ERROR;
1212 } catch (CKM::CryptoLogic::Exception::Base &e) {
1213 LogDebug("CryptoLogic error: " << e.GetMessage());
1214 retCode = CKM_API_ERROR_SERVER_ERROR;
1215 } catch (DB::Crypto::Exception::InternalError &e) {
1216 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1217 retCode = CKM_API_ERROR_DB_ERROR;
1218 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1219 LogError("Error " << e.GetMessage());
1220 retCode = CKM_API_ERROR_DB_LOCKED;
1221 } catch (const CKM::Exception &e) {
1222 LogError("CKM::Exception: " << e.GetMessage());
1223 retCode = CKM_API_ERROR_SERVER_ERROR;
1226 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
1229 int CKMLogic::readCertificateHelper(
1230 const Credentials &cred,
1231 const LabelNameVector &labelNameVector,
1232 CertificateImplVector &certVector)
1235 for (auto &i: labelNameVector) {
1236 int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1237 if (ec != CKM_API_SUCCESS)
1239 certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1241 // try to read chain certificates (if present)
1242 DB::RowVector rawCaChain;
1243 ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1244 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1246 for(auto &rawCaCert : rawCaChain)
1247 certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1249 return CKM_API_SUCCESS;
1252 int CKMLogic::getCertificateChainHelper(
1253 const CertificateImpl &cert,
1254 const RawBufferVector &untrustedCertificates,
1255 const RawBufferVector &trustedCertificates,
1256 bool useTrustedSystemCertificates,
1257 RawBufferVector &chainRawVector)
1259 CertificateImplVector untrustedCertVector;
1260 CertificateImplVector trustedCertVector;
1261 CertificateImplVector chainVector;
1264 return CKM_API_ERROR_INPUT_PARAM;
1266 for (auto &e: untrustedCertificates)
1267 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1268 for (auto &e: trustedCertificates)
1269 trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1271 CertificateStore store;
1272 int retCode = store.verifyCertificate(cert,
1273 untrustedCertVector,
1275 useTrustedSystemCertificates,
1276 m_accessControl.isCCMode(),
1278 if (retCode != CKM_API_SUCCESS)
1281 for (auto &e : chainVector)
1282 chainRawVector.push_back(e.getDER());
1283 return CKM_API_SUCCESS;
1286 int CKMLogic::getCertificateChainHelper(
1287 const Credentials &cred,
1288 const CertificateImpl &cert,
1289 const LabelNameVector &untrusted,
1290 const LabelNameVector &trusted,
1291 bool useTrustedSystemCertificates,
1292 RawBufferVector &chainRawVector)
1294 CertificateImplVector untrustedCertVector;
1295 CertificateImplVector trustedCertVector;
1296 CertificateImplVector chainVector;
1300 return CKM_API_ERROR_INPUT_PARAM;
1302 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1303 if (retCode != CKM_API_SUCCESS)
1305 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1306 if (retCode != CKM_API_SUCCESS)
1309 CertificateStore store;
1310 retCode = store.verifyCertificate(cert,
1311 untrustedCertVector,
1313 useTrustedSystemCertificates,
1314 m_accessControl.isCCMode(),
1316 if (retCode != CKM_API_SUCCESS)
1319 for (auto &i: chainVector)
1320 chainRawVector.push_back(i.getDER());
1322 return CKM_API_SUCCESS;
1325 RawBuffer CKMLogic::getCertificateChain(
1326 const Credentials & /*cred*/,
1328 const RawBuffer &certificate,
1329 const RawBufferVector &untrustedCertificates,
1330 const RawBufferVector &trustedCertificates,
1331 bool useTrustedSystemCertificates)
1333 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1334 RawBufferVector chainRawVector;
1335 int retCode = CKM_API_ERROR_UNKNOWN;
1337 retCode = getCertificateChainHelper(cert,
1338 untrustedCertificates,
1339 trustedCertificates,
1340 useTrustedSystemCertificates,
1342 } catch (const CryptoLogic::Exception::Base &e) {
1343 LogError("CryptoLogic failed with message: " << e.GetMessage());
1344 retCode = CKM_API_ERROR_SERVER_ERROR;
1345 } catch (const DB::Crypto::Exception::Base &e) {
1346 LogError("DB::Crypto failed with message: " << e.GetMessage());
1347 retCode = CKM_API_ERROR_DB_ERROR;
1348 } catch (const std::exception& e) {
1349 LogError("STD exception " << e.what());
1350 retCode = CKM_API_ERROR_SERVER_ERROR;
1352 LogError("Unknown error.");
1355 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1359 return response.Pop();
1362 RawBuffer CKMLogic::getCertificateChain(
1363 const Credentials &cred,
1365 const RawBuffer &certificate,
1366 const LabelNameVector &untrustedCertificates,
1367 const LabelNameVector &trustedCertificates,
1368 bool useTrustedSystemCertificates)
1370 int retCode = CKM_API_ERROR_UNKNOWN;
1371 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1372 RawBufferVector chainRawVector;
1374 retCode = getCertificateChainHelper(cred,
1376 untrustedCertificates,
1377 trustedCertificates,
1378 useTrustedSystemCertificates,
1380 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1381 LogError("CryptoLogic failed with message: " << e.GetMessage());
1382 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1383 } catch (const CryptoLogic::Exception::Base &e) {
1384 LogError("CryptoLogic failed with message: " << e.GetMessage());
1385 retCode = CKM_API_ERROR_SERVER_ERROR;
1386 } catch (const DB::Crypto::Exception::Base &e) {
1387 LogError("DB::Crypto failed with message: " << e.GetMessage());
1388 retCode = CKM_API_ERROR_DB_ERROR;
1389 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1390 LogError("Error " << e.GetMessage());
1391 retCode = CKM_API_ERROR_DB_LOCKED;
1392 } catch (const std::exception& e) {
1393 LogError("STD exception " << e.what());
1394 retCode = CKM_API_ERROR_SERVER_ERROR;
1396 LogError("Unknown error.");
1399 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1403 return response.Pop();
1406 RawBuffer CKMLogic::createSignature(
1407 const Credentials &cred,
1409 const Name &privateKeyName,
1410 const Label & ownerLabel,
1411 const Password &password, // password for private_key
1412 const RawBuffer &message,
1413 const HashAlgorithm hash,
1414 const RSAPaddingAlgorithm padding)
1417 Crypto::SW::CryptoService cs;
1418 RawBuffer signature;
1420 int retCode = CKM_API_SUCCESS;
1423 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1424 if(retCode == CKM_API_SUCCESS)
1426 KeyImpl keyParsed(row.data, Password());
1427 if (keyParsed.empty())
1428 retCode = CKM_API_ERROR_SERVER_ERROR;
1430 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
1432 } catch (const KeyProvider::Exception::Base &e) {
1433 LogError("KeyProvider failed with message: " << e.GetMessage());
1434 retCode = CKM_API_ERROR_SERVER_ERROR;
1435 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1436 LogError("CryptoLogic failed with message: " << e.GetMessage());
1437 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1438 } catch (const CryptoLogic::Exception::Base &e) {
1439 LogError("CryptoLogic failed with message: " << e.GetMessage());
1440 retCode = CKM_API_ERROR_SERVER_ERROR;
1441 } catch (const DB::Crypto::Exception::Base &e) {
1442 LogError("DB::Crypto failed with message: " << e.GetMessage());
1443 retCode = CKM_API_ERROR_DB_ERROR;
1444 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1445 LogError("Error " << e.GetMessage());
1446 retCode = CKM_API_ERROR_DB_LOCKED;
1447 } catch (const CKM::Exception &e) {
1448 LogError("Unknown CKM::Exception: " << e.GetMessage());
1449 retCode = CKM_API_ERROR_SERVER_ERROR;
1452 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1456 return response.Pop();
1459 RawBuffer CKMLogic::verifySignature(
1460 const Credentials &cred,
1462 const Name &publicKeyOrCertName,
1463 const Label & ownerLabel,
1464 const Password &password, // password for public_key (optional)
1465 const RawBuffer &message,
1466 const RawBuffer &signature,
1467 const HashAlgorithm hash,
1468 const RSAPaddingAlgorithm padding)
1470 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1474 Crypto::SW::CryptoService cs;
1478 // try certificate first - looking for a public key.
1479 // in case of PKCS, pub key from certificate will be found first
1480 // rather than private key from the same PKCS.
1481 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
1482 if (retCode == CKM_API_SUCCESS) {
1483 CertificateImpl cert(row.data, DataFormat::FORM_DER);
1484 key = cert.getKeyImpl();
1485 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1486 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
1487 if (retCode != CKM_API_SUCCESS)
1489 key = KeyImpl(row.data);
1495 retCode = CKM_API_ERROR_SERVER_ERROR;
1499 retCode = cs.verifySignature(key, message, signature, hash, padding);
1501 } catch (const Crypto::SW::CryptoService::Exception::Crypto_internal &e) {
1502 LogError("KeyProvider failed with message: " << e.GetMessage());
1503 retCode = CKM_API_ERROR_SERVER_ERROR;
1504 } catch (const Crypto::SW::CryptoService::Exception::opensslError &e) {
1505 LogError("KeyProvider failed with message: " << e.GetMessage());
1506 retCode = CKM_API_ERROR_SERVER_ERROR;
1507 } catch (const KeyProvider::Exception::Base &e) {
1508 LogError("KeyProvider failed with error: " << e.GetMessage());
1509 retCode = CKM_API_ERROR_SERVER_ERROR;
1510 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1511 LogError("CryptoLogic failed with message: " << e.GetMessage());
1512 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1513 } catch (const CryptoLogic::Exception::Base &e) {
1514 LogError("CryptoLogic failed with message: " << e.GetMessage());
1515 retCode = CKM_API_ERROR_SERVER_ERROR;
1516 } catch (const DB::Crypto::Exception::Base &e) {
1517 LogError("DB::Crypto failed with message: " << e.GetMessage());
1518 retCode = CKM_API_ERROR_DB_ERROR;
1519 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1520 LogError("Error " << e.GetMessage());
1521 retCode = CKM_API_ERROR_DB_LOCKED;
1522 } catch (const CKM::Exception &e) {
1523 LogError("Unknown CKM::Exception: " << e.GetMessage());
1524 retCode = CKM_API_ERROR_SERVER_ERROR;
1527 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1530 return response.Pop();
1533 int CKMLogic::setPermissionHelper(
1534 const Credentials &cred, // who's the client
1536 const Label &label, // who's the owner
1537 const Label &accessorLabel, // who will get the access
1538 const PermissionMask permissionMask)
1540 auto &handler = selectDatabase(cred, label);
1542 // we don't know the client
1543 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1544 return CKM_API_ERROR_INPUT_PARAM;
1546 // use client label if not explicitly provided
1547 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1549 // verify name and label are correct
1550 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1551 return CKM_API_ERROR_INPUT_PARAM;
1553 // currently we don't support modification of owner's permissions to his own rows
1554 if (ownerLabel==accessorLabel)
1555 return CKM_API_ERROR_INPUT_PARAM;
1557 // system database does not support write/remove permissions
1558 if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
1559 (permissionMask & Permission::REMOVE))
1560 return CKM_API_ERROR_INPUT_PARAM;
1562 // can the client modify permissions to owner's row?
1563 int retCode = m_accessControl.canModify(cred, ownerLabel);
1564 if(retCode != CKM_API_SUCCESS)
1567 DB::Crypto::Transaction transaction(&handler.database);
1569 if( !handler.database.isNameLabelPresent(name, ownerLabel) )
1570 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1572 // removing non-existing permissions: fail
1573 if(permissionMask == Permission::NONE)
1575 if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1576 return CKM_API_ERROR_INPUT_PARAM;
1579 // set permissions to the row owned by ownerLabel for accessorLabel
1580 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1581 transaction.commit();
1583 return CKM_API_SUCCESS;
1586 RawBuffer CKMLogic::setPermission(
1587 const Credentials &cred,
1592 const Label &accessorLabel,
1593 const PermissionMask permissionMask)
1597 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1598 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1599 LogError("Error " << e.GetMessage());
1600 retCode = CKM_API_ERROR_DB_LOCKED;
1601 } Catch (CKM::Exception) {
1602 LogError("Error in set row!");
1603 retCode = CKM_API_ERROR_DB_ERROR;
1606 return MessageBuffer::Serialize(command, msgID, retCode).Pop();