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 <generic-backend/exception.h>
34 #include <sw-backend/crypto-service.h>
37 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
38 const uid_t SYSTEM_DB_UID = 0;
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
59 CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR);
61 m_accessControl.updateCCMode();
64 CKMLogic::~CKMLogic(){}
66 void CKMLogic::loadDKEKFile(uid_t user, const Password &password) {
67 auto &handle = m_userDataMap[user];
71 auto wrappedDKEK = fs.getDKEK();
73 if (wrappedDKEK.empty()) {
74 wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
75 fs.saveDKEK(wrappedDKEK);
78 handle.keyProvider = KeyProvider(wrappedDKEK, password);
81 void CKMLogic::saveDKEKFile(uid_t user, const Password &password) {
82 auto &handle = m_userDataMap[user];
85 fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password));
88 int CKMLogic::unlockDatabase(uid_t user, const Password & password)
90 if (0<m_userDataMap.count(user) && m_userDataMap[user].keyProvider.isInitialized())
91 return CKM_API_SUCCESS;
93 int retCode = CKM_API_SUCCESS;
96 auto &handle = m_userDataMap[user];
99 loadDKEKFile(user, password);
101 auto wrappedDatabaseDEK = fs.getDBDEK();
102 if (wrappedDatabaseDEK.empty()) {
103 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
104 fs.saveDBDEK(wrappedDatabaseDEK);
107 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
109 handle.database = DB::Crypto(fs.getDBPath(), key);
110 handle.crypto = CryptoLogic();
112 if ( !m_accessControl.isSystemService(user) )
114 // remove data of removed apps during locked state
115 AppLabelVector removedApps = fs.clearRemovedsApps();
116 for(auto& appSmackLabel : removedApps) {
117 handle.crypto.removeKey(appSmackLabel);
118 handle.database.deleteKey(appSmackLabel);
121 } catch (const KeyProvider::Exception::PassWordError &e) {
122 LogError("Incorrect Password " << e.GetMessage());
123 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
124 } catch (const KeyProvider::Exception::Base &e) {
125 LogError("Error in KeyProvider " << e.GetMessage());
126 retCode = CKM_API_ERROR_SERVER_ERROR;
127 } catch (const CryptoLogic::Exception::Base &e) {
128 LogError("CryptoLogic error: " << e.GetMessage());
129 retCode = CKM_API_ERROR_SERVER_ERROR;
130 } catch (const FileSystem::Exception::Base &e) {
131 LogError("FileSystem error: " << e.GetMessage());
132 retCode = CKM_API_ERROR_FILE_SYSTEM;
133 } catch (const CKM::Exception &e) {
134 LogError("CKM::Exception: " << e.GetMessage());
135 retCode = CKM_API_ERROR_SERVER_ERROR;
138 if (CKM_API_SUCCESS != retCode)
139 m_userDataMap.erase(user);
144 int CKMLogic::unlockSystemDB()
146 return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD);
149 UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label)
151 // if user trying to access system service - check:
152 // * if user database is unlocked [mandatory]
153 // * if not - proceed with regular user database
154 // * if explicit system database label given -> switch to system DB
155 if ( !m_accessControl.isSystemService(cred) )
157 if (0 == m_userDataMap.count(cred.clientUid))
158 ThrowMsg(Exception::DatabaseLocked, "database with UID: " << cred.clientUid << " locked");
160 if (0 != incoming_label.compare(LABEL_SYSTEM_DB))
161 return m_userDataMap[cred.clientUid];
164 // system database selected, modify the label
165 if (CKM_API_SUCCESS != unlockSystemDB() )
166 ThrowMsg(Exception::DatabaseLocked, "can not unlock system database");
167 return m_userDataMap[SYSTEM_DB_UID];
170 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password)
172 int retCode = CKM_API_SUCCESS;
174 if( !m_accessControl.isSystemService(user) )
176 retCode = unlockDatabase(user, password);
180 // do not allow lock/unlock operations for system users
181 retCode = CKM_API_ERROR_INPUT_PARAM;
184 return MessageBuffer::Serialize(retCode).Pop();
187 RawBuffer CKMLogic::updateCCMode() {
188 m_accessControl.updateCCMode();
189 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
192 RawBuffer CKMLogic::lockUserKey(uid_t user)
194 int retCode = CKM_API_SUCCESS;
195 if( !m_accessControl.isSystemService(user) )
197 m_userDataMap.erase(user);
201 // do not allow lock/unlock operations for system users
202 retCode = CKM_API_ERROR_INPUT_PARAM;
205 return MessageBuffer::Serialize(retCode).Pop();
209 RawBuffer CKMLogic::removeUserData(uid_t user) {
210 int retCode = CKM_API_SUCCESS;
212 if (m_accessControl.isSystemService(user))
213 user = SYSTEM_DB_UID;
215 m_userDataMap.erase(user);
220 return MessageBuffer::Serialize(retCode).Pop();
223 int CKMLogic::changeUserPasswordHelper(uid_t user,
224 const Password &oldPassword,
225 const Password &newPassword)
227 // do not allow to change system database password
228 if( m_accessControl.isSystemService(user) )
229 return CKM_API_ERROR_INPUT_PARAM;
231 loadDKEKFile(user, oldPassword);
232 saveDKEKFile(user, newPassword);
234 return CKM_API_SUCCESS;
237 RawBuffer CKMLogic::changeUserPassword(
239 const Password &oldPassword,
240 const Password &newPassword)
242 int retCode = CKM_API_SUCCESS;
245 retCode = changeUserPasswordHelper(user, oldPassword, 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;
260 return MessageBuffer::Serialize(retCode).Pop();
263 int CKMLogic::resetUserPasswordHelper(
265 const Password &newPassword)
267 // do not allow to reset system database password
268 if( m_accessControl.isSystemService(user) )
269 return CKM_API_ERROR_INPUT_PARAM;
271 int retCode = CKM_API_SUCCESS;
272 if (0 == m_userDataMap.count(user))
274 // Check if key exists. If exists we must return error
276 auto wrappedDKEKMain = fs.getDKEK();
277 if (!wrappedDKEKMain.empty())
278 retCode = CKM_API_ERROR_BAD_REQUEST;
280 saveDKEKFile(user, newPassword);
286 RawBuffer CKMLogic::resetUserPassword(
288 const Password &newPassword)
290 int retCode = CKM_API_SUCCESS;
292 retCode = resetUserPasswordHelper(user, newPassword);
293 } catch (const FileSystem::Exception::Base &e) {
294 LogError("Error in FileSystem " << e.GetMessage());
295 retCode = CKM_API_ERROR_FILE_SYSTEM;
296 } catch (const CKM::Exception &e) {
297 LogError("CKM::Exception: " << e.GetMessage());
298 retCode = CKM_API_ERROR_SERVER_ERROR;
301 return MessageBuffer::Serialize(retCode).Pop();
304 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
305 int retCode = CKM_API_SUCCESS;
309 if (smackLabel.empty()) {
310 retCode = CKM_API_ERROR_INPUT_PARAM;
312 UidVector uids = FileSystem::getUIDsFromDBFile();
313 for (auto userId : uids) {
314 if (0 == m_userDataMap.count(userId)) {
315 FileSystem fs(userId);
316 fs.addRemovedApp(smackLabel);
318 auto &handle = m_userDataMap[userId];
319 handle.crypto.removeKey(smackLabel);
320 handle.database.deleteKey(smackLabel);
325 } catch (const DB::Crypto::Exception::InternalError &e) {
326 LogError("DB::Crypto couldn't remove data: " << e.GetMessage());
327 retCode = CKM_API_ERROR_DB_ERROR;
328 } catch (const DB::Crypto::Exception::TransactionError &e) {
329 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
330 retCode = CKM_API_ERROR_DB_ERROR;
331 } catch (const FileSystem::Exception::Base &e) {
332 LogError("Error in FileSystem " << e.GetMessage());
333 retCode = CKM_API_ERROR_FILE_SYSTEM;
334 } catch (const CKM::Exception &e) {
335 LogError("CKM::Exception: " << e.GetMessage());
336 retCode = CKM_API_ERROR_SERVER_ERROR;
339 return MessageBuffer::Serialize(retCode).Pop();
342 int CKMLogic::checkSaveConditions(
343 const Credentials &cred,
346 const Label &ownerLabel)
348 // verify name and label are correct
349 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
350 LogWarning("Invalid parameter passed to key-manager");
351 return CKM_API_ERROR_INPUT_PARAM;
354 // check if allowed to save using ownerLabel
355 int access_ec = m_accessControl.canSave(cred, ownerLabel);
356 if( access_ec != CKM_API_SUCCESS)
358 LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
362 // check if not a duplicate
363 if( handler.database.isNameLabelPresent(name, ownerLabel))
364 return CKM_API_ERROR_DB_ALIAS_EXISTS;
366 // encryption section
367 if (!handler.crypto.haveKey(ownerLabel))
370 auto key_optional = handler.database.getKey(ownerLabel);
372 LogDebug("No Key in database found. Generating new one for label: " << ownerLabel);
373 got_key = handler.keyProvider.generateDEK(ownerLabel);
374 handler.database.saveKey(ownerLabel, got_key);
376 LogDebug("Key from DB");
377 got_key = *key_optional;
380 got_key = handler.keyProvider.getPureDEK(got_key);
381 handler.crypto.pushKey(ownerLabel, got_key);
384 return CKM_API_SUCCESS;
387 DB::Row CKMLogic::createEncryptedRow(
392 const RawBuffer &data,
393 const Policy &policy) const
395 DB::Row row(name, label, static_cast<int>(policy.extractable), dataType, data, static_cast<int>(data.size()));
396 row.backendId = m_decider.chooseCryptoBackend(dataType, policy);
398 // do not encrypt data with password during cc_mode on
399 if(m_accessControl.isCCMode()) {
400 crypto.encryptRow("", row);
402 crypto.encryptRow(policy.password, row);
407 int CKMLogic::verifyBinaryData(DataType dataType, const RawBuffer &input_data) const
409 // verify the data integrity
410 if (dataType.isKey())
412 KeyShPtr output_key = CKM::Key::create(input_data);
413 if(output_key.get() == NULL)
415 LogError("provided binary data is not valid key data");
416 return CKM_API_ERROR_INPUT_PARAM;
419 else if (dataType.isCertificate() || dataType.isChainCert())
421 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
422 if(cert.get() == NULL)
424 LogError("provided binary data is not valid certificate data");
425 return CKM_API_ERROR_INPUT_PARAM;
428 // TODO: add here BINARY_DATA verification, i.e: max size etc.
429 return CKM_API_SUCCESS;
432 RawBuffer CKMLogic::saveData(
433 const Credentials &cred,
437 const RawBuffer &data,
439 const PolicySerializable &policy)
441 int retCode = CKM_API_ERROR_UNKNOWN;
444 // check if data is correct
445 retCode = verifyBinaryData(dataType, data);
446 if(retCode == CKM_API_SUCCESS)
448 retCode = saveDataHelper(cred, name, label, dataType, data, policy);
450 } catch (const KeyProvider::Exception::Base &e) {
451 LogError("KeyProvider failed with message: " << e.GetMessage());
452 retCode = CKM_API_ERROR_SERVER_ERROR;
453 } catch (const CryptoLogic::Exception::Base &e) {
454 LogError("CryptoLogic failed with message: " << e.GetMessage());
455 retCode = CKM_API_ERROR_SERVER_ERROR;
456 } catch (const DB::Crypto::Exception::InternalError &e) {
457 LogError("DB::Crypto failed with message: " << e.GetMessage());
458 retCode = CKM_API_ERROR_DB_ERROR;
459 } catch (const DB::Crypto::Exception::TransactionError &e) {
460 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
461 retCode = CKM_API_ERROR_DB_ERROR;
462 } catch (const FileSystem::Exception::Base &e) {
463 LogError("Error in FileSystem " << e.GetMessage());
464 retCode = CKM_API_ERROR_FILE_SYSTEM;
465 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
466 LogError("Error " << e.GetMessage());
467 retCode = CKM_API_ERROR_DB_LOCKED;
468 } catch (const CKM::Exception &e) {
469 LogError("CKM::Exception: " << e.GetMessage());
470 retCode = CKM_API_ERROR_SERVER_ERROR;
473 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
476 static_cast<int>(dataType));
477 return response.Pop();
480 int CKMLogic::extractPKCS12Data(
483 const Label &ownerLabel,
484 const PKCS12Serializable &pkcs,
485 const PolicySerializable &keyPolicy,
486 const PolicySerializable &certPolicy,
487 DB::RowVector &output) const
489 // private key is mandatory
491 return CKM_API_ERROR_INVALID_FORMAT;
492 Key* keyPtr = pkcs.getKey().get();
493 DataType keyType = DataType(keyPtr->getType());
494 RawBuffer keyData = keyPtr->getDER();
495 int retCode = verifyBinaryData(keyType, keyData);
496 if(retCode != CKM_API_SUCCESS)
498 output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyType, keyData, keyPolicy));
500 // certificate is mandatory
501 if( !pkcs.getCertificate() )
502 return CKM_API_ERROR_INVALID_FORMAT;
503 RawBuffer certData = pkcs.getCertificate().get()->getDER();
504 retCode = verifyBinaryData(DataType::CERTIFICATE, certData);
505 if(retCode != CKM_API_SUCCESS)
507 output.push_back(createEncryptedRow(crypto, name, ownerLabel, DataType::CERTIFICATE, certData, certPolicy));
510 unsigned int cert_index = 0;
511 for(const auto & ca : pkcs.getCaCertificateShPtrVector())
513 DataType chainDataType = DataType::getChainDatatype(cert_index ++);
514 RawBuffer caCertData = ca->getDER();
515 int retCode = verifyBinaryData(chainDataType, caCertData);
516 if(retCode != CKM_API_SUCCESS)
519 output.push_back(createEncryptedRow(crypto, name, ownerLabel, chainDataType, caCertData, certPolicy));
522 return CKM_API_SUCCESS;
525 RawBuffer CKMLogic::savePKCS12(
526 const Credentials &cred,
530 const PKCS12Serializable &pkcs,
531 const PolicySerializable &keyPolicy,
532 const PolicySerializable &certPolicy)
534 int retCode = CKM_API_ERROR_UNKNOWN;
536 retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy);
537 } catch (const KeyProvider::Exception::Base &e) {
538 LogError("KeyProvider failed with message: " << e.GetMessage());
539 retCode = CKM_API_ERROR_SERVER_ERROR;
540 } catch (const CryptoLogic::Exception::Base &e) {
541 LogError("CryptoLogic failed with message: " << e.GetMessage());
542 retCode = CKM_API_ERROR_SERVER_ERROR;
543 } catch (const DB::Crypto::Exception::InternalError &e) {
544 LogError("DB::Crypto failed with message: " << e.GetMessage());
545 retCode = CKM_API_ERROR_DB_ERROR;
546 } catch (const DB::Crypto::Exception::TransactionError &e) {
547 LogError("DB::Crypto transaction failed with message " << e.GetMessage());
548 retCode = CKM_API_ERROR_DB_ERROR;
549 } catch (const CKM::Exception &e) {
550 LogError("CKM::Exception: " << e.GetMessage());
551 retCode = CKM_API_ERROR_SERVER_ERROR;
554 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12),
557 return response.Pop();
561 int CKMLogic::removeDataHelper(
562 const Credentials &cred,
566 auto &handler = selectDatabase(cred, label);
568 // use client label if not explicitly provided
569 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
570 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
571 LogError("Invalid label or name format");
572 return CKM_API_ERROR_INPUT_PARAM;
575 DB::Crypto::Transaction transaction(&handler.database);
577 // read and check permissions
578 PermissionMaskOptional permissionRowOpt =
579 handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel);
580 int retCode = m_accessControl.canDelete(cred,
581 PermissionForLabel(cred.smackLabel, permissionRowOpt));
582 if(retCode != CKM_API_SUCCESS)
584 LogWarning("access control check result: " << retCode);
588 auto erased = handler.database.deleteRow(name, ownerLabel);
589 // check if the data existed or not
591 transaction.commit();
593 LogError("No row for given name and label");
594 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
597 return CKM_API_SUCCESS;
600 RawBuffer CKMLogic::removeData(
601 const Credentials &cred,
606 int retCode = CKM_API_ERROR_UNKNOWN;
610 retCode = removeDataHelper(cred, name, label);
612 catch (const CKMLogic::Exception::DatabaseLocked &e)
614 LogError("Error " << e.GetMessage());
615 retCode = CKM_API_ERROR_DB_LOCKED;
617 catch (const CKM::Exception &)
619 LogError("Error in deleting row!");
620 retCode = CKM_API_ERROR_DB_ERROR;
623 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
626 return response.Pop();
629 int CKMLogic::readSingleRow(const Name &name,
630 const Label &ownerLabel,
632 DB::Crypto & database,
635 DB::Crypto::RowOptional row_optional;
636 if (dataType.isKey())
638 // read all key types
639 row_optional = database.getRow(name,
641 DataType::DB_KEY_FIRST,
642 DataType::DB_KEY_LAST);
644 // read anything else
645 row_optional = database.getRow(name,
651 LogError("No row for given name, label and type");
652 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
657 return CKM_API_SUCCESS;
661 int CKMLogic::readMultiRow(const Name &name,
662 const Label &ownerLabel,
664 DB::Crypto & database,
665 DB::RowVector &output)
667 if (dataType.isKey())
669 // read all key types
670 database.getRows(name,
672 DataType::DB_KEY_FIRST,
673 DataType::DB_KEY_LAST,
676 else if (dataType.isChainCert())
678 // read all key types
679 database.getRows(name,
681 DataType::DB_CHAIN_FIRST,
682 DataType::DB_CHAIN_LAST,
687 // read anything else
688 database.getRows(name,
695 LogError("No row for given name, label and type");
696 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
699 return CKM_API_SUCCESS;
702 int CKMLogic::checkDataPermissionsHelper(const Credentials &cred,
704 const Label &ownerLabel,
705 const Label &accessorLabel,
708 DB::Crypto & database)
710 PermissionMaskOptional permissionRowOpt =
711 database.getPermissionRow(name, ownerLabel, accessorLabel);
714 return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt));
715 return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt));
718 int CKMLogic::readDataHelper(
720 const Credentials &cred,
724 const Password &password,
727 auto &handler = selectDatabase(cred, label);
729 // use client label if not explicitly provided
730 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
732 if (!isNameValid(name) || !isLabelValid(ownerLabel))
733 return CKM_API_ERROR_INPUT_PARAM;
736 DB::Crypto::Transaction transaction(&handler.database);
737 int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows);
738 if(CKM_API_SUCCESS != retCode)
741 // all read rows belong to the same owner
742 DB::Row & firstRow = rows.at(0);
744 // check access rights
745 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database);
746 if(CKM_API_SUCCESS != retCode)
750 if (!handler.crypto.haveKey(firstRow.ownerLabel)) {
752 auto key_optional = handler.database.getKey(firstRow.ownerLabel);
754 LogError("No key for given label in database");
755 return CKM_API_ERROR_DB_ERROR;
758 key = handler.keyProvider.getPureDEK(key);
759 handler.crypto.pushKey(firstRow.ownerLabel, key);
761 for(auto &row : rows)
762 handler.crypto.decryptRow(password, row);
764 return CKM_API_SUCCESS;
767 int CKMLogic::readDataHelper(
769 const Credentials &cred,
773 const Password &password,
776 auto &handler = selectDatabase(cred, label);
778 // use client label if not explicitly provided
779 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
781 if (!isNameValid(name) || !isLabelValid(ownerLabel))
782 return CKM_API_ERROR_INPUT_PARAM;
785 DB::Crypto::Transaction transaction(&handler.database);
786 int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row);
787 if(CKM_API_SUCCESS != retCode)
790 // check access rights
791 retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
792 if(CKM_API_SUCCESS != retCode)
796 if (!handler.crypto.haveKey(row.ownerLabel)) {
798 auto key_optional = handler.database.getKey(row.ownerLabel);
800 LogError("No key for given label in database");
801 return CKM_API_ERROR_DB_ERROR;
804 key = handler.keyProvider.getPureDEK(key);
805 handler.crypto.pushKey(row.ownerLabel, key);
807 handler.crypto.decryptRow(password, row);
809 return CKM_API_SUCCESS;
812 RawBuffer CKMLogic::getData(
813 const Credentials &cred,
818 const Password &password)
820 int retCode = CKM_API_SUCCESS;
824 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
825 } catch (const KeyProvider::Exception::Base &e) {
826 LogError("KeyProvider failed with error: " << e.GetMessage());
827 retCode = CKM_API_ERROR_SERVER_ERROR;
828 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
829 LogError("CryptoLogic failed with message: " << e.GetMessage());
830 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
831 } catch (const CryptoLogic::Exception::Base &e) {
832 LogError("CryptoLogic failed with message: " << e.GetMessage());
833 retCode = CKM_API_ERROR_SERVER_ERROR;
834 } catch (const DB::Crypto::Exception::Base &e) {
835 LogError("DB::Crypto failed with message: " << e.GetMessage());
836 retCode = CKM_API_ERROR_DB_ERROR;
837 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
838 LogError("Error " << e.GetMessage());
839 retCode = CKM_API_ERROR_DB_LOCKED;
840 } catch (const CKM::Exception &e) {
841 LogError("CKM::Exception: " << e.GetMessage());
842 retCode = CKM_API_ERROR_SERVER_ERROR;
845 if (CKM_API_SUCCESS != retCode) {
847 row.dataType = dataType;
850 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
853 static_cast<int>(row.dataType),
855 return response.Pop();
858 int CKMLogic::getPKCS12Helper(
859 const Credentials &cred,
862 const Password &keyPassword,
863 const Password &certPassword,
865 CertificateShPtr & cert,
866 CertificateShPtrVector & caChain)
870 // read private key (mandatory)
872 retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, privKeyRow);
873 if(retCode != CKM_API_SUCCESS)
875 privKey = CKM::Key::create(privKeyRow.data);
877 // read certificate (mandatory)
879 retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certRow);
880 if(retCode != CKM_API_SUCCESS)
882 cert = CKM::Certificate::create(certRow.data, DataFormat::FORM_DER);
884 // read CA cert chain (optional)
885 DB::RowVector rawCaChain;
886 retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, rawCaChain);
887 if(retCode != CKM_API_SUCCESS &&
888 retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
890 for(auto &rawCaCert : rawCaChain)
891 caChain.push_back(CKM::Certificate::create(rawCaCert.data, DataFormat::FORM_DER));
893 // if anything found, return it
894 if(privKey || cert || caChain.size()>0)
895 retCode = CKM_API_SUCCESS;
900 RawBuffer CKMLogic::getPKCS12(
901 const Credentials &cred,
905 const Password &keyPassword,
906 const Password &certPassword)
908 int retCode = CKM_API_ERROR_UNKNOWN;
910 PKCS12Serializable output;
913 CertificateShPtr cert;
914 CertificateShPtrVector caChain;
915 retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain);
918 if(retCode == CKM_API_SUCCESS)
919 output = PKCS12Serializable(privKey, cert, caChain);
921 } catch (const KeyProvider::Exception::Base &e) {
922 LogError("KeyProvider failed with error: " << e.GetMessage());
923 retCode = CKM_API_ERROR_SERVER_ERROR;
924 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
925 LogError("CryptoLogic failed with message: " << e.GetMessage());
926 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
927 } catch (const CryptoLogic::Exception::Base &e) {
928 LogError("CryptoLogic failed with message: " << e.GetMessage());
929 retCode = CKM_API_ERROR_SERVER_ERROR;
930 } catch (const DB::Crypto::Exception::Base &e) {
931 LogError("DB::Crypto failed with message: " << e.GetMessage());
932 retCode = CKM_API_ERROR_DB_ERROR;
933 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
934 LogError("Error " << e.GetMessage());
935 retCode = CKM_API_ERROR_DB_LOCKED;
936 } catch (const CKM::Exception &e) {
937 LogError("CKM::Exception: " << e.GetMessage());
938 retCode = CKM_API_ERROR_SERVER_ERROR;
941 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12),
945 return response.Pop();
948 int CKMLogic::getDataListHelper(const Credentials &cred,
949 const DataType dataType,
950 LabelNameVector &labelNameVector)
952 int retCode = CKM_API_ERROR_DB_LOCKED;
953 if (0 < m_userDataMap.count(cred.clientUid))
955 auto &database = m_userDataMap[cred.clientUid].database;
958 LabelNameVector tmpVector;
959 if (dataType.isKey()) {
960 // list all key types
961 database.listNames(cred.smackLabel,
963 DataType::DB_KEY_FIRST,
964 DataType::DB_KEY_LAST);
966 // list anything else
967 database.listNames(cred.smackLabel,
971 labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end());
972 retCode = CKM_API_SUCCESS;
974 Catch (CKM::Exception) {
975 LogError("Failed to get names");
976 retCode = CKM_API_ERROR_DB_ERROR;
982 RawBuffer CKMLogic::getDataList(
983 const Credentials &cred,
987 LabelNameVector systemVector;
988 LabelNameVector userVector;
989 LabelNameVector labelNameVector;
991 int retCode = unlockSystemDB();
992 if (CKM_API_SUCCESS == retCode)
995 if (m_accessControl.isSystemService(cred))
998 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1005 // user - lookup system, then client DB
1006 retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
1012 if(retCode == CKM_API_SUCCESS)
1014 retCode = getDataListHelper(cred,
1021 if(retCode == CKM_API_SUCCESS)
1023 labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end());
1024 labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end());
1026 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
1029 static_cast<int>(dataType),
1031 return response.Pop();
1034 int CKMLogic::saveDataHelper(
1035 const Credentials &cred,
1039 const RawBuffer &data,
1040 const PolicySerializable &policy)
1042 auto &handler = selectDatabase(cred, label);
1044 // use client label if not explicitly provided
1045 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1046 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1047 return CKM_API_ERROR_INPUT_PARAM;
1049 // check if save is possible
1050 DB::Crypto::Transaction transaction(&handler.database);
1051 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1052 if(retCode != CKM_API_SUCCESS)
1056 DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, dataType, data, policy);
1057 handler.database.saveRow(encryptedRow);
1059 transaction.commit();
1060 return CKM_API_SUCCESS;
1063 int CKMLogic::saveDataHelper(
1064 const Credentials &cred,
1067 const PKCS12Serializable &pkcs,
1068 const PolicySerializable &keyPolicy,
1069 const PolicySerializable &certPolicy)
1071 auto &handler = selectDatabase(cred, label);
1073 // use client label if not explicitly provided
1074 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
1075 if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
1076 return CKM_API_ERROR_INPUT_PARAM;
1078 // check if save is possible
1079 DB::Crypto::Transaction transaction(&handler.database);
1080 int retCode = checkSaveConditions(cred, handler, name, ownerLabel);
1081 if(retCode != CKM_API_SUCCESS)
1084 // extract and encrypt the data
1085 DB::RowVector encryptedRows;
1086 retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows);
1087 if(retCode != CKM_API_SUCCESS)
1091 handler.database.saveRows(name, ownerLabel, encryptedRows);
1092 transaction.commit();
1094 return CKM_API_SUCCESS;
1098 int CKMLogic::createKeyPairHelper(
1099 const Credentials &cred,
1100 const KeyType key_type,
1101 const int additional_param,
1102 const Name &namePrivate,
1103 const Label &labelPrivate,
1104 const Name &namePublic,
1105 const Label &labelPublic,
1106 const PolicySerializable &policyPrivate,
1107 const PolicySerializable &policyPublic)
1109 auto &handlerPriv = selectDatabase(cred, labelPrivate);
1110 auto &handlerPub = selectDatabase(cred, labelPublic);
1117 case KeyType::KEY_RSA_PUBLIC:
1118 case KeyType::KEY_RSA_PRIVATE:
1119 retCode = Crypto::SW::CryptoService::createKeyPairRSA(additional_param, prv, pub);
1122 case KeyType::KEY_DSA_PUBLIC:
1123 case KeyType::KEY_DSA_PRIVATE:
1124 retCode = Crypto::SW::CryptoService::createKeyPairDSA(additional_param, prv, pub);
1127 case KeyType::KEY_ECDSA_PUBLIC:
1128 case KeyType::KEY_ECDSA_PRIVATE:
1129 retCode = Crypto::SW::CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
1133 return CKM_API_ERROR_INPUT_PARAM;
1136 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
1138 LogDebug("CryptoService error with code: " << retCode);
1139 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
1142 DB::Crypto::Transaction transactionPriv(&handlerPriv.database);
1143 // in case the same database is used for private and public - the second
1144 // transaction will not be executed
1145 DB::Crypto::Transaction transactionPub(&handlerPub.database);
1147 retCode = saveDataHelper(cred,
1150 DataType(prv.getType()),
1153 if (CKM_API_SUCCESS != retCode)
1156 retCode = saveDataHelper(cred,
1159 DataType(pub.getType()),
1162 if (CKM_API_SUCCESS != retCode)
1165 transactionPub.commit();
1166 transactionPriv.commit();
1171 RawBuffer CKMLogic::createKeyPair(
1172 const Credentials &cred,
1173 LogicCommand protocol_cmd,
1175 const int additional_param,
1176 const Name &namePrivate,
1177 const Label &labelPrivate,
1178 const Name &namePublic,
1179 const Label &labelPublic,
1180 const PolicySerializable &policyPrivate,
1181 const PolicySerializable &policyPublic)
1183 int retCode = CKM_API_SUCCESS;
1185 KeyType key_type = KeyType::KEY_NONE;
1186 switch(protocol_cmd)
1188 case LogicCommand::CREATE_KEY_PAIR_RSA:
1189 key_type = KeyType::KEY_RSA_PUBLIC;
1191 case LogicCommand::CREATE_KEY_PAIR_DSA:
1192 key_type = KeyType::KEY_DSA_PUBLIC;
1194 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
1195 key_type = KeyType::KEY_ECDSA_PUBLIC;
1202 retCode = createKeyPairHelper(
1212 } catch (DB::Crypto::Exception::TransactionError &e) {
1213 LogDebug("DB::Crypto error: transaction error: " << e.GetMessage());
1214 retCode = CKM_API_ERROR_DB_ERROR;
1215 } catch (CKM::CryptoLogic::Exception::Base &e) {
1216 LogDebug("CryptoLogic error: " << e.GetMessage());
1217 retCode = CKM_API_ERROR_SERVER_ERROR;
1218 } catch (DB::Crypto::Exception::InternalError &e) {
1219 LogDebug("DB::Crypto internal error: " << e.GetMessage());
1220 retCode = CKM_API_ERROR_DB_ERROR;
1221 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1222 LogError("Error " << e.GetMessage());
1223 retCode = CKM_API_ERROR_DB_LOCKED;
1224 } catch (const CKM::Exception &e) {
1225 LogError("CKM::Exception: " << e.GetMessage());
1226 retCode = CKM_API_ERROR_SERVER_ERROR;
1229 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
1232 int CKMLogic::readCertificateHelper(
1233 const Credentials &cred,
1234 const LabelNameVector &labelNameVector,
1235 CertificateImplVector &certVector)
1238 for (auto &i: labelNameVector) {
1239 int ec = readDataHelper(false, cred, DataType::CERTIFICATE, i.second, i.first, Password(), row);
1240 if (ec != CKM_API_SUCCESS)
1242 certVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
1244 // try to read chain certificates (if present)
1245 DB::RowVector rawCaChain;
1246 ec = readDataHelper(false, cred, DataType::DB_CHAIN_FIRST, i.second, i.first, CKM::Password(), rawCaChain);
1247 if(ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN)
1249 for(auto &rawCaCert : rawCaChain)
1250 certVector.push_back(CertificateImpl(rawCaCert.data, DataFormat::FORM_DER));
1252 return CKM_API_SUCCESS;
1255 int CKMLogic::getCertificateChainHelper(
1256 const CertificateImpl &cert,
1257 const RawBufferVector &untrustedCertificates,
1258 const RawBufferVector &trustedCertificates,
1259 bool useTrustedSystemCertificates,
1260 RawBufferVector &chainRawVector)
1262 CertificateImplVector untrustedCertVector;
1263 CertificateImplVector trustedCertVector;
1264 CertificateImplVector chainVector;
1267 return CKM_API_ERROR_INPUT_PARAM;
1269 for (auto &e: untrustedCertificates)
1270 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1271 for (auto &e: trustedCertificates)
1272 trustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
1274 CertificateStore store;
1275 int retCode = store.verifyCertificate(cert,
1276 untrustedCertVector,
1278 useTrustedSystemCertificates,
1279 m_accessControl.isCCMode(),
1281 if (retCode != CKM_API_SUCCESS)
1284 for (auto &e : chainVector)
1285 chainRawVector.push_back(e.getDER());
1286 return CKM_API_SUCCESS;
1289 int CKMLogic::getCertificateChainHelper(
1290 const Credentials &cred,
1291 const CertificateImpl &cert,
1292 const LabelNameVector &untrusted,
1293 const LabelNameVector &trusted,
1294 bool useTrustedSystemCertificates,
1295 RawBufferVector &chainRawVector)
1297 CertificateImplVector untrustedCertVector;
1298 CertificateImplVector trustedCertVector;
1299 CertificateImplVector chainVector;
1303 return CKM_API_ERROR_INPUT_PARAM;
1305 int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector);
1306 if (retCode != CKM_API_SUCCESS)
1308 retCode = readCertificateHelper(cred, trusted, trustedCertVector);
1309 if (retCode != CKM_API_SUCCESS)
1312 CertificateStore store;
1313 retCode = store.verifyCertificate(cert,
1314 untrustedCertVector,
1316 useTrustedSystemCertificates,
1317 m_accessControl.isCCMode(),
1319 if (retCode != CKM_API_SUCCESS)
1322 for (auto &i: chainVector)
1323 chainRawVector.push_back(i.getDER());
1325 return CKM_API_SUCCESS;
1328 RawBuffer CKMLogic::getCertificateChain(
1329 const Credentials & /*cred*/,
1331 const RawBuffer &certificate,
1332 const RawBufferVector &untrustedCertificates,
1333 const RawBufferVector &trustedCertificates,
1334 bool useTrustedSystemCertificates)
1336 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1337 RawBufferVector chainRawVector;
1338 int retCode = CKM_API_ERROR_UNKNOWN;
1340 retCode = getCertificateChainHelper(cert,
1341 untrustedCertificates,
1342 trustedCertificates,
1343 useTrustedSystemCertificates,
1345 } catch (const CryptoLogic::Exception::Base &e) {
1346 LogError("CryptoLogic failed with message: " << e.GetMessage());
1347 retCode = CKM_API_ERROR_SERVER_ERROR;
1348 } catch (const DB::Crypto::Exception::Base &e) {
1349 LogError("DB::Crypto failed with message: " << e.GetMessage());
1350 retCode = CKM_API_ERROR_DB_ERROR;
1351 } catch (const std::exception& e) {
1352 LogError("STD exception " << e.what());
1353 retCode = CKM_API_ERROR_SERVER_ERROR;
1355 LogError("Unknown error.");
1358 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
1362 return response.Pop();
1365 RawBuffer CKMLogic::getCertificateChain(
1366 const Credentials &cred,
1368 const RawBuffer &certificate,
1369 const LabelNameVector &untrustedCertificates,
1370 const LabelNameVector &trustedCertificates,
1371 bool useTrustedSystemCertificates)
1373 int retCode = CKM_API_ERROR_UNKNOWN;
1374 CertificateImpl cert(certificate, DataFormat::FORM_DER);
1375 RawBufferVector chainRawVector;
1377 retCode = getCertificateChainHelper(cred,
1379 untrustedCertificates,
1380 trustedCertificates,
1381 useTrustedSystemCertificates,
1383 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1384 LogError("CryptoLogic failed with message: " << e.GetMessage());
1385 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1386 } catch (const CryptoLogic::Exception::Base &e) {
1387 LogError("CryptoLogic failed with message: " << e.GetMessage());
1388 retCode = CKM_API_ERROR_SERVER_ERROR;
1389 } catch (const DB::Crypto::Exception::Base &e) {
1390 LogError("DB::Crypto failed with message: " << e.GetMessage());
1391 retCode = CKM_API_ERROR_DB_ERROR;
1392 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1393 LogError("Error " << e.GetMessage());
1394 retCode = CKM_API_ERROR_DB_LOCKED;
1395 } catch (const std::exception& e) {
1396 LogError("STD exception " << e.what());
1397 retCode = CKM_API_ERROR_SERVER_ERROR;
1399 LogError("Unknown error.");
1402 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
1406 return response.Pop();
1409 RawBuffer CKMLogic::createSignature(
1410 const Credentials &cred,
1412 const Name &privateKeyName,
1413 const Label & ownerLabel,
1414 const Password &password, // password for private_key
1415 const RawBuffer &message,
1416 const HashAlgorithm hash,
1417 const RSAPaddingAlgorithm padding)
1420 RawBuffer signature;
1421 CryptoAlgorithm cryptoAlg;
1422 cryptoAlg.addParam(ParamName::SV_HASH_ALGO, hash);
1423 cryptoAlg.addParam(ParamName::SV_RSA_PADDING, padding);
1425 int retCode = CKM_API_SUCCESS;
1428 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
1429 if(retCode == CKM_API_SUCCESS) {
1430 signature = m_decider.getStore(row).getKey(row)->sign(cryptoAlg, message);
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::Crypto::Exception::InputParam &e) {
1448 LogError("CKM::Crypto failed with message: " << e.GetMessage());
1449 retCode = CKM_API_ERROR_INPUT_PARAM;
1450 } catch (const CKM::Crypto::Exception::Base &e) {
1451 LogError("CKM::Crypto failed with message: " << e.GetMessage());
1452 retCode = CKM_API_ERROR_SERVER_ERROR;
1453 } catch (const CKM::Exception &e) {
1454 LogError("Unknown CKM::Exception: " << e.GetMessage());
1455 retCode = CKM_API_ERROR_SERVER_ERROR;
1458 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
1462 return response.Pop();
1465 RawBuffer CKMLogic::verifySignature(
1466 const Credentials &cred,
1468 const Name &publicKeyOrCertName,
1469 const Label & ownerLabel,
1470 const Password &password, // password for public_key (optional)
1471 const RawBuffer &message,
1472 const RawBuffer &signature,
1473 const HashAlgorithm hash,
1474 const RSAPaddingAlgorithm padding)
1476 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
1482 CryptoAlgorithm params;
1483 params.addParam(ParamName::SV_HASH_ALGO, hash);
1484 params.addParam(ParamName::SV_RSA_PADDING, padding);
1486 // try certificate first - looking for a public key.
1487 // in case of PKCS, pub key from certificate will be found first
1488 // rather than private key from the same PKCS.
1489 retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
1490 if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
1491 retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
1494 if (retCode == CKM_API_SUCCESS) {
1495 retCode = m_decider.getStore(row).getKey(row)->verify(params, message, signature);
1497 } catch (const Crypto::SW::CryptoService::Exception::Crypto_internal &e) {
1498 LogError("KeyProvider failed with message: " << e.GetMessage());
1499 retCode = CKM_API_ERROR_SERVER_ERROR;
1500 } catch (const Crypto::SW::CryptoService::Exception::opensslError &e) {
1501 LogError("KeyProvider failed with message: " << e.GetMessage());
1502 retCode = CKM_API_ERROR_SERVER_ERROR;
1503 } catch (const KeyProvider::Exception::Base &e) {
1504 LogError("KeyProvider failed with error: " << e.GetMessage());
1505 retCode = CKM_API_ERROR_SERVER_ERROR;
1506 } catch (const CryptoLogic::Exception::DecryptDBRowError &e) {
1507 LogError("CryptoLogic failed with message: " << e.GetMessage());
1508 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
1509 } catch (const CryptoLogic::Exception::Base &e) {
1510 LogError("CryptoLogic failed with message: " << e.GetMessage());
1511 retCode = CKM_API_ERROR_SERVER_ERROR;
1512 } catch (const DB::Crypto::Exception::Base &e) {
1513 LogError("DB::Crypto failed with message: " << e.GetMessage());
1514 retCode = CKM_API_ERROR_DB_ERROR;
1515 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1516 LogError("Error " << e.GetMessage());
1517 retCode = CKM_API_ERROR_DB_LOCKED;
1518 } catch (const CKM::Exception &e) {
1519 LogError("Unknown CKM::Exception: " << e.GetMessage());
1520 retCode = CKM_API_ERROR_SERVER_ERROR;
1523 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
1526 return response.Pop();
1529 int CKMLogic::setPermissionHelper(
1530 const Credentials &cred, // who's the client
1532 const Label &label, // who's the owner
1533 const Label &accessorLabel, // who will get the access
1534 const PermissionMask permissionMask)
1536 auto &handler = selectDatabase(cred, label);
1538 // we don't know the client
1539 if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
1540 return CKM_API_ERROR_INPUT_PARAM;
1542 // use client label if not explicitly provided
1543 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
1545 // verify name and label are correct
1546 if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
1547 return CKM_API_ERROR_INPUT_PARAM;
1549 // currently we don't support modification of owner's permissions to his own rows
1550 if (ownerLabel==accessorLabel)
1551 return CKM_API_ERROR_INPUT_PARAM;
1553 // system database does not support write/remove permissions
1554 if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
1555 (permissionMask & Permission::REMOVE))
1556 return CKM_API_ERROR_INPUT_PARAM;
1558 // can the client modify permissions to owner's row?
1559 int retCode = m_accessControl.canModify(cred, ownerLabel);
1560 if(retCode != CKM_API_SUCCESS)
1563 DB::Crypto::Transaction transaction(&handler.database);
1565 if( !handler.database.isNameLabelPresent(name, ownerLabel) )
1566 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
1568 // removing non-existing permissions: fail
1569 if(permissionMask == Permission::NONE)
1571 if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
1572 return CKM_API_ERROR_INPUT_PARAM;
1575 // set permissions to the row owned by ownerLabel for accessorLabel
1576 handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
1577 transaction.commit();
1579 return CKM_API_SUCCESS;
1582 RawBuffer CKMLogic::setPermission(
1583 const Credentials &cred,
1588 const Label &accessorLabel,
1589 const PermissionMask permissionMask)
1593 retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
1594 } catch (const CKMLogic::Exception::DatabaseLocked &e) {
1595 LogError("Error " << e.GetMessage());
1596 retCode = CKM_API_ERROR_DB_LOCKED;
1597 } Catch (CKM::Exception) {
1598 LogError("Error in set row!");
1599 retCode = CKM_API_ERROR_DB_ERROR;
1602 return MessageBuffer::Serialize(command, msgID, retCode).Pop();