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>
33 #ifndef VCONFKEY_SECURITY_MDPP_STATE
34 #define VCONFKEY_SECURITY_MDPP_STATE = "file/security_mdpp/security_mdpp_state";
38 const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
40 const char* const MDPP_MODE_ENFORCING = "Enforcing";
41 const char* const MDPP_MODE_ENABLED = "Enabled";
42 const char* const MDPP_MODE_DISABLED = "Disabled";
44 } // anonymous namespace
48 CKMLogic::CKMLogic() : m_ccMode(false)
50 if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
51 LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
54 updateCCMode_internal();
57 CKMLogic::~CKMLogic(){}
59 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
60 // TODO try catch for all errors that should be supported by error code
61 int retCode = CKM_API_SUCCESS;
64 if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
65 auto &handle = m_userDataMap[user];
67 auto wrappedDomainKEK = fs.getDKEK();
69 if (wrappedDomainKEK.empty()) {
70 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
71 fs.saveDKEK(wrappedDomainKEK);
74 handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
76 auto wrappedDatabaseDEK = fs.getDBDEK();
78 if (wrappedDatabaseDEK.empty()) {
79 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
80 fs.saveDBDEK(wrappedDatabaseDEK);
83 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
84 handle.database = DBCrypto(fs.getDBPath(), key);
85 handle.crypto = CryptoLogic();
87 // remove data of removed apps during locked state
88 AppLabelVector removedApps = fs.clearRemovedsApps();
89 for(auto& appSmackLabel : removedApps) {
90 handle.database.deleteKey(appSmackLabel);
95 } catch (const KeyProvider::Exception::PassWordError &e) {
96 LogError("Incorrect Password " << e.GetMessage());
97 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
98 } catch (const KeyProvider::Exception::Base &e) {
99 LogError("Error in KeyProvider " << e.GetMessage());
100 retCode = CKM_API_ERROR_SERVER_ERROR;
101 } catch (const CryptoLogic::Exception::Base &e) {
102 LogError("CryptoLogic error: " << e.GetMessage());
103 retCode = CKM_API_ERROR_SERVER_ERROR;
104 } catch (const CKM::Exception &e) {
105 LogError("CKM::Exception: " << e.GetMessage());
106 retCode = CKM_API_ERROR_SERVER_ERROR;
109 if(retCode != CKM_API_SUCCESS) {
110 // When not successful, UserData in m_userDataMap should be erased.
111 // Because other operations make decision based on the existence of UserData in m_userDataMap.
112 m_userDataMap.erase(user);
115 return MessageBuffer::Serialize(retCode).Pop();
118 void CKMLogic::updateCCMode_internal() {
119 int fipsModeStatus = 0;
123 char *mdppState = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
124 newMode = (mdppState && ( !strcmp(mdppState, MDPP_MODE_ENABLED)
125 || !strcmp(mdppState, MDPP_MODE_ENFORCING)
126 || !strcmp(mdppState, MDPP_MODE_DISABLED)));
127 if (newMode == m_ccMode)
132 fipsModeStatus = FIPS_mode();
135 if(fipsModeStatus == 0) { // If FIPS mode off
136 rc = FIPS_mode_set(1); // Change FIPS_mode from off to on
138 LogError("Error in FIPS_mode_set function");
142 if(fipsModeStatus == 1) { // If FIPS mode on
143 rc = FIPS_mode_set(0); // Change FIPS_mode from on to off
145 LogError("Error in FIPS_mode_set function");
151 RawBuffer CKMLogic::updateCCMode() {
152 updateCCMode_internal();
153 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
156 RawBuffer CKMLogic::lockUserKey(uid_t user) {
157 int retCode = CKM_API_SUCCESS;
158 // TODO try catch for all errors that should be supported by error code
159 m_userDataMap.erase(user);
161 return MessageBuffer::Serialize(retCode).Pop();
165 RawBuffer CKMLogic::removeUserData(uid_t user) {
166 int retCode = CKM_API_SUCCESS;
167 // TODO try catch for all errors that should be supported by error code
168 m_userDataMap.erase(user);
173 return MessageBuffer::Serialize(retCode).Pop();
176 RawBuffer CKMLogic::changeUserPassword(
178 const Password &oldPassword,
179 const Password &newPassword)
181 int retCode = CKM_API_SUCCESS;
184 auto wrappedDomainKEK = fs.getDKEK();
185 if (wrappedDomainKEK.empty()) {
186 retCode = CKM_API_ERROR_BAD_REQUEST;
188 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
189 fs.saveDKEK(wrappedDomainKEK);
191 } catch (const KeyProvider::Exception::PassWordError &e) {
192 LogError("Incorrect Password " << e.GetMessage());
193 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
194 } catch (const KeyProvider::Exception::Base &e) {
195 LogError("Error in KeyProvider " << e.GetMessage());
196 retCode = CKM_API_ERROR_SERVER_ERROR;
197 } catch (const CKM::Exception &e) {
198 LogError("CKM::Exception: " << e.GetMessage());
199 retCode = CKM_API_ERROR_SERVER_ERROR;
202 return MessageBuffer::Serialize(retCode).Pop();
205 RawBuffer CKMLogic::resetUserPassword(
207 const Password &newPassword)
209 int retCode = CKM_API_SUCCESS;
211 if (0 == m_userDataMap.count(user)) {
212 retCode = CKM_API_ERROR_BAD_REQUEST;
214 auto &handler = m_userDataMap[user];
216 fs.saveDKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
219 return MessageBuffer::Serialize(retCode).Pop();
222 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
223 int retCode = CKM_API_SUCCESS;
227 if (smackLabel.empty()) {
228 retCode = CKM_API_ERROR_INPUT_PARAM;
230 UidVector uids = FileSystem::getUIDsFromDBFile();
231 for (auto userId : uids) {
232 if (0 == m_userDataMap.count(userId)) {
233 FileSystem fs(userId);
234 fs.addRemovedApp(smackLabel);
236 auto &handle = m_userDataMap[userId];
237 handle.database.deleteKey(smackLabel);
242 } catch (const DBCrypto::Exception::InternalError &e) {
243 LogError("DBCrypto couldn't remove data: " << e.GetMessage());
244 retCode = CKM_API_ERROR_DB_ERROR;
245 } catch (const DBCrypto::Exception::TransactionError &e) {
246 LogError("DBCrypto transaction failed with message " << e.GetMessage());
247 retCode = CKM_API_ERROR_DB_ERROR;
250 return MessageBuffer::Serialize(retCode).Pop();
253 int CKMLogic::saveDataHelper(
257 const RawBuffer &key,
258 const PolicySerializable &policy)
260 if (0 == m_userDataMap.count(cred.uid))
261 return CKM_API_ERROR_DB_LOCKED;
263 // proceed to data save
264 DBRow row = { name, cred.smackLabel,
265 policy.extractable, dataType, DBCMAlgType::NONE,
266 0, RawBuffer(), static_cast<int>(key.size()), key, RawBuffer() };
268 auto &handler = m_userDataMap[cred.uid];
269 DBCrypto::Transaction transaction(&handler.database);
270 if (!handler.crypto.haveKey(cred.smackLabel)) {
272 auto key_optional = handler.database.getKey(cred.smackLabel);
274 LogDebug("No Key in database found. Generating new one for label: "
276 got_key = handler.keyProvider.generateDEK(cred.smackLabel);
277 handler.database.saveKey(cred.smackLabel, got_key);
279 LogDebug("Key from DB");
280 got_key = *key_optional;
283 got_key = handler.keyProvider.getPureDEK(got_key);
284 handler.crypto.pushKey(cred.smackLabel, got_key);
287 // Do not encrypt data with password during cc_mode on
289 handler.crypto.encryptRow("", row);
291 handler.crypto.encryptRow(policy.password, row);
294 handler.database.saveDBRow(row);
295 transaction.commit();
296 return CKM_API_SUCCESS;
299 void CKMLogic::verifyBinaryData(DBDataType dataType, const RawBuffer &input_data) const
301 // verify the data integrity
304 case DBDataType::KEY_RSA_PUBLIC:
305 case DBDataType::KEY_RSA_PRIVATE:
306 case DBDataType::KEY_ECDSA_PUBLIC:
307 case DBDataType::KEY_ECDSA_PRIVATE:
308 case DBDataType::KEY_DSA_PUBLIC:
309 case DBDataType::KEY_DSA_PRIVATE:
310 case DBDataType::KEY_AES:
312 KeyShPtr output_key = CKM::Key::create(input_data);
313 if(output_key.get() == NULL)
314 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid key data");
318 case DBDataType::CERTIFICATE:
320 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
321 if(cert.get() == NULL)
322 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid certificate data");
326 // TODO: add here BINARY_DATA verification, i.e: max size etc.
332 RawBuffer CKMLogic::saveData(
337 const RawBuffer &key,
338 const PolicySerializable &policy)
340 int retCode = CKM_API_SUCCESS;
342 verifyBinaryData(dataType, key);
344 retCode = saveDataHelper(cred, dataType, name, key, policy);
345 LogDebug("SaveDataHelper returned: " << retCode);
346 } catch (const CKMLogic::Exception::InputDataInvalid &e) {
347 LogError("Provided data invalid: " << e.GetMessage());
348 retCode = CKM_API_ERROR_INPUT_PARAM;
349 } catch (const KeyProvider::Exception::Base &e) {
350 LogError("KeyProvider failed with message: " << e.GetMessage());
351 retCode = CKM_API_ERROR_SERVER_ERROR;
352 } catch (const CryptoLogic::Exception::Base &e) {
353 LogError("CryptoLogic failed with message: " << e.GetMessage());
354 retCode = CKM_API_ERROR_SERVER_ERROR;
355 } catch (const DBCrypto::Exception::InternalError &e) {
356 LogError("DBCrypto failed with message: " << e.GetMessage());
357 retCode = CKM_API_ERROR_DB_ERROR;
358 } catch (const DBCrypto::Exception::NameExists &e) {
359 LogError("DBCrypto couldn't save duplicate name");
360 retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
361 } catch (const DBCrypto::Exception::TransactionError &e) {
362 LogError("DBCrypto transaction failed with message " << e.GetMessage());
363 retCode = CKM_API_ERROR_DB_ERROR;
366 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
369 static_cast<int>(dataType));
370 return response.Pop();
373 RawBuffer CKMLogic::removeData(
380 int retCode = CKM_API_SUCCESS;
382 if (0 < m_userDataMap.count(cred.uid)) {
384 // use client label if not explicitly provided
385 const Label & ownerLabel = label.empty() ? cred.smackLabel : label;
387 // verify name and label are correct
388 if (true == checkNameAndLabelValid(name, ownerLabel))
390 auto erased = m_userDataMap[cred.uid].database.deleteDBRow(name, ownerLabel, cred.smackLabel);
391 // check if the data existed or not
393 LogError("No row for given name and label");
394 retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
399 LogError("Invalid label or name format");
400 retCode = CKM_API_ERROR_INPUT_PARAM;
402 } Catch (DBCrypto::Exception::PermissionDenied) {
403 LogError("Error: not enough permissions!");
404 retCode = CKM_API_ERROR_ACCESS_DENIED;
405 } Catch (CKM::Exception) {
406 LogError("Error in deleting row!");
407 retCode = CKM_API_ERROR_DB_ERROR;
410 retCode = CKM_API_ERROR_DB_LOCKED;
413 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
416 static_cast<int>(dataType));
417 return response.Pop();
420 bool CKMLogic::checkNameAndLabelValid(const Name &name, const Label &label)
422 // verify the name is valid
423 if(name.find(':') != Label::npos)
426 // verify the label is valid
427 if(label.find(LABEL_NAME_SEPARATOR) != Label::npos)
433 int CKMLogic::getDataHelper(
438 const Password &password,
441 if (0 == m_userDataMap.count(cred.uid))
442 return CKM_API_ERROR_DB_LOCKED;
444 auto &handler = m_userDataMap[cred.uid];
446 // use client label if not explicitly provided
447 const Label ownerLabel = label.empty() ? cred.smackLabel : label;
449 // verify name and label are correct
450 if (true != checkNameAndLabelValid(name, ownerLabel))
451 return CKM_API_ERROR_INPUT_PARAM;
453 DBCrypto::DBRowOptional row_optional;
454 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA)
456 row_optional = handler.database.getDBRow(name, ownerLabel, cred.smackLabel, dataType);
458 else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST)) &&
459 (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
461 row_optional = handler.database.getKeyDBRow(name, ownerLabel, cred.smackLabel);
465 LogError("Unknown type of requested data" << (int)dataType);
466 return CKM_API_ERROR_BAD_REQUEST;
469 LogError("No row for given name, label and type");
470 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
475 if (!handler.crypto.haveKey(row.smackLabel)) {
477 auto key_optional = handler.database.getKey(row.smackLabel);
479 LogError("No key for given label in database");
480 return CKM_API_ERROR_DB_ERROR;
483 key = handler.keyProvider.getPureDEK(key);
484 handler.crypto.pushKey(row.smackLabel, key);
486 handler.crypto.decryptRow(password, row);
488 return CKM_API_SUCCESS;
491 RawBuffer CKMLogic::getData(
497 const Password &password)
499 int retCode = CKM_API_SUCCESS;
503 retCode = getDataHelper(cred, dataType, name, label, password, row);
504 } catch (const KeyProvider::Exception::Base &e) {
505 LogError("KeyProvider failed with error: " << e.GetMessage());
506 retCode = CKM_API_ERROR_SERVER_ERROR;
507 } catch (const CryptoLogic::Exception::Base &e) {
508 LogError("CryptoLogic failed with message: " << e.GetMessage());
509 retCode = CKM_API_ERROR_SERVER_ERROR;
510 } catch (const DBCrypto::Exception::PermissionDenied &e) {
511 LogError("DBCrypto failed with message: " << e.GetMessage());
512 retCode = CKM_API_ERROR_ACCESS_DENIED;
513 } catch (const DBCrypto::Exception::Base &e) {
514 LogError("DBCrypto failed with message: " << e.GetMessage());
515 retCode = CKM_API_ERROR_DB_ERROR;
518 if (CKM_API_SUCCESS != retCode) {
520 row.dataType = dataType;
523 if ((CKM_API_SUCCESS == retCode) && (row.exportable == 0)) {
525 retCode = CKM_API_ERROR_NOT_EXPORTABLE;
528 // Prevent extracting private keys during cc-mode on
529 if((m_ccMode) && (row.dataType == DBDataType::KEY_RSA_PRIVATE ||
530 row.dataType == DBDataType::KEY_ECDSA_PRIVATE ||
531 row.dataType == DBDataType::KEY_DSA_PRIVATE))
534 retCode = CKM_API_ERROR_BAD_REQUEST;
537 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
540 static_cast<int>(row.dataType),
542 return response.Pop();
545 RawBuffer CKMLogic::getDataList(
550 int retCode = CKM_API_SUCCESS;
551 LabelNameVector labelNameVector;
553 if (0 < m_userDataMap.count(cred.uid)) {
554 auto &handler = m_userDataMap[cred.uid];
556 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
557 handler.database.getNames(cred.smackLabel, dataType, labelNameVector);
559 handler.database.getKeyNames(cred.smackLabel, labelNameVector);
561 } Catch (CKM::Exception) {
562 LogError("Failed to get names");
563 retCode = CKM_API_ERROR_DB_ERROR;
566 retCode = CKM_API_ERROR_DB_LOCKED;
569 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
572 static_cast<int>(dataType),
574 return response.Pop();
578 int CKMLogic::createKeyPairHelper(
580 const KeyType key_type,
581 const int additional_param,
582 const Name &namePrivate,
583 const Name &namePublic,
584 const PolicySerializable &policyPrivate,
585 const PolicySerializable &policyPublic)
587 if (0 >= m_userDataMap.count(cred.uid))
588 return CKM_API_ERROR_DB_LOCKED;
590 auto &handler = m_userDataMap[cred.uid];
595 case KeyType::KEY_RSA_PUBLIC:
596 case KeyType::KEY_RSA_PRIVATE:
597 retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
600 case KeyType::KEY_DSA_PUBLIC:
601 case KeyType::KEY_DSA_PRIVATE:
602 retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
605 case KeyType::KEY_ECDSA_PUBLIC:
606 case KeyType::KEY_ECDSA_PRIVATE:
607 retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
611 return CKM_API_ERROR_INPUT_PARAM;
614 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
616 LogDebug("CryptoService error with code: " << retCode);
617 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
620 DBCrypto::Transaction transaction(&handler.database);
621 retCode = saveDataHelper(cred,
622 toDBDataType(prv.getType()),
627 if (CKM_API_SUCCESS != retCode)
630 retCode = saveDataHelper(cred,
631 toDBDataType(pub.getType()),
636 if (CKM_API_SUCCESS != retCode)
639 transaction.commit();
644 RawBuffer CKMLogic::createKeyPair(
646 LogicCommand protocol_cmd,
648 const int additional_param,
649 const Name &namePrivate,
650 const Name &namePublic,
651 const PolicySerializable &policyPrivate,
652 const PolicySerializable &policyPublic)
654 int retCode = CKM_API_SUCCESS;
656 KeyType key_type = KeyType::KEY_NONE;
659 case LogicCommand::CREATE_KEY_PAIR_RSA:
660 key_type = KeyType::KEY_RSA_PUBLIC;
662 case LogicCommand::CREATE_KEY_PAIR_DSA:
663 key_type = KeyType::KEY_DSA_PUBLIC;
665 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
666 key_type = KeyType::KEY_ECDSA_PUBLIC;
673 retCode = createKeyPairHelper(
682 } catch (DBCrypto::Exception::NameExists &e) {
683 LogDebug("DBCrypto error: name exists: " << e.GetMessage());
684 retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
685 } catch (DBCrypto::Exception::TransactionError &e) {
686 LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
687 retCode = CKM_API_ERROR_DB_ERROR;
688 } catch (CKM::CryptoLogic::Exception::Base &e) {
689 LogDebug("CryptoLogic error: " << e.GetMessage());
690 retCode = CKM_API_ERROR_SERVER_ERROR;
691 } catch (DBCrypto::Exception::InternalError &e) {
692 LogDebug("DBCrypto internal error: " << e.GetMessage());
693 retCode = CKM_API_ERROR_DB_ERROR;
696 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
699 RawBuffer CKMLogic::getCertificateChain(
702 const RawBuffer &certificate,
703 const RawBufferVector &untrustedRawCertVector)
707 CertificateImpl cert(certificate, DataFormat::FORM_DER);
708 CertificateImplVector untrustedCertVector;
709 CertificateImplVector chainVector;
710 RawBufferVector chainRawVector;
712 for (auto &e: untrustedRawCertVector)
713 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
715 LogDebug("Cert is empty: " << cert.empty());
717 int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
719 if (retCode == CKM_API_SUCCESS) {
720 for (auto &e : chainVector)
721 chainRawVector.push_back(e.getDER());
724 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
728 return response.Pop();
731 RawBuffer CKMLogic::getCertificateChain(
734 const RawBuffer &certificate,
735 const LabelNameVector &labelNameVector)
737 int retCode = CKM_API_SUCCESS;
738 RawBufferVector chainRawVector;
740 CertificateImpl cert(certificate, DataFormat::FORM_DER);
741 CertificateImplVector untrustedCertVector;
742 CertificateImplVector chainVector;
746 retCode = CKM_API_ERROR_SERVER_ERROR;
750 for (auto &i: labelNameVector) {
751 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i.second, i.first, Password(), row);
753 if (retCode != CKM_API_SUCCESS)
756 untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
759 retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
761 if (retCode != CKM_API_SUCCESS)
764 for (auto &i: chainVector)
765 chainRawVector.push_back(i.getDER());
767 } catch (const CryptoLogic::Exception::Base &e) {
768 LogError("DBCyptorModule failed with message: " << e.GetMessage());
769 retCode = CKM_API_ERROR_SERVER_ERROR;
770 } catch (const DBCrypto::Exception::PermissionDenied &e) {
771 LogError("DBCrypto failed with message: " << e.GetMessage());
772 retCode = CKM_API_ERROR_ACCESS_DENIED;
773 } catch (const DBCrypto::Exception::Base &e) {
774 LogError("DBCrypto failed with message: " << e.GetMessage());
775 retCode = CKM_API_ERROR_DB_ERROR;
777 LogError("Unknown error.");
781 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
785 return response.Pop();
788 RawBuffer CKMLogic::createSignature(
791 const Name &privateKeyName,
792 const Label & ownerLabel,
793 const Password &password, // password for private_key
794 const RawBuffer &message,
795 const HashAlgorithm hash,
796 const RSAPaddingAlgorithm padding)
802 int retCode = CKM_API_SUCCESS;
806 retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
807 if (CKM_API_SUCCESS != retCode) {
808 LogError("getDataHelper return error");
812 KeyImpl keyParsed(row.data, Password());
813 if (keyParsed.empty())
814 retCode = CKM_API_ERROR_SERVER_ERROR;
816 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
818 } catch (const KeyProvider::Exception::Base &e) {
819 LogError("KeyProvider failed with message: " << e.GetMessage());
820 retCode = CKM_API_ERROR_SERVER_ERROR;
821 } catch (const CryptoLogic::Exception::Base &e) {
822 LogError("CryptoLogic failed with message: " << e.GetMessage());
823 retCode = CKM_API_ERROR_SERVER_ERROR;
824 } catch (const DBCrypto::Exception::PermissionDenied &e) {
825 LogError("DBCrypto failed with message: " << e.GetMessage());
826 retCode = CKM_API_ERROR_ACCESS_DENIED;
827 } catch (const DBCrypto::Exception::Base &e) {
828 LogError("DBCrypto failed with message: " << e.GetMessage());
829 retCode = CKM_API_ERROR_DB_ERROR;
830 } catch (const CKM::Exception &e) {
831 LogError("Unknown CKM::Exception: " << e.GetMessage());
832 retCode = CKM_API_ERROR_SERVER_ERROR;
835 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
839 return response.Pop();
842 RawBuffer CKMLogic::verifySignature(
845 const Name &publicKeyOrCertName,
846 const Label & ownerLabel,
847 const Password &password, // password for public_key (optional)
848 const RawBuffer &message,
849 const RawBuffer &signature,
850 const HashAlgorithm hash,
851 const RSAPaddingAlgorithm padding)
853 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
861 retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
863 if (retCode == CKM_API_SUCCESS) {
864 key = KeyImpl(row.data);
865 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
866 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
867 if (retCode != CKM_API_SUCCESS)
869 CertificateImpl cert(row.data, DataFormat::FORM_DER);
870 key = cert.getKeyImpl();
876 retCode = CKM_API_ERROR_SERVER_ERROR;
880 retCode = cs.verifySignature(key, message, signature, hash, padding);
882 } catch (const CryptoService::Exception::Crypto_internal &e) {
883 LogError("KeyProvider failed with message: " << e.GetMessage());
884 retCode = CKM_API_ERROR_SERVER_ERROR;
885 } catch (const CryptoService::Exception::opensslError &e) {
886 LogError("KeyProvider failed with message: " << e.GetMessage());
887 retCode = CKM_API_ERROR_SERVER_ERROR;
888 } catch (const KeyProvider::Exception::Base &e) {
889 LogError("KeyProvider failed with error: " << e.GetMessage());
890 retCode = CKM_API_ERROR_SERVER_ERROR;
891 } catch (const CryptoLogic::Exception::Base &e) {
892 LogError("CryptoLogic failed with message: " << e.GetMessage());
893 retCode = CKM_API_ERROR_SERVER_ERROR;
894 } catch (const DBCrypto::Exception::PermissionDenied &e) {
895 LogError("DBCrypto failed with message: " << e.GetMessage());
896 retCode = CKM_API_ERROR_ACCESS_DENIED;
897 } catch (const DBCrypto::Exception::Base &e) {
898 LogError("DBCrypto failed with message: " << e.GetMessage());
899 retCode = CKM_API_ERROR_DB_ERROR;
900 } catch (const CKM::Exception &e) {
901 LogError("Unknown CKM::Exception: " << e.GetMessage());
902 retCode = CKM_API_ERROR_SERVER_ERROR;
905 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
908 return response.Pop();
911 RawBuffer CKMLogic::allowAccess(
916 const Label &accessorLabel,
917 const AccessRight reqRights)
919 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
921 if (cred.smackLabel.empty()) {
922 retCode = CKM_API_ERROR_INPUT_PARAM;
923 } else if (0 < m_userDataMap.count(cred.uid) && !cred.smackLabel.empty()) {
925 retCode = m_userDataMap[cred.uid].database.setAccessRights(
930 } Catch (DBCrypto::Exception::InvalidArgs) {
931 LogError("Error: invalid args!");
932 retCode = CKM_API_ERROR_INPUT_PARAM;
933 } Catch (DBCrypto::Exception::PermissionDenied) {
934 LogError("Error: not enough permissions!");
935 retCode = CKM_API_ERROR_ACCESS_DENIED;
936 } Catch (CKM::Exception) {
937 LogError("Error in set row!");
938 retCode = CKM_API_ERROR_DB_ERROR;
941 retCode = CKM_API_ERROR_DB_LOCKED;
944 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
947 RawBuffer CKMLogic::denyAccess(
952 const Label &accessorLabel)
954 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
956 if (cred.smackLabel.empty()) {
957 retCode = CKM_API_ERROR_INPUT_PARAM;
958 } else if (0 < m_userDataMap.count(cred.uid)) {
960 retCode = m_userDataMap[cred.uid].database.clearAccessRights(name, cred.smackLabel, accessorLabel);
961 } Catch (DBCrypto::Exception::PermissionDenied) {
962 LogError("Error: not enough permissions!");
963 retCode = CKM_API_ERROR_ACCESS_DENIED;
964 } Catch (DBCrypto::Exception::InvalidArgs) {
965 LogError("Error: permission not found!");
966 retCode = CKM_API_ERROR_INPUT_PARAM;
967 } Catch (CKM::Exception) {
968 LogError("Error in deleting row!");
969 retCode = CKM_API_ERROR_DB_ERROR;
972 retCode = CKM_API_ERROR_DB_LOCKED;
975 return MessageBuffer::Serialize(command, msgID, retCode).Pop();