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 int retCode = FileSystem::init();
50 // TODO what can I do when init went wrong? exit(-1) ??
52 LogError("Fatal error in FileSystem::init()");
55 if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
56 LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
59 updateCCMode_internal();
62 CKMLogic::~CKMLogic(){}
64 RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
65 // TODO try catch for all errors that should be supported by error code
66 int retCode = CKM_API_SUCCESS;
69 if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
70 auto &handle = m_userDataMap[user];
72 auto wrappedDomainKEK = fs.getDKEK();
74 if (wrappedDomainKEK.empty()) {
75 wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password);
76 fs.saveDKEK(wrappedDomainKEK);
79 handle.keyProvider = KeyProvider(wrappedDomainKEK, password);
81 auto wrappedDatabaseDEK = fs.getDBDEK();
83 if (wrappedDatabaseDEK.empty()) {
84 wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user));
85 fs.saveDBDEK(wrappedDatabaseDEK);
88 RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
89 handle.database = DBCrypto(fs.getDBPath(), key);
90 handle.crypto = CryptoLogic();
92 // remove data of removed apps during locked state
93 AppLabelVector removedApps = fs.clearRemovedsApps();
94 for(auto& appSmackLabel : removedApps) {
95 handle.database.deleteKey(appSmackLabel);
100 } catch (const KeyProvider::Exception::PassWordError &e) {
101 LogError("Incorrect Password " << e.GetMessage());
102 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
103 } catch (const KeyProvider::Exception::Base &e) {
104 LogError("Error in KeyProvider " << e.GetMessage());
105 retCode = CKM_API_ERROR_SERVER_ERROR;
106 } catch (const CryptoLogic::Exception::Base &e) {
107 LogError("CryptoLogic error: " << e.GetMessage());
108 retCode = CKM_API_ERROR_SERVER_ERROR;
109 } catch (const CKM::Exception &e) {
110 LogError("CKM::Exception: " << e.GetMessage());
111 retCode = CKM_API_ERROR_SERVER_ERROR;
114 if(retCode != CKM_API_SUCCESS) {
115 // When not successful, UserData in m_userDataMap should be erased.
116 // Because other operations make decision based on the existence of UserData in m_userDataMap.
117 m_userDataMap.erase(user);
120 return MessageBuffer::Serialize(retCode).Pop();
123 void CKMLogic::updateCCMode_internal() {
124 int fipsModeStatus = 0;
128 char *mdppState = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
129 newMode = ( mdppState && (!strcmp(mdppState, MDPP_MODE_ENABLED) ||
130 !strcmp(mdppState, MDPP_MODE_ENFORCING)) );
131 if (newMode == m_ccMode)
136 fipsModeStatus = FIPS_mode();
139 if(fipsModeStatus == 0) { // If FIPS mode off
140 rc = FIPS_mode_set(1); // Change FIPS_mode from off to on
142 LogError("Error in FIPS_mode_set function");
146 if(fipsModeStatus == 1) { // If FIPS mode on
147 rc = FIPS_mode_set(0); // Change FIPS_mode from on to off
149 LogError("Error in FIPS_mode_set function");
155 RawBuffer CKMLogic::updateCCMode() {
156 updateCCMode_internal();
157 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
160 RawBuffer CKMLogic::lockUserKey(uid_t user) {
161 int retCode = CKM_API_SUCCESS;
162 // TODO try catch for all errors that should be supported by error code
163 m_userDataMap.erase(user);
165 return MessageBuffer::Serialize(retCode).Pop();
169 RawBuffer CKMLogic::removeUserData(uid_t user) {
170 int retCode = CKM_API_SUCCESS;
171 // TODO try catch for all errors that should be supported by error code
172 m_userDataMap.erase(user);
177 return MessageBuffer::Serialize(retCode).Pop();
180 RawBuffer CKMLogic::changeUserPassword(
182 const Password &oldPassword,
183 const Password &newPassword)
185 int retCode = CKM_API_SUCCESS;
188 auto wrappedDomainKEK = fs.getDKEK();
189 if (wrappedDomainKEK.empty()) {
190 retCode = CKM_API_ERROR_BAD_REQUEST;
192 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
193 fs.saveDKEK(wrappedDomainKEK);
195 } catch (const KeyProvider::Exception::PassWordError &e) {
196 LogError("Incorrect Password " << e.GetMessage());
197 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
198 } catch (const KeyProvider::Exception::Base &e) {
199 LogError("Error in KeyProvider " << e.GetMessage());
200 retCode = CKM_API_ERROR_SERVER_ERROR;
201 } catch (const CKM::Exception &e) {
202 LogError("CKM::Exception: " << e.GetMessage());
203 retCode = CKM_API_ERROR_SERVER_ERROR;
206 return MessageBuffer::Serialize(retCode).Pop();
209 RawBuffer CKMLogic::resetUserPassword(
211 const Password &newPassword)
213 int retCode = CKM_API_SUCCESS;
215 if (0 == m_userDataMap.count(user)) {
216 retCode = CKM_API_ERROR_BAD_REQUEST;
218 auto &handler = m_userDataMap[user];
220 fs.saveDKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
223 return MessageBuffer::Serialize(retCode).Pop();
226 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
227 int retCode = CKM_API_SUCCESS;
231 if (smackLabel.empty()) {
232 retCode = CKM_API_ERROR_INPUT_PARAM;
234 UidVector uids = FileSystem::getUIDsFromDBFile();
235 for (auto userId : uids) {
236 if (0 == m_userDataMap.count(userId)) {
237 FileSystem fs(userId);
238 fs.addRemovedApp(smackLabel);
240 auto &handle = m_userDataMap[userId];
241 handle.database.deleteKey(smackLabel);
246 } catch (const DBCrypto::Exception::InternalError &e) {
247 LogError("DBCrypto couldn't remove data: " << e.GetMessage());
248 retCode = CKM_API_ERROR_DB_ERROR;
249 } catch (const DBCrypto::Exception::TransactionError &e) {
250 LogError("DBCrypto transaction failed with message " << e.GetMessage());
251 retCode = CKM_API_ERROR_DB_ERROR;
254 return MessageBuffer::Serialize(retCode).Pop();
257 int CKMLogic::saveDataHelper(
261 const RawBuffer &key,
262 const PolicySerializable &policy)
264 if (0 == m_userDataMap.count(cred.uid))
265 return CKM_API_ERROR_DB_LOCKED;
267 // proceed to data save
268 DBRow row = { name, cred.smackLabel,
269 policy.extractable, dataType, DBCMAlgType::NONE,
270 0, RawBuffer(), static_cast<int>(key.size()), key, RawBuffer() };
272 auto &handler = m_userDataMap[cred.uid];
273 DBCrypto::Transaction transaction(&handler.database);
274 if (!handler.crypto.haveKey(cred.smackLabel)) {
276 auto key_optional = handler.database.getKey(cred.smackLabel);
278 LogDebug("No Key in database found. Generating new one for label: "
280 key = handler.keyProvider.generateDEK(cred.smackLabel);
281 handler.database.saveKey(cred.smackLabel, key);
283 LogDebug("Key from DB");
287 key = handler.keyProvider.getPureDEK(key);
288 handler.crypto.pushKey(cred.smackLabel, key);
291 // Do not encrypt data with password during cc_mode on
293 handler.crypto.encryptRow("", row);
295 handler.crypto.encryptRow(policy.password, row);
298 handler.database.saveDBRow(row);
299 transaction.commit();
300 return CKM_API_SUCCESS;
303 void CKMLogic::verifyBinaryData(DBDataType dataType, const RawBuffer &input_data) const
305 // verify the data integrity
308 case DBDataType::KEY_RSA_PUBLIC:
309 case DBDataType::KEY_RSA_PRIVATE:
310 case DBDataType::KEY_ECDSA_PUBLIC:
311 case DBDataType::KEY_ECDSA_PRIVATE:
312 case DBDataType::KEY_DSA_PUBLIC:
313 case DBDataType::KEY_DSA_PRIVATE:
314 case DBDataType::KEY_AES:
316 KeyShPtr output_key = CKM::Key::create(input_data);
317 if(output_key.get() == NULL)
318 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid key data");
322 case DBDataType::CERTIFICATE:
324 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
325 if(cert.get() == NULL)
326 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid certificate data");
330 // TODO: add here BINARY_DATA verification, i.e: max size etc.
336 RawBuffer CKMLogic::saveData(
341 const RawBuffer &key,
342 const PolicySerializable &policy)
344 int retCode = CKM_API_SUCCESS;
346 verifyBinaryData(dataType, key);
348 retCode = saveDataHelper(cred, dataType, name, key, policy);
349 LogDebug("SaveDataHelper returned: " << retCode);
350 } catch (const CKMLogic::Exception::InputDataInvalid &e) {
351 LogError("Provided data invalid: " << e.GetMessage());
352 retCode = CKM_API_ERROR_INPUT_PARAM;
353 } catch (const KeyProvider::Exception::Base &e) {
354 LogError("KeyProvider failed with message: " << e.GetMessage());
355 retCode = CKM_API_ERROR_SERVER_ERROR;
356 } catch (const CryptoLogic::Exception::Base &e) {
357 LogError("CryptoLogic failed with message: " << e.GetMessage());
358 retCode = CKM_API_ERROR_SERVER_ERROR;
359 } catch (const DBCrypto::Exception::InternalError &e) {
360 LogError("DBCrypto failed with message: " << e.GetMessage());
361 retCode = CKM_API_ERROR_DB_ERROR;
362 } catch (const DBCrypto::Exception::NameExists &e) {
363 LogError("DBCrypto couldn't save duplicate name");
364 retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
365 } catch (const DBCrypto::Exception::TransactionError &e) {
366 LogError("DBCrypto transaction failed with message " << e.GetMessage());
367 retCode = CKM_API_ERROR_DB_ERROR;
370 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
373 static_cast<int>(dataType));
374 return response.Pop();
377 RawBuffer CKMLogic::removeData(
384 int retCode = CKM_API_SUCCESS;
386 if (0 < m_userDataMap.count(cred.uid)) {
388 // use client label if not explicitly provided
389 const Label & ownerLabel = label.empty() ? cred.smackLabel : label;
391 // verify name and label are correct
392 if (true == checkNameAndLabelValid(name, ownerLabel))
394 auto erased = m_userDataMap[cred.uid].database.deleteDBRow(name, ownerLabel, cred.smackLabel);
395 // check if the data existed or not
397 LogError("No row for given name and label");
398 retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
403 LogError("Invalid label or name format");
404 retCode = CKM_API_ERROR_INPUT_PARAM;
406 } Catch (DBCrypto::Exception::PermissionDenied) {
407 LogError("Error: not enough permissions!");
408 retCode = CKM_API_ERROR_ACCESS_DENIED;
409 } Catch (CKM::Exception) {
410 LogError("Error in deleting row!");
411 retCode = CKM_API_ERROR_DB_ERROR;
414 retCode = CKM_API_ERROR_DB_LOCKED;
417 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
420 static_cast<int>(dataType));
421 return response.Pop();
424 bool CKMLogic::checkNameAndLabelValid(const Name &name, const Label &label)
426 // verify the name is valid
427 if(name.find(':') != Label::npos)
430 // verify the label is valid
431 if(label.find(LABEL_NAME_SEPARATOR) != Label::npos)
437 int CKMLogic::getDataHelper(
442 const Password &password,
445 if (0 == m_userDataMap.count(cred.uid))
446 return CKM_API_ERROR_DB_LOCKED;
448 auto &handler = m_userDataMap[cred.uid];
450 // use client label if not explicitly provided
451 const Label ownerLabel = label.empty() ? cred.smackLabel : label;
453 // verify name and label are correct
454 if (true != checkNameAndLabelValid(name, ownerLabel))
455 return CKM_API_ERROR_INPUT_PARAM;
457 DBCrypto::DBRowOptional row_optional;
458 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA)
460 row_optional = handler.database.getDBRow(name, ownerLabel, cred.smackLabel, dataType);
462 else if ((static_cast<int>(dataType) >= static_cast<int>(DBDataType::DB_KEY_FIRST)) &&
463 (static_cast<int>(dataType) <= static_cast<int>(DBDataType::DB_KEY_LAST)))
465 row_optional = handler.database.getKeyDBRow(name, ownerLabel, cred.smackLabel);
469 LogError("Unknown type of requested data" << (int)dataType);
470 return CKM_API_ERROR_BAD_REQUEST;
473 LogError("No row for given name, label and type");
474 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
479 if (!handler.crypto.haveKey(row.smackLabel)) {
481 auto key_optional = handler.database.getKey(row.smackLabel);
483 LogError("No key for given label in database");
484 return CKM_API_ERROR_DB_ERROR;
487 key = handler.keyProvider.getPureDEK(key);
488 handler.crypto.pushKey(cred.smackLabel, key);
490 handler.crypto.decryptRow(password, row);
492 return CKM_API_SUCCESS;
495 RawBuffer CKMLogic::getData(
501 const Password &password)
503 int retCode = CKM_API_SUCCESS;
507 retCode = getDataHelper(cred, dataType, name, label, password, row);
508 } catch (const KeyProvider::Exception::Base &e) {
509 LogError("KeyProvider failed with error: " << e.GetMessage());
510 retCode = CKM_API_ERROR_SERVER_ERROR;
511 } catch (const CryptoLogic::Exception::Base &e) {
512 LogError("CryptoLogic failed with message: " << e.GetMessage());
513 retCode = CKM_API_ERROR_SERVER_ERROR;
514 } catch (const DBCrypto::Exception::PermissionDenied &e) {
515 LogError("DBCrypto failed with message: " << e.GetMessage());
516 retCode = CKM_API_ERROR_ACCESS_DENIED;
517 } catch (const DBCrypto::Exception::Base &e) {
518 LogError("DBCrypto failed with message: " << e.GetMessage());
519 retCode = CKM_API_ERROR_DB_ERROR;
522 if (CKM_API_SUCCESS != retCode) {
524 row.dataType = dataType;
527 if ((CKM_API_SUCCESS == retCode) && (row.exportable == 0)) {
529 retCode = CKM_API_ERROR_NOT_EXPORTABLE;
532 // Prevent extracting private keys during cc-mode on
533 if((m_ccMode) && (row.dataType == DBDataType::KEY_RSA_PRIVATE ||
534 row.dataType == DBDataType::KEY_ECDSA_PRIVATE ||
535 row.dataType == DBDataType::KEY_DSA_PRIVATE))
538 retCode = CKM_API_ERROR_BAD_REQUEST;
541 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
544 static_cast<int>(row.dataType),
546 return response.Pop();
549 RawBuffer CKMLogic::getDataList(
554 int retCode = CKM_API_SUCCESS;
555 LabelNameVector labelNameVector;
557 if (0 < m_userDataMap.count(cred.uid)) {
558 auto &handler = m_userDataMap[cred.uid];
560 if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) {
561 handler.database.getNames(cred.smackLabel, dataType, labelNameVector);
563 handler.database.getKeyNames(cred.smackLabel, labelNameVector);
565 } Catch (CKM::Exception) {
566 LogError("Failed to get names");
567 retCode = CKM_API_ERROR_DB_ERROR;
570 retCode = CKM_API_ERROR_DB_LOCKED;
573 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
576 static_cast<int>(dataType),
578 return response.Pop();
582 int CKMLogic::createKeyPairHelper(
584 const KeyType key_type,
585 const int additional_param,
586 const Name &namePrivate,
587 const Name &namePublic,
588 const PolicySerializable &policyPrivate,
589 const PolicySerializable &policyPublic)
591 if (0 >= m_userDataMap.count(cred.uid))
592 return CKM_API_ERROR_DB_LOCKED;
594 auto &handler = m_userDataMap[cred.uid];
599 case KeyType::KEY_RSA_PUBLIC:
600 case KeyType::KEY_RSA_PRIVATE:
601 retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
604 case KeyType::KEY_DSA_PUBLIC:
605 case KeyType::KEY_DSA_PRIVATE:
606 retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
609 case KeyType::KEY_ECDSA_PUBLIC:
610 case KeyType::KEY_ECDSA_PRIVATE:
611 retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
615 return CKM_API_ERROR_INPUT_PARAM;
618 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
620 LogDebug("CryptoService error with code: " << retCode);
621 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
624 DBCrypto::Transaction transaction(&handler.database);
625 retCode = saveDataHelper(cred,
626 toDBDataType(prv.getType()),
631 if (CKM_API_SUCCESS != retCode)
634 retCode = saveDataHelper(cred,
635 toDBDataType(pub.getType()),
640 if (CKM_API_SUCCESS != retCode)
643 transaction.commit();
648 RawBuffer CKMLogic::createKeyPair(
650 LogicCommand protocol_cmd,
652 const int additional_param,
653 const Name &namePrivate,
654 const Name &namePublic,
655 const PolicySerializable &policyPrivate,
656 const PolicySerializable &policyPublic)
658 int retCode = CKM_API_SUCCESS;
660 KeyType key_type = KeyType::KEY_NONE;
663 case LogicCommand::CREATE_KEY_PAIR_RSA:
664 key_type = KeyType::KEY_RSA_PUBLIC;
666 case LogicCommand::CREATE_KEY_PAIR_DSA:
667 key_type = KeyType::KEY_DSA_PUBLIC;
669 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
670 key_type = KeyType::KEY_ECDSA_PUBLIC;
677 retCode = createKeyPairHelper(
686 } catch (DBCrypto::Exception::NameExists &e) {
687 LogDebug("DBCrypto error: name exists: " << e.GetMessage());
688 retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
689 } catch (DBCrypto::Exception::TransactionError &e) {
690 LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
691 retCode = CKM_API_ERROR_DB_ERROR;
692 } catch (CKM::CryptoLogic::Exception::Base &e) {
693 LogDebug("CryptoLogic error: " << e.GetMessage());
694 retCode = CKM_API_ERROR_SERVER_ERROR;
695 } catch (DBCrypto::Exception::InternalError &e) {
696 LogDebug("DBCrypto internal error: " << e.GetMessage());
697 retCode = CKM_API_ERROR_DB_ERROR;
700 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
703 RawBuffer CKMLogic::getCertificateChain(
706 const RawBuffer &certificate,
707 const RawBufferVector &untrustedRawCertVector)
711 CertificateImpl cert(certificate, DataFormat::FORM_DER);
712 CertificateImplVector untrustedCertVector;
713 CertificateImplVector chainVector;
714 RawBufferVector chainRawVector;
716 for (auto &e: untrustedRawCertVector)
717 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
719 LogDebug("Cert is empty: " << cert.empty());
721 int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
723 if (retCode == CKM_API_SUCCESS) {
724 for (auto &e : chainVector)
725 chainRawVector.push_back(e.getDER());
728 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
732 return response.Pop();
735 RawBuffer CKMLogic::getCertificateChain(
738 const RawBuffer &certificate,
739 const AliasVector &aliasVector)
741 int retCode = CKM_API_SUCCESS;
742 RawBufferVector chainRawVector;
744 CertificateImpl cert(certificate, DataFormat::FORM_DER);
745 CertificateImplVector untrustedCertVector;
746 CertificateImplVector chainVector;
750 retCode = CKM_API_ERROR_SERVER_ERROR;
754 for (auto &i: aliasVector) {
755 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i, Label(), Password(), row);
757 if (retCode != CKM_API_SUCCESS)
760 untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
763 retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
765 if (retCode != CKM_API_SUCCESS)
768 for (auto &i: chainVector)
769 chainRawVector.push_back(i.getDER());
771 } catch (const CryptoLogic::Exception::Base &e) {
772 LogError("DBCyptorModule failed with message: " << e.GetMessage());
773 retCode = CKM_API_ERROR_SERVER_ERROR;
774 } catch (const DBCrypto::Exception::PermissionDenied &e) {
775 LogError("DBCrypto failed with message: " << e.GetMessage());
776 retCode = CKM_API_ERROR_ACCESS_DENIED;
777 } catch (const DBCrypto::Exception::Base &e) {
778 LogError("DBCrypto failed with message: " << e.GetMessage());
779 retCode = CKM_API_ERROR_DB_ERROR;
781 LogError("Unknown error.");
785 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
789 return response.Pop();
792 RawBuffer CKMLogic::createSignature(
795 const Name &privateKeyName,
796 const Label & ownerLabel,
797 const Password &password, // password for private_key
798 const RawBuffer &message,
799 const HashAlgorithm hash,
800 const RSAPaddingAlgorithm padding)
806 int retCode = CKM_API_SUCCESS;
810 retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
811 if (CKM_API_SUCCESS != retCode) {
812 LogError("getDataHelper return error");
816 KeyImpl keyParsed(row.data, Password());
817 if (keyParsed.empty())
818 retCode = CKM_API_ERROR_SERVER_ERROR;
820 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
822 } catch (const KeyProvider::Exception::Base &e) {
823 LogError("KeyProvider failed with message: " << e.GetMessage());
824 retCode = CKM_API_ERROR_SERVER_ERROR;
825 } catch (const CryptoLogic::Exception::Base &e) {
826 LogError("CryptoLogic failed with message: " << e.GetMessage());
827 retCode = CKM_API_ERROR_SERVER_ERROR;
828 } catch (const DBCrypto::Exception::PermissionDenied &e) {
829 LogError("DBCrypto failed with message: " << e.GetMessage());
830 retCode = CKM_API_ERROR_ACCESS_DENIED;
831 } catch (const DBCrypto::Exception::Base &e) {
832 LogError("DBCrypto failed with message: " << e.GetMessage());
833 retCode = CKM_API_ERROR_DB_ERROR;
834 } catch (const CKM::Exception &e) {
835 LogError("Unknown CKM::Exception: " << e.GetMessage());
836 retCode = CKM_API_ERROR_SERVER_ERROR;
839 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
843 return response.Pop();
846 RawBuffer CKMLogic::verifySignature(
849 const Name &publicKeyOrCertName,
850 const Label & ownerLabel,
851 const Password &password, // password for public_key (optional)
852 const RawBuffer &message,
853 const RawBuffer &signature,
854 const HashAlgorithm hash,
855 const RSAPaddingAlgorithm padding)
857 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
865 retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
867 if (retCode == CKM_API_SUCCESS) {
868 key = KeyImpl(row.data);
869 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
870 retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
871 if (retCode != CKM_API_SUCCESS)
873 CertificateImpl cert(row.data, DataFormat::FORM_DER);
874 key = cert.getKeyImpl();
880 retCode = CKM_API_ERROR_SERVER_ERROR;
884 retCode = cs.verifySignature(key, message, signature, hash, padding);
886 } catch (const CryptoService::Exception::Crypto_internal &e) {
887 LogError("KeyProvider failed with message: " << e.GetMessage());
888 retCode = CKM_API_ERROR_SERVER_ERROR;
889 } catch (const CryptoService::Exception::opensslError &e) {
890 LogError("KeyProvider failed with message: " << e.GetMessage());
891 retCode = CKM_API_ERROR_SERVER_ERROR;
892 } catch (const KeyProvider::Exception::Base &e) {
893 LogError("KeyProvider failed with error: " << e.GetMessage());
894 retCode = CKM_API_ERROR_SERVER_ERROR;
895 } catch (const CryptoLogic::Exception::Base &e) {
896 LogError("CryptoLogic failed with message: " << e.GetMessage());
897 retCode = CKM_API_ERROR_SERVER_ERROR;
898 } catch (const DBCrypto::Exception::PermissionDenied &e) {
899 LogError("DBCrypto failed with message: " << e.GetMessage());
900 retCode = CKM_API_ERROR_ACCESS_DENIED;
901 } catch (const DBCrypto::Exception::Base &e) {
902 LogError("DBCrypto failed with message: " << e.GetMessage());
903 retCode = CKM_API_ERROR_DB_ERROR;
904 } catch (const CKM::Exception &e) {
905 LogError("Unknown CKM::Exception: " << e.GetMessage());
906 retCode = CKM_API_ERROR_SERVER_ERROR;
909 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
912 return response.Pop();
915 RawBuffer CKMLogic::allowAccess(
920 const Label &accessorLabel,
921 const AccessRight reqRights)
923 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
925 if (cred.smackLabel.empty()) {
926 retCode = CKM_API_ERROR_INPUT_PARAM;
927 } else if (0 < m_userDataMap.count(cred.uid) && !cred.smackLabel.empty()) {
929 retCode = m_userDataMap[cred.uid].database.setAccessRights(
934 } Catch (DBCrypto::Exception::InvalidArgs) {
935 LogError("Error: invalid args!");
936 retCode = CKM_API_ERROR_INPUT_PARAM;
937 } Catch (DBCrypto::Exception::PermissionDenied) {
938 LogError("Error: not enough permissions!");
939 retCode = CKM_API_ERROR_ACCESS_DENIED;
940 } Catch (CKM::Exception) {
941 LogError("Error in set row!");
942 retCode = CKM_API_ERROR_DB_ERROR;
945 retCode = CKM_API_ERROR_DB_LOCKED;
948 return MessageBuffer::Serialize(command, msgID, retCode).Pop();
951 RawBuffer CKMLogic::denyAccess(
956 const Label &accessorLabel)
958 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
960 if (cred.smackLabel.empty()) {
961 retCode = CKM_API_ERROR_INPUT_PARAM;
962 } else if (0 < m_userDataMap.count(cred.uid)) {
964 retCode = m_userDataMap[cred.uid].database.clearAccessRights(name, cred.smackLabel, accessorLabel);
965 } Catch (DBCrypto::Exception::PermissionDenied) {
966 LogError("Error: not enough permissions!");
967 retCode = CKM_API_ERROR_ACCESS_DENIED;
968 } Catch (DBCrypto::Exception::InvalidArgs) {
969 LogError("Error: permission not found!");
970 retCode = CKM_API_ERROR_INPUT_PARAM;
971 } Catch (CKM::Exception) {
972 LogError("Error in deleting row!");
973 retCode = CKM_API_ERROR_DB_ERROR;
976 retCode = CKM_API_ERROR_DB_LOCKED;
979 return MessageBuffer::Serialize(command, msgID, retCode).Pop();