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";
43 } // anonymous namespace
47 CKMLogic::CKMLogic() : m_ccMode(false)
49 if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
50 LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
53 updateCCMode_internal();
56 CKMLogic::~CKMLogic(){}
58 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
59 // TODO try catch for all errors that should be supported by error code
60 int retCode = CKM_API_SUCCESS;
63 if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
64 auto &handle = m_userDataMap[user];
66 auto wrappedDomainKEK = fs.getDKEK();
68 if (wrappedDomainKEK.empty()) {
69 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
70 fs.saveDKEK(wrappedDomainKEK);
73 handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
75 auto wrappedDatabaseDEK = fs.getDBDEK();
77 if (wrappedDatabaseDEK.empty()) {
78 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
79 fs.saveDBDEK(wrappedDatabaseDEK);
82 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
83 handle.database = DBCrypto(fs.getDBPath(), key);
84 handle.crypto = CryptoLogic();
86 // remove data of removed apps during locked state
87 AppLabelVector removedApps = fs.clearRemovedsApps();
88 for(auto& appSmackLabel : removedApps) {
89 handle.database.deleteKey(appSmackLabel);
94 } catch (const KeyProvider::Exception::PassWordError &e) {
95 LogError("Incorrect Password " << e.GetMessage());
96 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
97 } catch (const KeyProvider::Exception::Base &e) {
98 LogError("Error in KeyProvider " << e.GetMessage());
99 retCode = CKM_API_ERROR_SERVER_ERROR;
100 } catch (const CryptoLogic::Exception::Base &e) {
101 LogError("CryptoLogic error: " << e.GetMessage());
102 retCode = CKM_API_ERROR_SERVER_ERROR;
103 } catch (const CKM::Exception &e) {
104 LogError("CKM::Exception: " << e.GetMessage());
105 retCode = CKM_API_ERROR_SERVER_ERROR;
108 if(retCode != CKM_API_SUCCESS) {
109 // When not successful, UserData in m_userDataMap should be erased.
110 // Because other operations make decision based on the existence of UserData in m_userDataMap.
111 m_userDataMap.erase(user);
114 return MessageBuffer::Serialize(retCode).Pop();
117 void CKMLogic::updateCCMode_internal() {
118 int fipsModeStatus = 0;
122 char *mdppState = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
123 newMode = ( mdppState && (!strcmp(mdppState, MDPP_MODE_ENABLED) ||
124 !strcmp(mdppState, MDPP_MODE_ENFORCING)) );
125 if (newMode == m_ccMode)
130 fipsModeStatus = FIPS_mode();
133 if(fipsModeStatus == 0) { // If FIPS mode off
134 rc = FIPS_mode_set(1); // Change FIPS_mode from off to on
136 LogError("Error in FIPS_mode_set function");
140 if(fipsModeStatus == 1) { // If FIPS mode on
141 rc = FIPS_mode_set(0); // Change FIPS_mode from on to off
143 LogError("Error in FIPS_mode_set function");
149 RawBuffer CKMLogic::updateCCMode() {
150 updateCCMode_internal();
151 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
154 RawBuffer CKMLogic::lockUserKey(uid_t user) {
155 int retCode = CKM_API_SUCCESS;
156 // TODO try catch for all errors that should be supported by error code
157 m_userDataMap.erase(user);
159 return MessageBuffer::Serialize(retCode).Pop();
163 RawBuffer CKMLogic::removeUserData(uid_t user) {
164 int retCode = CKM_API_SUCCESS;
165 // TODO try catch for all errors that should be supported by error code
166 m_userDataMap.erase(user);
171 return MessageBuffer::Serialize(retCode).Pop();
174 RawBuffer CKMLogic::changeUserPassword(
176 const Password &oldPassword,
177 const Password &newPassword)
179 int retCode = CKM_API_SUCCESS;
182 auto wrappedDomainKEK = fs.getDKEK();
183 if (wrappedDomainKEK.empty()) {
184 retCode = CKM_API_ERROR_BAD_REQUEST;
186 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
187 fs.saveDKEK(wrappedDomainKEK);
189 } catch (const KeyProvider::Exception::PassWordError &e) {
190 LogError("Incorrect Password " << e.GetMessage());
191 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
192 } catch (const KeyProvider::Exception::Base &e) {
193 LogError("Error in KeyProvider " << e.GetMessage());
194 retCode = CKM_API_ERROR_SERVER_ERROR;
195 } catch (const CKM::Exception &e) {
196 LogError("CKM::Exception: " << e.GetMessage());
197 retCode = CKM_API_ERROR_SERVER_ERROR;
200 return MessageBuffer::Serialize(retCode).Pop();
203 RawBuffer CKMLogic::resetUserPassword(
205 const Password &newPassword)
207 int retCode = CKM_API_SUCCESS;
209 if (0 == m_userDataMap.count(user)) {
210 retCode = CKM_API_ERROR_BAD_REQUEST;
212 auto &handler = m_userDataMap[user];
214 fs.saveDKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
217 return MessageBuffer::Serialize(retCode).Pop();
220 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
221 int retCode = CKM_API_SUCCESS;
225 if (smackLabel.empty()) {
226 retCode = CKM_API_ERROR_INPUT_PARAM;
228 UidVector uids = FileSystem::getUIDsFromDBFile();
229 for (auto userId : uids) {
230 if (0 == m_userDataMap.count(userId)) {
231 FileSystem fs(userId);
232 fs.addRemovedApp(smackLabel);
234 auto &handle = m_userDataMap[userId];
235 handle.database.deleteKey(smackLabel);
240 } catch (const DBCrypto::Exception::InternalError &e) {
241 LogError("DBCrypto couldn't remove data: " << e.GetMessage());
242 retCode = CKM_API_ERROR_DB_ERROR;
243 } catch (const DBCrypto::Exception::TransactionError &e) {
244 LogError("DBCrypto transaction failed with message " << e.GetMessage());
245 retCode = CKM_API_ERROR_DB_ERROR;
248 return MessageBuffer::Serialize(retCode).Pop();
251 int CKMLogic::saveDataHelper(
255 const RawBuffer &key,
256 const PolicySerializable &policy)
258 if (0 == m_userDataMap.count(cred.uid))
259 return CKM_API_ERROR_DB_LOCKED;
261 // proceed to data save
262 DBRow row = { name, cred.smackLabel,
263 policy.extractable, dataType, DBCMAlgType::NONE,
264 0, RawBuffer(), static_cast<int>(key.size()), key, RawBuffer() };
266 auto &handler = m_userDataMap[cred.uid];
267 DBCrypto::Transaction transaction(&handler.database);
268 if (!handler.crypto.haveKey(cred.smackLabel)) {
270 auto key_optional = handler.database.getKey(cred.smackLabel);
272 LogDebug("No Key in database found. Generating new one for label: "
274 key = handler.keyProvider.generateDEK(cred.smackLabel);
275 handler.database.saveKey(cred.smackLabel, key);
277 LogDebug("Key from DB");
281 key = handler.keyProvider.getPureDEK(key);
282 handler.crypto.pushKey(cred.smackLabel, key);
285 // Do not encrypt data with password during cc_mode on
287 handler.crypto.encryptRow("", row);
289 handler.crypto.encryptRow(policy.password, row);
292 handler.database.saveDBRow(row);
293 transaction.commit();
294 return CKM_API_SUCCESS;
297 void CKMLogic::verifyBinaryData(DBDataType dataType, const RawBuffer &input_data) const
299 // verify the data integrity
302 case DBDataType::KEY_RSA_PUBLIC:
303 case DBDataType::KEY_RSA_PRIVATE:
304 case DBDataType::KEY_ECDSA_PUBLIC:
305 case DBDataType::KEY_ECDSA_PRIVATE:
306 case DBDataType::KEY_DSA_PUBLIC:
307 case DBDataType::KEY_DSA_PRIVATE:
308 case DBDataType::KEY_AES:
310 KeyShPtr output_key = CKM::Key::create(input_data);
311 if(output_key.get() == NULL)
312 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid key data");
316 case DBDataType::CERTIFICATE:
318 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
319 if(cert.get() == NULL)
320 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid certificate data");
324 // TODO: add here BINARY_DATA verification, i.e: max size etc.
330 RawBuffer CKMLogic::saveData(
335 const RawBuffer &key,
336 const PolicySerializable &policy)
338 int retCode = CKM_API_SUCCESS;
340 verifyBinaryData(dataType, key);
342 retCode = saveDataHelper(cred, dataType, name, key, policy);
343 LogDebug("SaveDataHelper returned: " << retCode);
344 } catch (const CKMLogic::Exception::InputDataInvalid &e) {
345 LogError("Provided data invalid: " << e.GetMessage());
346 retCode = CKM_API_ERROR_INPUT_PARAM;
347 } catch (const KeyProvider::Exception::Base &e) {
348 LogError("KeyProvider failed with message: " << e.GetMessage());
349 retCode = CKM_API_ERROR_SERVER_ERROR;
350 } catch (const CryptoLogic::Exception::Base &e) {
351 LogError("CryptoLogic failed with message: " << e.GetMessage());
352 retCode = CKM_API_ERROR_SERVER_ERROR;
353 } catch (const DBCrypto::Exception::InternalError &e) {
354 LogError("DBCrypto failed with message: " << e.GetMessage());
355 retCode = CKM_API_ERROR_DB_ERROR;
356 } catch (const DBCrypto::Exception::NameExists &e) {
357 LogError("DBCrypto couldn't save duplicate name");
358 retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
359 } catch (const DBCrypto::Exception::TransactionError &e) {
360 LogError("DBCrypto transaction failed with message " << e.GetMessage());
361 retCode = CKM_API_ERROR_DB_ERROR;
364 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
367 static_cast<int>(dataType));
368 return response.Pop();
371 RawBuffer CKMLogic::removeData(
378 int retCode = CKM_API_SUCCESS;
380 if (0 < m_userDataMap.count(cred.uid)) {
382 // use client label if not explicitly provided
383 const Label & ownerLabel = label.empty() ? cred.smackLabel : label;
385 // verify name and label are correct
386 if (true == checkNameAndLabelValid(name, ownerLabel))
388 auto erased = m_userDataMap[cred.uid].database.deleteDBRow(name, ownerLabel, cred.smackLabel);
389 // check if the data existed or not
391 LogError("No row for given name and label");
392 retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
397 LogError("Invalid label or name format");
398 retCode = CKM_API_ERROR_INPUT_PARAM;
400 } Catch (DBCrypto::Exception::PermissionDenied) {
401 LogError("Error: not enough permissions!");
402 retCode = CKM_API_ERROR_ACCESS_DENIED;
403 } Catch (CKM::Exception) {
404 LogError("Error in deleting row!");
405 retCode = CKM_API_ERROR_DB_ERROR;
408 retCode = CKM_API_ERROR_DB_LOCKED;
411 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
414 static_cast<int>(dataType));
415 return response.Pop();
418 bool CKMLogic::checkNameAndLabelValid(const Name &name, const Label &label)
420 // verify the name is valid
421 if(name.find(':') != Label::npos)
424 // verify the label is valid
425 if(label.find(LABEL_NAME_SEPARATOR) != Label::npos)
431 int CKMLogic::getDataHelper(
436 const Password &password,
439 if (0 == m_userDataMap.count(cred.uid))
440 return CKM_API_ERROR_DB_LOCKED;
442 auto &handler = m_userDataMap[cred.uid];
444 // use client label if not explicitly provided
445 const Label ownerLabel = label.empty() ? cred.smackLabel : label;
447 // verify name and label are correct
448 if (true != checkNameAndLabelValid(name, ownerLabel))
449 return CKM_API_ERROR_INPUT_PARAM;
451 DBCrypto::DBRowOptional row_optional;
452 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA)
454 row_optional = handler.database.getDBRow(name, ownerLabel, cred.smackLabel, dataType);
456 else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST)) &&
457 (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
459 row_optional = handler.database.getKeyDBRow(name, ownerLabel, cred.smackLabel);
463 LogError("Unknown type of requested data" << (int)dataType);
464 return CKM_API_ERROR_BAD_REQUEST;
467 LogError("No row for given name, label and type");
468 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
473 if (!handler.crypto.haveKey(row.smackLabel)) {
475 auto key_optional = handler.database.getKey(row.smackLabel);
477 LogError("No key for given label in database");
478 return CKM_API_ERROR_DB_ERROR;
481 key = handler.keyProvider.getPureDEK(key);
482 handler.crypto.pushKey(cred.smackLabel, key);
484 handler.crypto.decryptRow(password, row);
486 return CKM_API_SUCCESS;
489 RawBuffer CKMLogic::getData(
495 const Password &password)
497 int retCode = CKM_API_SUCCESS;
501 retCode = getDataHelper(cred, dataType, name, label, password, row);
502 } catch (const KeyProvider::Exception::Base &e) {
503 LogError("KeyProvider failed with error: " << e.GetMessage());
504 retCode = CKM_API_ERROR_SERVER_ERROR;
505 } catch (const CryptoLogic::Exception::Base &e) {
506 LogError("CryptoLogic failed with message: " << e.GetMessage());
507 retCode = CKM_API_ERROR_SERVER_ERROR;
508 } catch (const DBCrypto::Exception::PermissionDenied &e) {
509 LogError("DBCrypto failed with message: " << e.GetMessage());
510 retCode = CKM_API_ERROR_ACCESS_DENIED;
511 } catch (const DBCrypto::Exception::Base &e) {
512 LogError("DBCrypto failed with message: " << e.GetMessage());
513 retCode = CKM_API_ERROR_DB_ERROR;
516 if (CKM_API_SUCCESS != retCode) {
518 row.dataType = dataType;
521 if ((CKM_API_SUCCESS == retCode) && (row.exportable == 0)) {
523 retCode = CKM_API_ERROR_NOT_EXPORTABLE;
526 // Prevent extracting private keys during cc-mode on
527 if((m_ccMode) && (row.dataType == DBDataType::KEY_RSA_PRIVATE ||
528 row.dataType == DBDataType::KEY_ECDSA_PRIVATE ||
529 row.dataType == DBDataType::KEY_DSA_PRIVATE))
532 retCode = CKM_API_ERROR_BAD_REQUEST;
535 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
538 static_cast<int>(row.dataType),
540 return response.Pop();
543 RawBuffer CKMLogic::getDataList(
548 int retCode = CKM_API_SUCCESS;
549 LabelNameVector labelNameVector;
551 if (0 < m_userDataMap.count(cred.uid)) {
552 auto &handler = m_userDataMap[cred.uid];
554 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
555 handler.database.getNames(cred.smackLabel, dataType, labelNameVector);
557 handler.database.getKeyNames(cred.smackLabel, labelNameVector);
559 } Catch (CKM::Exception) {
560 LogError("Failed to get names");
561 retCode = CKM_API_ERROR_DB_ERROR;
564 retCode = CKM_API_ERROR_DB_LOCKED;
567 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
570 static_cast<int>(dataType),
572 return response.Pop();
576 int CKMLogic::createKeyPairHelper(
578 const KeyType key_type,
579 const int additional_param,
580 const Name &namePrivate,
581 const Name &namePublic,
582 const PolicySerializable &policyPrivate,
583 const PolicySerializable &policyPublic)
585 if (0 >= m_userDataMap.count(cred.uid))
586 return CKM_API_ERROR_DB_LOCKED;
588 auto &handler = m_userDataMap[cred.uid];
593 case KeyType::KEY_RSA_PUBLIC:
594 case KeyType::KEY_RSA_PRIVATE:
595 retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
598 case KeyType::KEY_DSA_PUBLIC:
599 case KeyType::KEY_DSA_PRIVATE:
600 retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
603 case KeyType::KEY_ECDSA_PUBLIC:
604 case KeyType::KEY_ECDSA_PRIVATE:
605 retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
609 return CKM_API_ERROR_INPUT_PARAM;
612 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
614 LogDebug("CryptoService error with code: " << retCode);
615 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
618 DBCrypto::Transaction transaction(&handler.database);
619 retCode = saveDataHelper(cred,
620 toDBDataType(prv.getType()),
625 if (CKM_API_SUCCESS != retCode)
628 retCode = saveDataHelper(cred,
629 toDBDataType(pub.getType()),
634 if (CKM_API_SUCCESS != retCode)
637 transaction.commit();
642 RawBuffer CKMLogic::createKeyPair(
644 LogicCommand protocol_cmd,
646 const int additional_param,
647 const Name &namePrivate,
648 const Name &namePublic,
649 const PolicySerializable &policyPrivate,
650 const PolicySerializable &policyPublic)
652 int retCode = CKM_API_SUCCESS;
654 KeyType key_type = KeyType::KEY_NONE;
657 case LogicCommand::CREATE_KEY_PAIR_RSA:
658 key_type = KeyType::KEY_RSA_PUBLIC;
660 case LogicCommand::CREATE_KEY_PAIR_DSA:
661 key_type = KeyType::KEY_DSA_PUBLIC;
663 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
664 key_type = KeyType::KEY_ECDSA_PUBLIC;
671 retCode = createKeyPairHelper(
680 } catch (DBCrypto::Exception::NameExists &e) {
681 LogDebug("DBCrypto error: name exists: " << e.GetMessage());
682 retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
683 } catch (DBCrypto::Exception::TransactionError &e) {
684 LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
685 retCode = CKM_API_ERROR_DB_ERROR;
686 } catch (CKM::CryptoLogic::Exception::Base &e) {
687 LogDebug("CryptoLogic error: " << e.GetMessage());
688 retCode = CKM_API_ERROR_SERVER_ERROR;
689 } catch (DBCrypto::Exception::InternalError &e) {
690 LogDebug("DBCrypto internal error: " << e.GetMessage());
691 retCode = CKM_API_ERROR_DB_ERROR;
694 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
697 RawBuffer CKMLogic::getCertificateChain(
700 const RawBuffer &certificate,
701 const RawBufferVector &untrustedRawCertVector)
705 CertificateImpl cert(certificate, DataFormat::FORM_DER);
706 CertificateImplVector untrustedCertVector;
707 CertificateImplVector chainVector;
708 RawBufferVector chainRawVector;
710 for (auto &e: untrustedRawCertVector)
711 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
713 LogDebug("Cert is empty: " << cert.empty());
715 int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
717 if (retCode == CKM_API_SUCCESS) {
718 for (auto &e : chainVector)
719 chainRawVector.push_back(e.getDER());
722 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
726 return response.Pop();
729 RawBuffer CKMLogic::getCertificateChain(
732 const RawBuffer &certificate,
733 const AliasVector &aliasVector)
735 int retCode = CKM_API_SUCCESS;
736 std::size_t separator_pos = 0;
737 RawBufferVector chainRawVector;
739 CertificateImpl cert(certificate, DataFormat::FORM_DER);
740 CertificateImplVector untrustedCertVector;
741 CertificateImplVector chainVector;
745 retCode = CKM_API_ERROR_SERVER_ERROR;
749 for (auto &i: aliasVector) {
750 if ((separator_pos = i.rfind(LABEL_NAME_SEPARATOR)) == Alias::npos) {
751 // No label prefixed in alias. put empty label
752 retCode = getDataHelper(
754 DBDataType::CERTIFICATE,
761 retCode = getDataHelper(
763 DBDataType::CERTIFICATE,
764 i.substr(separator_pos+strlen(LABEL_NAME_SEPARATOR)), // alias
765 Label(i.substr(0, separator_pos)), // label
770 if (retCode != CKM_API_SUCCESS)
773 untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
776 retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
778 if (retCode != CKM_API_SUCCESS)
781 for (auto &i: chainVector)
782 chainRawVector.push_back(i.getDER());
784 } catch (const CryptoLogic::Exception::Base &e) {
785 LogError("DBCyptorModule failed with message: " << e.GetMessage());
786 retCode = CKM_API_ERROR_SERVER_ERROR;
787 } catch (const DBCrypto::Exception::PermissionDenied &e) {
788 LogError("DBCrypto failed with message: " << e.GetMessage());
789 retCode = CKM_API_ERROR_ACCESS_DENIED;
790 } catch (const DBCrypto::Exception::Base &e) {
791 LogError("DBCrypto failed with message: " << e.GetMessage());
792 retCode = CKM_API_ERROR_DB_ERROR;
794 LogError("Unknown error.");
798 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
802 return response.Pop();
805 RawBuffer CKMLogic::createSignature(
808 const Name &privateKeyName,
809 const Label & ownerLabel,
810 const Password &password, // password for private_key
811 const RawBuffer &message,
812 const HashAlgorithm hash,
813 const RSAPaddingAlgorithm padding)
819 int retCode = CKM_API_SUCCESS;
823 retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
824 if (CKM_API_SUCCESS != retCode) {
825 LogError("getDataHelper return error");
829 KeyImpl keyParsed(row.data, Password());
830 if (keyParsed.empty())
831 retCode = CKM_API_ERROR_SERVER_ERROR;
833 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
835 } catch (const KeyProvider::Exception::Base &e) {
836 LogError("KeyProvider failed with message: " << e.GetMessage());
837 retCode = CKM_API_ERROR_SERVER_ERROR;
838 } catch (const CryptoLogic::Exception::Base &e) {
839 LogError("CryptoLogic failed with message: " << e.GetMessage());
840 retCode = CKM_API_ERROR_SERVER_ERROR;
841 } catch (const DBCrypto::Exception::PermissionDenied &e) {
842 LogError("DBCrypto failed with message: " << e.GetMessage());
843 retCode = CKM_API_ERROR_ACCESS_DENIED;
844 } catch (const DBCrypto::Exception::Base &e) {
845 LogError("DBCrypto failed with message: " << e.GetMessage());
846 retCode = CKM_API_ERROR_DB_ERROR;
847 } catch (const CKM::Exception &e) {
848 LogError("Unknown CKM::Exception: " << e.GetMessage());
849 retCode = CKM_API_ERROR_SERVER_ERROR;
852 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
856 return response.Pop();
859 RawBuffer CKMLogic::verifySignature(
862 const Name &publicKeyOrCertName,
863 const Label & ownerLabel,
864 const Password &password, // password for public_key (optional)
865 const RawBuffer &message,
866 const RawBuffer &signature,
867 const HashAlgorithm hash,
868 const RSAPaddingAlgorithm padding)
870 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
878 retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
880 if (retCode == CKM_API_SUCCESS) {
881 key = KeyImpl(row.data);
882 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
883 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
884 if (retCode != CKM_API_SUCCESS)
886 CertificateImpl cert(row.data, DataFormat::FORM_DER);
887 key = cert.getKeyImpl();
893 retCode = CKM_API_ERROR_SERVER_ERROR;
897 retCode = cs.verifySignature(key, message, signature, hash, padding);
899 } catch (const CryptoService::Exception::Crypto_internal &e) {
900 LogError("KeyProvider failed with message: " << e.GetMessage());
901 retCode = CKM_API_ERROR_SERVER_ERROR;
902 } catch (const CryptoService::Exception::opensslError &e) {
903 LogError("KeyProvider failed with message: " << e.GetMessage());
904 retCode = CKM_API_ERROR_SERVER_ERROR;
905 } catch (const KeyProvider::Exception::Base &e) {
906 LogError("KeyProvider failed with error: " << e.GetMessage());
907 retCode = CKM_API_ERROR_SERVER_ERROR;
908 } catch (const CryptoLogic::Exception::Base &e) {
909 LogError("CryptoLogic failed with message: " << e.GetMessage());
910 retCode = CKM_API_ERROR_SERVER_ERROR;
911 } catch (const DBCrypto::Exception::PermissionDenied &e) {
912 LogError("DBCrypto failed with message: " << e.GetMessage());
913 retCode = CKM_API_ERROR_ACCESS_DENIED;
914 } catch (const DBCrypto::Exception::Base &e) {
915 LogError("DBCrypto failed with message: " << e.GetMessage());
916 retCode = CKM_API_ERROR_DB_ERROR;
917 } catch (const CKM::Exception &e) {
918 LogError("Unknown CKM::Exception: " << e.GetMessage());
919 retCode = CKM_API_ERROR_SERVER_ERROR;
922 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
925 return response.Pop();
928 RawBuffer CKMLogic::allowAccess(
933 const Label &accessorLabel,
934 const AccessRight reqRights)
936 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
938 if (cred.smackLabel.empty()) {
939 retCode = CKM_API_ERROR_INPUT_PARAM;
940 } else if (0 < m_userDataMap.count(cred.uid) && !cred.smackLabel.empty()) {
942 retCode = m_userDataMap[cred.uid].database.setAccessRights(
947 } Catch (DBCrypto::Exception::InvalidArgs) {
948 LogError("Error: invalid args!");
949 retCode = CKM_API_ERROR_INPUT_PARAM;
950 } Catch (DBCrypto::Exception::PermissionDenied) {
951 LogError("Error: not enough permissions!");
952 retCode = CKM_API_ERROR_ACCESS_DENIED;
953 } Catch (CKM::Exception) {
954 LogError("Error in set row!");
955 retCode = CKM_API_ERROR_DB_ERROR;
958 retCode = CKM_API_ERROR_DB_LOCKED;
961 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
964 RawBuffer CKMLogic::denyAccess(
969 const Label &accessorLabel)
971 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
973 if (cred.smackLabel.empty()) {
974 retCode = CKM_API_ERROR_INPUT_PARAM;
975 } else if (0 < m_userDataMap.count(cred.uid)) {
977 retCode = m_userDataMap[cred.uid].database.clearAccessRights(name, cred.smackLabel, accessorLabel);
978 } Catch (DBCrypto::Exception::PermissionDenied) {
979 LogError("Error: not enough permissions!");
980 retCode = CKM_API_ERROR_ACCESS_DENIED;
981 } Catch (DBCrypto::Exception::InvalidArgs) {
982 LogError("Error: permission not found!");
983 retCode = CKM_API_ERROR_INPUT_PARAM;
984 } Catch (CKM::Exception) {
985 LogError("Error in deleting row!");
986 retCode = CKM_API_ERROR_DB_ERROR;
989 retCode = CKM_API_ERROR_DB_LOCKED;
992 return MessageBuffer::Serialize(command, msgID, retCode).Pop();