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 <vconf/vconf.h>
23 #include <dpl/serialization.h>
24 #include <dpl/log/log.h>
25 #include <ckm/ckm-error.h>
26 #include <ckm/ckm-type.h>
27 #include <key-provider.h>
28 #include <file-system.h>
29 #include <CryptoService.h>
30 #include <ckm-logic.h>
34 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
35 } // anonymous namespace
41 if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
42 LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
45 m_accessControl.updateCCMode();
48 CKMLogic::~CKMLogic(){}
50 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
51 // TODO try catch for all errors that should be supported by error code
52 int retCode = CKM_API_SUCCESS;
55 if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
56 auto &handle = m_userDataMap[user];
58 auto wrappedDomainKEK = fs.getDKEK();
60 if (wrappedDomainKEK.empty()) {
61 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
62 fs.saveDKEK(wrappedDomainKEK);
65 handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
67 auto wrappedDatabaseDEK = fs.getDBDEK();
69 if (wrappedDatabaseDEK.empty()) {
70 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
71 fs.saveDBDEK(wrappedDatabaseDEK);
74 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
75 handle.database = DBCrypto(fs.getDBPath(), key);
76 handle.crypto = CryptoLogic();
78 // remove data of removed apps during locked state
79 AppLabelVector removedApps = fs.clearRemovedsApps();
80 for(auto& appSmackLabel : removedApps) {
81 handle.database.deleteKey(appSmackLabel);
86 } catch (const KeyProvider::Exception::PassWordError &e) {
87 LogError("Incorrect Password " << e.GetMessage());
88 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
89 } catch (const KeyProvider::Exception::Base &e) {
90 LogError("Error in KeyProvider " << e.GetMessage());
91 retCode = CKM_API_ERROR_SERVER_ERROR;
92 } catch (const CryptoLogic::Exception::Base &e) {
93 LogError("CryptoLogic error: " << e.GetMessage());
94 retCode = CKM_API_ERROR_SERVER_ERROR;
95 } catch (const CKM::Exception &e) {
96 LogError("CKM::Exception: " << e.GetMessage());
97 retCode = CKM_API_ERROR_SERVER_ERROR;
100 if(retCode != CKM_API_SUCCESS) {
101 // When not successful, UserData in m_userDataMap should be erased.
102 // Because other operations make decision based on the existence of UserData in m_userDataMap.
103 m_userDataMap.erase(user);
106 return MessageBuffer::Serialize(retCode).Pop();
109 RawBuffer CKMLogic::updateCCMode() {
110 m_accessControl.updateCCMode();
111 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
114 RawBuffer CKMLogic::lockUserKey(uid_t user) {
115 int retCode = CKM_API_SUCCESS;
116 // TODO try catch for all errors that should be supported by error code
117 m_userDataMap.erase(user);
119 return MessageBuffer::Serialize(retCode).Pop();
123 RawBuffer CKMLogic::removeUserData(uid_t user) {
124 int retCode = CKM_API_SUCCESS;
125 // TODO try catch for all errors that should be supported by error code
126 m_userDataMap.erase(user);
131 return MessageBuffer::Serialize(retCode).Pop();
134 RawBuffer CKMLogic::changeUserPassword(
136 const Password &oldPassword,
137 const Password &newPassword)
139 int retCode = CKM_API_SUCCESS;
142 auto wrappedDomainKEK = fs.getDKEK();
143 if (wrappedDomainKEK.empty()) {
144 retCode = CKM_API_ERROR_BAD_REQUEST;
146 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
147 fs.saveDKEK(wrappedDomainKEK);
149 } catch (const KeyProvider::Exception::PassWordError &e) {
150 LogError("Incorrect Password " << e.GetMessage());
151 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
152 } catch (const KeyProvider::Exception::Base &e) {
153 LogError("Error in KeyProvider " << e.GetMessage());
154 retCode = CKM_API_ERROR_SERVER_ERROR;
155 } catch (const CKM::Exception &e) {
156 LogError("CKM::Exception: " << e.GetMessage());
157 retCode = CKM_API_ERROR_SERVER_ERROR;
160 return MessageBuffer::Serialize(retCode).Pop();
163 RawBuffer CKMLogic::resetUserPassword(
165 const Password &newPassword)
167 int retCode = CKM_API_SUCCESS;
169 if (0 == m_userDataMap.count(user)) {
170 retCode = CKM_API_ERROR_BAD_REQUEST;
172 auto &handler = m_userDataMap[user];
174 fs.saveDKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
177 return MessageBuffer::Serialize(retCode).Pop();
180 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
181 int retCode = CKM_API_SUCCESS;
185 if (smackLabel.empty()) {
186 retCode = CKM_API_ERROR_INPUT_PARAM;
188 UidVector uids = FileSystem::getUIDsFromDBFile();
189 for (auto userId : uids) {
190 if (0 == m_userDataMap.count(userId)) {
191 FileSystem fs(userId);
192 fs.addRemovedApp(smackLabel);
194 auto &handle = m_userDataMap[userId];
195 handle.database.deleteKey(smackLabel);
200 } catch (const DBCrypto::Exception::InternalError &e) {
201 LogError("DBCrypto couldn't remove data: " << e.GetMessage());
202 retCode = CKM_API_ERROR_DB_ERROR;
203 } catch (const DBCrypto::Exception::TransactionError &e) {
204 LogError("DBCrypto transaction failed with message " << e.GetMessage());
205 retCode = CKM_API_ERROR_DB_ERROR;
208 return MessageBuffer::Serialize(retCode).Pop();
211 int CKMLogic::saveDataHelper(
212 const Credentials &cred,
215 const RawBuffer &key,
216 const PolicySerializable &policy)
218 if (0 == m_userDataMap.count(cred.uid))
219 return CKM_API_ERROR_DB_LOCKED;
221 // proceed to data save
222 DBRow row = { name, cred.smackLabel,
223 policy.extractable, dataType, DBCMAlgType::NONE,
224 0, RawBuffer(), static_cast<int>(key.size()), key, RawBuffer() };
226 auto &handler = m_userDataMap[cred.uid];
227 DBCrypto::Transaction transaction(&handler.database);
229 // check if not a duplicate
230 if( handler.database.isNameLabelPresent(name, cred.smackLabel) )
231 return CKM_API_ERROR_DB_ALIAS_EXISTS;
233 // encryption section
234 if (!handler.crypto.haveKey(cred.smackLabel)) {
236 auto key_optional = handler.database.getKey(cred.smackLabel);
238 LogDebug("No Key in database found. Generating new one for label: "
240 got_key = handler.keyProvider.generateDEK(cred.smackLabel);
241 handler.database.saveKey(cred.smackLabel, got_key);
243 LogDebug("Key from DB");
244 got_key = *key_optional;
247 got_key = handler.keyProvider.getPureDEK(got_key);
248 handler.crypto.pushKey(cred.smackLabel, got_key);
251 // do not encrypt data with password during cc_mode on
252 if(m_accessControl.isCCMode()) {
253 handler.crypto.encryptRow("", row);
255 handler.crypto.encryptRow(policy.password, row);
258 handler.database.saveDBRow(row);
259 transaction.commit();
260 return CKM_API_SUCCESS;
263 void CKMLogic::verifyBinaryData(DBDataType dataType, const RawBuffer &input_data) const
265 // verify the data integrity
268 case DBDataType::KEY_RSA_PUBLIC:
269 case DBDataType::KEY_RSA_PRIVATE:
270 case DBDataType::KEY_ECDSA_PUBLIC:
271 case DBDataType::KEY_ECDSA_PRIVATE:
272 case DBDataType::KEY_DSA_PUBLIC:
273 case DBDataType::KEY_DSA_PRIVATE:
274 case DBDataType::KEY_AES:
276 KeyShPtr output_key = CKM::Key::create(input_data);
277 if(output_key.get() == NULL)
278 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid key data");
282 case DBDataType::CERTIFICATE:
284 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
285 if(cert.get() == NULL)
286 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid certificate data");
290 // TODO: add here BINARY_DATA verification, i.e: max size etc.
296 RawBuffer CKMLogic::saveData(
297 const Credentials &cred,
301 const RawBuffer &key,
302 const PolicySerializable &policy)
304 int retCode = CKM_API_SUCCESS;
306 verifyBinaryData(dataType, key);
308 retCode = saveDataHelper(cred, dataType, name, key, policy);
309 LogDebug("SaveDataHelper returned: " << retCode);
310 } catch (const CKMLogic::Exception::InputDataInvalid &e) {
311 LogError("Provided data invalid: " << e.GetMessage());
312 retCode = CKM_API_ERROR_INPUT_PARAM;
313 } catch (const KeyProvider::Exception::Base &e) {
314 LogError("KeyProvider failed with message: " << e.GetMessage());
315 retCode = CKM_API_ERROR_SERVER_ERROR;
316 } catch (const CryptoLogic::Exception::Base &e) {
317 LogError("CryptoLogic failed with message: " << e.GetMessage());
318 retCode = CKM_API_ERROR_SERVER_ERROR;
319 } catch (const DBCrypto::Exception::InternalError &e) {
320 LogError("DBCrypto failed with message: " << e.GetMessage());
321 retCode = CKM_API_ERROR_DB_ERROR;
322 } catch (const DBCrypto::Exception::TransactionError &e) {
323 LogError("DBCrypto transaction failed with message " << e.GetMessage());
324 retCode = CKM_API_ERROR_DB_ERROR;
327 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
330 static_cast<int>(dataType));
331 return response.Pop();
334 int CKMLogic::removeDataHelper(
335 const Credentials &cred,
337 const Label &ownerLabel)
339 if (0 == m_userDataMap.count(cred.uid))
340 return CKM_API_ERROR_DB_LOCKED;
342 // verify name and label are correct
343 if( !checkNameAndLabelValid(name, ownerLabel) )
345 LogError("Invalid label or name format");
346 return CKM_API_ERROR_INPUT_PARAM;
349 auto &database = m_userDataMap[cred.uid].database;
350 DBCrypto::Transaction transaction(&database);
352 // read and check permissions
353 PermissionOptional permissionRowOpt =
354 database.getPermissionRow(name, ownerLabel, cred.smackLabel);
355 int access_ec = m_accessControl.canDelete(ownerLabel, PermissionForLabel(cred.smackLabel, permissionRowOpt));
356 if(access_ec != CKM_API_SUCCESS)
358 LogWarning("access control check result: " << access_ec);
362 auto erased = database.deleteDBRow(name, ownerLabel);
363 // check if the data existed or not
365 transaction.commit();
367 LogError("No row for given name and label");
368 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
371 return CKM_API_SUCCESS;
374 RawBuffer CKMLogic::removeData(
375 const Credentials &cred,
383 // use client label if not explicitly provided
384 const Label & ownerLabel = label.empty() ? cred.smackLabel : label;
386 retCode = removeDataHelper(cred, name, ownerLabel);
387 } Catch (CKM::Exception) {
388 LogError("Error in deleting row!");
389 retCode = CKM_API_ERROR_DB_ERROR;
392 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
395 static_cast<int>(dataType));
396 return response.Pop();
399 bool CKMLogic::checkNameAndLabelValid(const Name &name, const Label &label)
401 // verify the name is valid
402 if(name.find(':') != Label::npos)
405 // verify the label is valid
406 if(label.find(LABEL_NAME_SEPARATOR) != Label::npos)
412 int CKMLogic::readDataRowHelper(const Name &name,
413 const Label &ownerLabel,
419 DBCrypto::DBRowOptional row_optional;
420 // TODO: move this check into request deserialization
421 if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
422 (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
424 LogError("Unknown type of requested data: " << (int)dataType);
425 return CKM_API_ERROR_BAD_REQUEST;
427 // TODO: provide internal type rather than using DB types in socket comms
428 else if ((dataType >= DBDataType::DB_KEY_FIRST) &&
429 (dataType <= DBDataType::DB_KEY_LAST))
431 // read all key types
432 row_optional = database.getDBRow(name,
434 DBDataType::DB_KEY_FIRST,
435 DBDataType::DB_KEY_LAST);
438 // read anything else
439 row_optional = database.getDBRow(name,
445 LogError("No row for given name, label and type");
446 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
451 return CKM_API_SUCCESS;
454 int CKMLogic::checkDataPermissionsHelper(const Name &name,
455 const Label &ownerLabel,
456 const Label &accessorLabel,
461 PermissionOptional permissionRowOpt =
462 database.getPermissionRow(name, ownerLabel, accessorLabel);
465 return m_accessControl.canExport(row, PermissionForLabel(accessorLabel, permissionRowOpt));
466 return m_accessControl.canRead(row, PermissionForLabel(accessorLabel, permissionRowOpt));
469 int CKMLogic::readDataHelper(
471 const Credentials &cred,
475 const Password &password,
478 if (0 == m_userDataMap.count(cred.uid))
479 return CKM_API_ERROR_DB_LOCKED;
481 // use client label if not explicitly provided
482 const Label ownerLabel = label.empty() ? cred.smackLabel : label;
484 // verify name and label are correct
485 if (true != checkNameAndLabelValid(name, ownerLabel))
486 return CKM_API_ERROR_INPUT_PARAM;
488 auto &handler = m_userDataMap[cred.uid];
491 DBCrypto::Transaction transaction(&handler.database);
492 int ec = readDataRowHelper(name, ownerLabel, dataType, handler.database, row);
493 if(CKM_API_SUCCESS != ec)
497 // check access rights
498 ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
499 if(CKM_API_SUCCESS != ec)
503 if (!handler.crypto.haveKey(row.ownerLabel)) {
505 auto key_optional = handler.database.getKey(row.ownerLabel);
507 LogError("No key for given label in database");
508 return CKM_API_ERROR_DB_ERROR;
511 key = handler.keyProvider.getPureDEK(key);
512 handler.crypto.pushKey(row.ownerLabel, key);
514 handler.crypto.decryptRow(password, row);
516 return CKM_API_SUCCESS;
519 RawBuffer CKMLogic::getData(
520 const Credentials &cred,
525 const Password &password)
527 int retCode = CKM_API_SUCCESS;
531 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
532 } catch (const KeyProvider::Exception::Base &e) {
533 LogError("KeyProvider failed with error: " << e.GetMessage());
534 retCode = CKM_API_ERROR_SERVER_ERROR;
535 } catch (const CryptoLogic::Exception::Base &e) {
536 LogError("CryptoLogic failed with message: " << e.GetMessage());
537 retCode = CKM_API_ERROR_SERVER_ERROR;
538 } catch (const DBCrypto::Exception::Base &e) {
539 LogError("DBCrypto failed with message: " << e.GetMessage());
540 retCode = CKM_API_ERROR_DB_ERROR;
543 if (CKM_API_SUCCESS != retCode) {
545 row.dataType = dataType;
548 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
551 static_cast<int>(row.dataType),
553 return response.Pop();
556 RawBuffer CKMLogic::getDataList(
557 const Credentials &cred,
561 int retCode = CKM_API_SUCCESS;
562 LabelNameVector labelNameVector;
564 if (0 < m_userDataMap.count(cred.uid)) {
565 auto &database = m_userDataMap[cred.uid].database;
569 // TODO: move this check into request deserialization
570 if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
571 (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
573 LogError("Unknown type of requested data: " << (int)dataType);
574 retCode = CKM_API_ERROR_BAD_REQUEST;
576 // TODO: provide internal type rather than using DB types in socket comms
577 else if ((dataType >= DBDataType::DB_KEY_FIRST) && (dataType <= DBDataType::DB_KEY_LAST))
579 // list all key types
580 database.listNames(cred.smackLabel,
582 DBDataType::DB_KEY_FIRST,
583 DBDataType::DB_KEY_LAST);
586 // list anything else
587 database.listNames(cred.smackLabel,
592 Catch (CKM::Exception) {
593 LogError("Failed to get names");
594 retCode = CKM_API_ERROR_DB_ERROR;
597 retCode = CKM_API_ERROR_DB_LOCKED;
600 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
603 static_cast<int>(dataType),
605 return response.Pop();
609 int CKMLogic::createKeyPairHelper(
610 const Credentials &cred,
611 const KeyType key_type,
612 const int additional_param,
613 const Name &namePrivate,
614 const Name &namePublic,
615 const PolicySerializable &policyPrivate,
616 const PolicySerializable &policyPublic)
618 if (0 == m_userDataMap.count(cred.uid))
619 return CKM_API_ERROR_DB_LOCKED;
625 case KeyType::KEY_RSA_PUBLIC:
626 case KeyType::KEY_RSA_PRIVATE:
627 retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
630 case KeyType::KEY_DSA_PUBLIC:
631 case KeyType::KEY_DSA_PRIVATE:
632 retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
635 case KeyType::KEY_ECDSA_PUBLIC:
636 case KeyType::KEY_ECDSA_PRIVATE:
637 retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
641 return CKM_API_ERROR_INPUT_PARAM;
644 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
646 LogDebug("CryptoService error with code: " << retCode);
647 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
650 auto &database = m_userDataMap[cred.uid].database;
651 DBCrypto::Transaction transaction(&database);
652 retCode = saveDataHelper(cred,
653 toDBDataType(prv.getType()),
658 if (CKM_API_SUCCESS != retCode)
661 retCode = saveDataHelper(cred,
662 toDBDataType(pub.getType()),
667 if (CKM_API_SUCCESS != retCode)
670 transaction.commit();
675 RawBuffer CKMLogic::createKeyPair(
676 const Credentials &cred,
677 LogicCommand protocol_cmd,
679 const int additional_param,
680 const Name &namePrivate,
681 const Name &namePublic,
682 const PolicySerializable &policyPrivate,
683 const PolicySerializable &policyPublic)
685 int retCode = CKM_API_SUCCESS;
687 KeyType key_type = KeyType::KEY_NONE;
690 case LogicCommand::CREATE_KEY_PAIR_RSA:
691 key_type = KeyType::KEY_RSA_PUBLIC;
693 case LogicCommand::CREATE_KEY_PAIR_DSA:
694 key_type = KeyType::KEY_DSA_PUBLIC;
696 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
697 key_type = KeyType::KEY_ECDSA_PUBLIC;
704 retCode = createKeyPairHelper(
712 } catch (DBCrypto::Exception::TransactionError &e) {
713 LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
714 retCode = CKM_API_ERROR_DB_ERROR;
715 } catch (CKM::CryptoLogic::Exception::Base &e) {
716 LogDebug("CryptoLogic error: " << e.GetMessage());
717 retCode = CKM_API_ERROR_SERVER_ERROR;
718 } catch (DBCrypto::Exception::InternalError &e) {
719 LogDebug("DBCrypto internal error: " << e.GetMessage());
720 retCode = CKM_API_ERROR_DB_ERROR;
723 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
726 RawBuffer CKMLogic::getCertificateChain(
727 const Credentials &cred,
729 const RawBuffer &certificate,
730 const RawBufferVector &untrustedRawCertVector)
734 CertificateImpl cert(certificate, DataFormat::FORM_DER);
735 CertificateImplVector untrustedCertVector;
736 CertificateImplVector chainVector;
737 RawBufferVector chainRawVector;
739 for (auto &e: untrustedRawCertVector)
740 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
742 LogDebug("Cert is empty: " << cert.empty());
744 int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
746 if (retCode == CKM_API_SUCCESS) {
747 for (auto &e : chainVector)
748 chainRawVector.push_back(e.getDER());
751 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
755 return response.Pop();
758 int CKMLogic::getCertificateChainHelper(
759 const Credentials &cred,
760 const RawBuffer &certificate,
761 const LabelNameVector &labelNameVector,
762 RawBufferVector & chainRawVector)
764 CertificateImpl cert(certificate, DataFormat::FORM_DER);
765 CertificateImplVector untrustedCertVector;
766 CertificateImplVector chainVector;
770 return CKM_API_ERROR_SERVER_ERROR;
772 for (auto &i: labelNameVector) {
773 int ec = readDataHelper(false, cred, DBDataType::CERTIFICATE, i.second, i.first, Password(), row);
774 if (ec != CKM_API_SUCCESS)
777 untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
780 int ec = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
781 if (ec != CKM_API_SUCCESS)
784 for (auto &i: chainVector)
785 chainRawVector.push_back(i.getDER());
787 return CKM_API_SUCCESS;
790 RawBuffer CKMLogic::getCertificateChain(
791 const Credentials &cred,
793 const RawBuffer &certificate,
794 const LabelNameVector &labelNameVector)
796 int retCode = CKM_API_SUCCESS;
797 RawBufferVector chainRawVector;
800 retCode = getCertificateChainHelper(cred, certificate, labelNameVector, chainRawVector);
801 } catch (const CryptoLogic::Exception::Base &e) {
802 LogError("DBCyptorModule failed with message: " << e.GetMessage());
803 retCode = CKM_API_ERROR_SERVER_ERROR;
804 } catch (const DBCrypto::Exception::Base &e) {
805 LogError("DBCrypto failed with message: " << e.GetMessage());
806 retCode = CKM_API_ERROR_DB_ERROR;
808 LogError("Unknown error.");
811 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
815 return response.Pop();
818 RawBuffer CKMLogic::createSignature(
819 const Credentials &cred,
821 const Name &privateKeyName,
822 const Label & ownerLabel,
823 const Password &password, // password for private_key
824 const RawBuffer &message,
825 const HashAlgorithm hash,
826 const RSAPaddingAlgorithm padding)
832 int retCode = CKM_API_SUCCESS;
835 retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
836 if(retCode == CKM_API_SUCCESS)
838 KeyImpl keyParsed(row.data, Password());
839 if (keyParsed.empty())
840 retCode = CKM_API_ERROR_SERVER_ERROR;
842 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
844 } catch (const KeyProvider::Exception::Base &e) {
845 LogError("KeyProvider failed with message: " << e.GetMessage());
846 retCode = CKM_API_ERROR_SERVER_ERROR;
847 } catch (const CryptoLogic::Exception::Base &e) {
848 LogError("CryptoLogic failed with message: " << e.GetMessage());
849 retCode = CKM_API_ERROR_SERVER_ERROR;
850 } catch (const DBCrypto::Exception::Base &e) {
851 LogError("DBCrypto failed with message: " << e.GetMessage());
852 retCode = CKM_API_ERROR_DB_ERROR;
853 } catch (const CKM::Exception &e) {
854 LogError("Unknown CKM::Exception: " << e.GetMessage());
855 retCode = CKM_API_ERROR_SERVER_ERROR;
858 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
862 return response.Pop();
865 RawBuffer CKMLogic::verifySignature(
866 const Credentials &cred,
868 const Name &publicKeyOrCertName,
869 const Label & ownerLabel,
870 const Password &password, // password for public_key (optional)
871 const RawBuffer &message,
872 const RawBuffer &signature,
873 const HashAlgorithm hash,
874 const RSAPaddingAlgorithm padding)
876 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
884 retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
886 if (retCode == CKM_API_SUCCESS) {
887 key = KeyImpl(row.data);
888 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
889 retCode = readDataHelper(false, cred, DBDataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
890 if (retCode != CKM_API_SUCCESS)
892 CertificateImpl cert(row.data, DataFormat::FORM_DER);
893 key = cert.getKeyImpl();
899 retCode = CKM_API_ERROR_SERVER_ERROR;
903 retCode = cs.verifySignature(key, message, signature, hash, padding);
905 } catch (const CryptoService::Exception::Crypto_internal &e) {
906 LogError("KeyProvider failed with message: " << e.GetMessage());
907 retCode = CKM_API_ERROR_SERVER_ERROR;
908 } catch (const CryptoService::Exception::opensslError &e) {
909 LogError("KeyProvider failed with message: " << e.GetMessage());
910 retCode = CKM_API_ERROR_SERVER_ERROR;
911 } catch (const KeyProvider::Exception::Base &e) {
912 LogError("KeyProvider failed with error: " << e.GetMessage());
913 retCode = CKM_API_ERROR_SERVER_ERROR;
914 } catch (const CryptoLogic::Exception::Base &e) {
915 LogError("CryptoLogic failed with message: " << e.GetMessage());
916 retCode = CKM_API_ERROR_SERVER_ERROR;
917 } catch (const DBCrypto::Exception::Base &e) {
918 LogError("DBCrypto failed with message: " << e.GetMessage());
919 retCode = CKM_API_ERROR_DB_ERROR;
920 } catch (const CKM::Exception &e) {
921 LogError("Unknown CKM::Exception: " << e.GetMessage());
922 retCode = CKM_API_ERROR_SERVER_ERROR;
925 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
928 return response.Pop();
931 int CKMLogic::setPermissionHelper(
932 const Credentials &cred,
934 const Label &accessorLabel,
935 const Permission reqRights)
938 if(cred.smackLabel.empty() || cred.smackLabel==accessorLabel)
939 return CKM_API_ERROR_INPUT_PARAM;
941 if (0 == m_userDataMap.count(cred.uid))
942 return CKM_API_ERROR_DB_LOCKED;
943 auto &database = m_userDataMap[cred.uid].database;
944 DBCrypto::Transaction transaction(&database);
946 if( ! database.isNameLabelPresent(name, cred.smackLabel) )
947 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
949 // removing non-existing permissions: fail
950 if(reqRights == Permission::NONE)
952 if( !database.getPermissionRow(name, cred.smackLabel, accessorLabel) )
953 return CKM_API_ERROR_INPUT_PARAM;
956 retCode = database.setPermission(name,
961 transaction.commit();
966 RawBuffer CKMLogic::setPermission(
967 const Credentials &cred,
971 const Label &accessorLabel,
972 const Permission reqRights)
976 retCode = setPermissionHelper(cred, name, accessorLabel, reqRights);
977 } Catch (CKM::Exception) {
978 LogError("Error in set row!");
979 retCode = CKM_API_ERROR_DB_ERROR;
982 return MessageBuffer::Serialize(command, msgID, retCode).Pop();