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);
84 } catch (const KeyProvider::Exception::PassWordError &e) {
85 LogError("Incorrect Password " << e.GetMessage());
86 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
87 } catch (const KeyProvider::Exception::Base &e) {
88 LogError("Error in KeyProvider " << e.GetMessage());
89 retCode = CKM_API_ERROR_SERVER_ERROR;
90 } catch (const CryptoLogic::Exception::Base &e) {
91 LogError("CryptoLogic error: " << e.GetMessage());
92 retCode = CKM_API_ERROR_SERVER_ERROR;
93 } catch (const CKM::Exception &e) {
94 LogError("CKM::Exception: " << e.GetMessage());
95 retCode = CKM_API_ERROR_SERVER_ERROR;
98 if(retCode != CKM_API_SUCCESS) {
99 // When not successful, UserData in m_userDataMap should be erased.
100 // Because other operations make decision based on the existence of UserData in m_userDataMap.
101 m_userDataMap.erase(user);
104 return MessageBuffer::Serialize(retCode).Pop();
107 RawBuffer CKMLogic::updateCCMode() {
108 m_accessControl.updateCCMode();
109 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
112 RawBuffer CKMLogic::lockUserKey(uid_t user) {
113 int retCode = CKM_API_SUCCESS;
114 // TODO try catch for all errors that should be supported by error code
115 m_userDataMap.erase(user);
117 return MessageBuffer::Serialize(retCode).Pop();
121 RawBuffer CKMLogic::removeUserData(uid_t user) {
122 int retCode = CKM_API_SUCCESS;
123 // TODO try catch for all errors that should be supported by error code
124 m_userDataMap.erase(user);
129 return MessageBuffer::Serialize(retCode).Pop();
132 RawBuffer CKMLogic::changeUserPassword(
134 const Password &oldPassword,
135 const Password &newPassword)
137 int retCode = CKM_API_SUCCESS;
140 auto wrappedDomainKEK = fs.getDKEK();
141 if (wrappedDomainKEK.empty()) {
142 retCode = CKM_API_ERROR_BAD_REQUEST;
144 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
145 fs.saveDKEK(wrappedDomainKEK);
147 } catch (const KeyProvider::Exception::PassWordError &e) {
148 LogError("Incorrect Password " << e.GetMessage());
149 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
150 } catch (const KeyProvider::Exception::Base &e) {
151 LogError("Error in KeyProvider " << e.GetMessage());
152 retCode = CKM_API_ERROR_SERVER_ERROR;
153 } catch (const CKM::Exception &e) {
154 LogError("CKM::Exception: " << e.GetMessage());
155 retCode = CKM_API_ERROR_SERVER_ERROR;
158 return MessageBuffer::Serialize(retCode).Pop();
161 RawBuffer CKMLogic::resetUserPassword(
163 const Password &newPassword)
165 int retCode = CKM_API_SUCCESS;
167 if (0 == m_userDataMap.count(user)) {
168 retCode = CKM_API_ERROR_BAD_REQUEST;
170 auto &handler = m_userDataMap[user];
172 fs.saveDKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
175 return MessageBuffer::Serialize(retCode).Pop();
178 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
179 int retCode = CKM_API_SUCCESS;
183 if (smackLabel.empty()) {
184 retCode = CKM_API_ERROR_INPUT_PARAM;
186 UidVector uids = FileSystem::getUIDsFromDBFile();
187 for (auto userId : uids) {
188 if (0 == m_userDataMap.count(userId)) {
189 FileSystem fs(userId);
190 fs.addRemovedApp(smackLabel);
192 auto &handle = m_userDataMap[userId];
193 handle.database.deleteKey(smackLabel);
198 } catch (const DBCrypto::Exception::InternalError &e) {
199 LogError("DBCrypto couldn't remove data: " << e.GetMessage());
200 retCode = CKM_API_ERROR_DB_ERROR;
201 } catch (const DBCrypto::Exception::TransactionError &e) {
202 LogError("DBCrypto transaction failed with message " << e.GetMessage());
203 retCode = CKM_API_ERROR_DB_ERROR;
206 return MessageBuffer::Serialize(retCode).Pop();
209 int CKMLogic::saveDataHelper(
210 const Credentials &cred,
213 const RawBuffer &key,
214 const PolicySerializable &policy)
216 if (0 == m_userDataMap.count(cred.uid))
217 return CKM_API_ERROR_DB_LOCKED;
219 // proceed to data save
220 DBRow row = { name, cred.smackLabel,
221 policy.extractable, dataType, DBCMAlgType::NONE,
222 0, RawBuffer(), static_cast<int>(key.size()), key, RawBuffer() };
224 auto &handler = m_userDataMap[cred.uid];
225 DBCrypto::Transaction transaction(&handler.database);
227 // check if not a duplicate
228 if( handler.database.isNameLabelPresent(name, cred.smackLabel) )
229 return CKM_API_ERROR_DB_ALIAS_EXISTS;
231 // encryption section
232 if (!handler.crypto.haveKey(cred.smackLabel)) {
234 auto key_optional = handler.database.getKey(cred.smackLabel);
236 LogDebug("No Key in database found. Generating new one for label: "
238 got_key = handler.keyProvider.generateDEK(cred.smackLabel);
239 handler.database.saveKey(cred.smackLabel, got_key);
241 LogDebug("Key from DB");
242 got_key = *key_optional;
245 got_key = handler.keyProvider.getPureDEK(got_key);
246 handler.crypto.pushKey(cred.smackLabel, got_key);
249 // do not encrypt data with password during cc_mode on
250 if(m_accessControl.isCCMode()) {
251 handler.crypto.encryptRow("", row);
253 handler.crypto.encryptRow(policy.password, row);
256 handler.database.saveDBRow(row);
257 transaction.commit();
258 return CKM_API_SUCCESS;
261 void CKMLogic::verifyBinaryData(DBDataType dataType, const RawBuffer &input_data) const
263 // verify the data integrity
266 case DBDataType::KEY_RSA_PUBLIC:
267 case DBDataType::KEY_RSA_PRIVATE:
268 case DBDataType::KEY_ECDSA_PUBLIC:
269 case DBDataType::KEY_ECDSA_PRIVATE:
270 case DBDataType::KEY_DSA_PUBLIC:
271 case DBDataType::KEY_DSA_PRIVATE:
272 case DBDataType::KEY_AES:
274 KeyShPtr output_key = CKM::Key::create(input_data);
275 if(output_key.get() == NULL)
276 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid key data");
280 case DBDataType::CERTIFICATE:
282 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
283 if(cert.get() == NULL)
284 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid certificate data");
288 // TODO: add here BINARY_DATA verification, i.e: max size etc.
294 RawBuffer CKMLogic::saveData(
295 const Credentials &cred,
300 const RawBuffer &key,
301 const PolicySerializable &policy)
303 int retCode = CKM_API_SUCCESS;
305 if (!label.empty() && label.compare(cred.smackLabel))
306 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "smack label in param is not your label");
308 verifyBinaryData(dataType, key);
310 retCode = saveDataHelper(cred, dataType, name, key, policy);
311 LogDebug("SaveDataHelper returned: " << retCode);
312 } catch (const CKMLogic::Exception::InputDataInvalid &e) {
313 LogError("Provided data invalid: " << e.GetMessage());
314 retCode = CKM_API_ERROR_INPUT_PARAM;
315 } catch (const KeyProvider::Exception::Base &e) {
316 LogError("KeyProvider failed with message: " << e.GetMessage());
317 retCode = CKM_API_ERROR_SERVER_ERROR;
318 } catch (const CryptoLogic::Exception::Base &e) {
319 LogError("CryptoLogic failed with message: " << e.GetMessage());
320 retCode = CKM_API_ERROR_SERVER_ERROR;
321 } catch (const DBCrypto::Exception::InternalError &e) {
322 LogError("DBCrypto failed with message: " << e.GetMessage());
323 retCode = CKM_API_ERROR_DB_ERROR;
324 } catch (const DBCrypto::Exception::TransactionError &e) {
325 LogError("DBCrypto transaction failed with message " << e.GetMessage());
326 retCode = CKM_API_ERROR_DB_ERROR;
329 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
332 static_cast<int>(dataType));
333 return response.Pop();
336 int CKMLogic::removeDataHelper(
337 const Credentials &cred,
339 const Label &ownerLabel)
341 if (0 == m_userDataMap.count(cred.uid))
342 return CKM_API_ERROR_DB_LOCKED;
344 // verify name and label are correct
345 if( !checkNameAndLabelValid(name, ownerLabel) )
347 LogError("Invalid label or name format");
348 return CKM_API_ERROR_INPUT_PARAM;
351 auto &database = m_userDataMap[cred.uid].database;
352 DBCrypto::Transaction transaction(&database);
354 // read and check permissions
355 PermissionOptional permissionRowOpt =
356 database.getPermissionRow(name, ownerLabel, cred.smackLabel);
357 int access_ec = m_accessControl.canDelete(ownerLabel, PermissionForLabel(cred.smackLabel, permissionRowOpt));
358 if(access_ec != CKM_API_SUCCESS)
360 LogWarning("access control check result: " << access_ec);
364 auto erased = database.deleteDBRow(name, ownerLabel);
365 // check if the data existed or not
367 transaction.commit();
369 LogError("No row for given name and label");
370 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
373 return CKM_API_SUCCESS;
376 RawBuffer CKMLogic::removeData(
377 const Credentials &cred,
385 // use client label if not explicitly provided
386 const Label & ownerLabel = label.empty() ? cred.smackLabel : label;
388 retCode = removeDataHelper(cred, name, ownerLabel);
389 } Catch (CKM::Exception) {
390 LogError("Error in deleting row!");
391 retCode = CKM_API_ERROR_DB_ERROR;
394 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
397 static_cast<int>(dataType));
398 return response.Pop();
401 bool CKMLogic::checkNameAndLabelValid(const Name &name, const Label &label)
403 // verify the name is valid
404 if(name.find(':') != Label::npos)
407 // verify the label is valid
408 if(label.find(LABEL_NAME_SEPARATOR) != Label::npos)
414 int CKMLogic::readDataRowHelper(const Name &name,
415 const Label &ownerLabel,
421 DBCrypto::DBRowOptional row_optional;
422 // TODO: move this check into request deserialization
423 if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
424 (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
426 LogError("Unknown type of requested data: " << (int)dataType);
427 return CKM_API_ERROR_BAD_REQUEST;
429 // TODO: provide internal type rather than using DB types in socket comms
430 else if ((dataType >= DBDataType::DB_KEY_FIRST) &&
431 (dataType <= DBDataType::DB_KEY_LAST))
433 // read all key types
434 row_optional = database.getDBRow(name,
436 DBDataType::DB_KEY_FIRST,
437 DBDataType::DB_KEY_LAST);
440 // read anything else
441 row_optional = database.getDBRow(name,
447 LogError("No row for given name, label and type");
448 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
453 return CKM_API_SUCCESS;
456 int CKMLogic::checkDataPermissionsHelper(const Name &name,
457 const Label &ownerLabel,
458 const Label &accessorLabel,
463 PermissionOptional permissionRowOpt =
464 database.getPermissionRow(name, ownerLabel, accessorLabel);
467 return m_accessControl.canExport(row, PermissionForLabel(accessorLabel, permissionRowOpt));
468 return m_accessControl.canRead(row, PermissionForLabel(accessorLabel, permissionRowOpt));
471 int CKMLogic::readDataHelper(
473 const Credentials &cred,
477 const Password &password,
480 if (0 == m_userDataMap.count(cred.uid))
481 return CKM_API_ERROR_DB_LOCKED;
483 // use client label if not explicitly provided
484 const Label ownerLabel = label.empty() ? cred.smackLabel : label;
486 // verify name and label are correct
487 if (true != checkNameAndLabelValid(name, ownerLabel))
488 return CKM_API_ERROR_INPUT_PARAM;
490 auto &handler = m_userDataMap[cred.uid];
493 DBCrypto::Transaction transaction(&handler.database);
494 int ec = readDataRowHelper(name, ownerLabel, dataType, handler.database, row);
495 if(CKM_API_SUCCESS != ec)
499 // check access rights
500 ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
501 if(CKM_API_SUCCESS != ec)
505 if (!handler.crypto.haveKey(row.ownerLabel)) {
507 auto key_optional = handler.database.getKey(row.ownerLabel);
509 LogError("No key for given label in database");
510 return CKM_API_ERROR_DB_ERROR;
513 key = handler.keyProvider.getPureDEK(key);
514 handler.crypto.pushKey(row.ownerLabel, key);
516 handler.crypto.decryptRow(password, row);
518 return CKM_API_SUCCESS;
521 RawBuffer CKMLogic::getData(
522 const Credentials &cred,
527 const Password &password)
529 int retCode = CKM_API_SUCCESS;
533 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
534 } catch (const KeyProvider::Exception::Base &e) {
535 LogError("KeyProvider failed with error: " << e.GetMessage());
536 retCode = CKM_API_ERROR_SERVER_ERROR;
537 } catch (const CryptoLogic::Exception::Base &e) {
538 LogError("CryptoLogic failed with message: " << e.GetMessage());
539 retCode = CKM_API_ERROR_SERVER_ERROR;
540 } catch (const DBCrypto::Exception::Base &e) {
541 LogError("DBCrypto failed with message: " << e.GetMessage());
542 retCode = CKM_API_ERROR_DB_ERROR;
545 if (CKM_API_SUCCESS != retCode) {
547 row.dataType = dataType;
550 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
553 static_cast<int>(row.dataType),
555 return response.Pop();
558 RawBuffer CKMLogic::getDataList(
559 const Credentials &cred,
563 int retCode = CKM_API_SUCCESS;
564 LabelNameVector labelNameVector;
566 if (0 < m_userDataMap.count(cred.uid)) {
567 auto &database = m_userDataMap[cred.uid].database;
571 // TODO: move this check into request deserialization
572 if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
573 (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
575 LogError("Unknown type of requested data: " << (int)dataType);
576 retCode = CKM_API_ERROR_BAD_REQUEST;
578 // TODO: provide internal type rather than using DB types in socket comms
579 else if ((dataType >= DBDataType::DB_KEY_FIRST) && (dataType <= DBDataType::DB_KEY_LAST))
581 // list all key types
582 database.listNames(cred.smackLabel,
584 DBDataType::DB_KEY_FIRST,
585 DBDataType::DB_KEY_LAST);
588 // list anything else
589 database.listNames(cred.smackLabel,
594 Catch (CKM::Exception) {
595 LogError("Failed to get names");
596 retCode = CKM_API_ERROR_DB_ERROR;
599 retCode = CKM_API_ERROR_DB_LOCKED;
602 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
605 static_cast<int>(dataType),
607 return response.Pop();
611 int CKMLogic::createKeyPairHelper(
612 const Credentials &cred,
613 const KeyType key_type,
614 const int additional_param,
615 const Name &namePrivate,
616 const Name &namePublic,
617 const PolicySerializable &policyPrivate,
618 const PolicySerializable &policyPublic)
620 if (0 == m_userDataMap.count(cred.uid))
621 return CKM_API_ERROR_DB_LOCKED;
627 case KeyType::KEY_RSA_PUBLIC:
628 case KeyType::KEY_RSA_PRIVATE:
629 retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
632 case KeyType::KEY_DSA_PUBLIC:
633 case KeyType::KEY_DSA_PRIVATE:
634 retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
637 case KeyType::KEY_ECDSA_PUBLIC:
638 case KeyType::KEY_ECDSA_PRIVATE:
639 retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
643 return CKM_API_ERROR_INPUT_PARAM;
646 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
648 LogDebug("CryptoService error with code: " << retCode);
649 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
652 auto &database = m_userDataMap[cred.uid].database;
653 DBCrypto::Transaction transaction(&database);
654 retCode = saveDataHelper(cred,
655 toDBDataType(prv.getType()),
660 if (CKM_API_SUCCESS != retCode)
663 retCode = saveDataHelper(cred,
664 toDBDataType(pub.getType()),
669 if (CKM_API_SUCCESS != retCode)
672 transaction.commit();
677 RawBuffer CKMLogic::createKeyPair(
678 const Credentials &cred,
679 LogicCommand protocol_cmd,
681 const int additional_param,
682 const Name &namePrivate,
683 const Name &namePublic,
684 const PolicySerializable &policyPrivate,
685 const PolicySerializable &policyPublic)
687 int retCode = CKM_API_SUCCESS;
689 KeyType key_type = KeyType::KEY_NONE;
692 case LogicCommand::CREATE_KEY_PAIR_RSA:
693 key_type = KeyType::KEY_RSA_PUBLIC;
695 case LogicCommand::CREATE_KEY_PAIR_DSA:
696 key_type = KeyType::KEY_DSA_PUBLIC;
698 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
699 key_type = KeyType::KEY_ECDSA_PUBLIC;
706 retCode = createKeyPairHelper(
714 } catch (DBCrypto::Exception::TransactionError &e) {
715 LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
716 retCode = CKM_API_ERROR_DB_ERROR;
717 } catch (CKM::CryptoLogic::Exception::Base &e) {
718 LogDebug("CryptoLogic error: " << e.GetMessage());
719 retCode = CKM_API_ERROR_SERVER_ERROR;
720 } catch (DBCrypto::Exception::InternalError &e) {
721 LogDebug("DBCrypto internal error: " << e.GetMessage());
722 retCode = CKM_API_ERROR_DB_ERROR;
725 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
728 RawBuffer CKMLogic::getCertificateChain(
729 const Credentials &cred,
731 const RawBuffer &certificate,
732 const RawBufferVector &untrustedRawCertVector)
736 CertificateImpl cert(certificate, DataFormat::FORM_DER);
737 CertificateImplVector untrustedCertVector;
738 CertificateImplVector chainVector;
739 RawBufferVector chainRawVector;
741 for (auto &e: untrustedRawCertVector)
742 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
744 LogDebug("Cert is empty: " << cert.empty());
746 int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
748 if (retCode == CKM_API_SUCCESS) {
749 for (auto &e : chainVector)
750 chainRawVector.push_back(e.getDER());
753 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
757 return response.Pop();
760 int CKMLogic::getCertificateChainHelper(
761 const Credentials &cred,
762 const RawBuffer &certificate,
763 const LabelNameVector &labelNameVector,
764 RawBufferVector & chainRawVector)
766 CertificateImpl cert(certificate, DataFormat::FORM_DER);
767 CertificateImplVector untrustedCertVector;
768 CertificateImplVector chainVector;
772 return CKM_API_ERROR_SERVER_ERROR;
774 for (auto &i: labelNameVector) {
775 int ec = readDataHelper(false, cred, DBDataType::CERTIFICATE, i.second, i.first, Password(), row);
776 if (ec != CKM_API_SUCCESS)
779 untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
782 int ec = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
783 if (ec != CKM_API_SUCCESS)
786 for (auto &i: chainVector)
787 chainRawVector.push_back(i.getDER());
789 return CKM_API_SUCCESS;
792 RawBuffer CKMLogic::getCertificateChain(
793 const Credentials &cred,
795 const RawBuffer &certificate,
796 const LabelNameVector &labelNameVector)
798 int retCode = CKM_API_SUCCESS;
799 RawBufferVector chainRawVector;
802 retCode = getCertificateChainHelper(cred, certificate, labelNameVector, chainRawVector);
803 } catch (const CryptoLogic::Exception::Base &e) {
804 LogError("DBCyptorModule failed with message: " << e.GetMessage());
805 retCode = CKM_API_ERROR_SERVER_ERROR;
806 } catch (const DBCrypto::Exception::Base &e) {
807 LogError("DBCrypto failed with message: " << e.GetMessage());
808 retCode = CKM_API_ERROR_DB_ERROR;
810 LogError("Unknown error.");
813 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
817 return response.Pop();
820 RawBuffer CKMLogic::createSignature(
821 const Credentials &cred,
823 const Name &privateKeyName,
824 const Label & ownerLabel,
825 const Password &password, // password for private_key
826 const RawBuffer &message,
827 const HashAlgorithm hash,
828 const RSAPaddingAlgorithm padding)
834 int retCode = CKM_API_SUCCESS;
837 retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
838 if(retCode == CKM_API_SUCCESS)
840 KeyImpl keyParsed(row.data, Password());
841 if (keyParsed.empty())
842 retCode = CKM_API_ERROR_SERVER_ERROR;
844 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
846 } catch (const KeyProvider::Exception::Base &e) {
847 LogError("KeyProvider failed with message: " << e.GetMessage());
848 retCode = CKM_API_ERROR_SERVER_ERROR;
849 } catch (const CryptoLogic::Exception::Base &e) {
850 LogError("CryptoLogic failed with message: " << e.GetMessage());
851 retCode = CKM_API_ERROR_SERVER_ERROR;
852 } catch (const DBCrypto::Exception::Base &e) {
853 LogError("DBCrypto failed with message: " << e.GetMessage());
854 retCode = CKM_API_ERROR_DB_ERROR;
855 } catch (const CKM::Exception &e) {
856 LogError("Unknown CKM::Exception: " << e.GetMessage());
857 retCode = CKM_API_ERROR_SERVER_ERROR;
860 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
864 return response.Pop();
867 RawBuffer CKMLogic::verifySignature(
868 const Credentials &cred,
870 const Name &publicKeyOrCertName,
871 const Label & ownerLabel,
872 const Password &password, // password for public_key (optional)
873 const RawBuffer &message,
874 const RawBuffer &signature,
875 const HashAlgorithm hash,
876 const RSAPaddingAlgorithm padding)
878 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
886 retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
888 if (retCode == CKM_API_SUCCESS) {
889 key = KeyImpl(row.data);
890 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
891 retCode = readDataHelper(false, cred, DBDataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
892 if (retCode != CKM_API_SUCCESS)
894 CertificateImpl cert(row.data, DataFormat::FORM_DER);
895 key = cert.getKeyImpl();
901 retCode = CKM_API_ERROR_SERVER_ERROR;
905 retCode = cs.verifySignature(key, message, signature, hash, padding);
907 } catch (const CryptoService::Exception::Crypto_internal &e) {
908 LogError("KeyProvider failed with message: " << e.GetMessage());
909 retCode = CKM_API_ERROR_SERVER_ERROR;
910 } catch (const CryptoService::Exception::opensslError &e) {
911 LogError("KeyProvider failed with message: " << e.GetMessage());
912 retCode = CKM_API_ERROR_SERVER_ERROR;
913 } catch (const KeyProvider::Exception::Base &e) {
914 LogError("KeyProvider failed with error: " << e.GetMessage());
915 retCode = CKM_API_ERROR_SERVER_ERROR;
916 } catch (const CryptoLogic::Exception::Base &e) {
917 LogError("CryptoLogic failed with message: " << e.GetMessage());
918 retCode = CKM_API_ERROR_SERVER_ERROR;
919 } catch (const DBCrypto::Exception::Base &e) {
920 LogError("DBCrypto failed with message: " << e.GetMessage());
921 retCode = CKM_API_ERROR_DB_ERROR;
922 } catch (const CKM::Exception &e) {
923 LogError("Unknown CKM::Exception: " << e.GetMessage());
924 retCode = CKM_API_ERROR_SERVER_ERROR;
927 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
930 return response.Pop();
933 int CKMLogic::setPermissionHelper(
934 const Credentials &cred,
936 const Label &accessorLabel,
937 const Permission reqRights)
940 if(cred.smackLabel.empty() || cred.smackLabel==accessorLabel)
941 return CKM_API_ERROR_INPUT_PARAM;
943 if (0 == m_userDataMap.count(cred.uid))
944 return CKM_API_ERROR_DB_LOCKED;
945 auto &database = m_userDataMap[cred.uid].database;
946 DBCrypto::Transaction transaction(&database);
948 if( ! database.isNameLabelPresent(name, cred.smackLabel) )
949 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
951 // removing non-existing permissions: fail
952 if(reqRights == Permission::NONE)
954 if( !database.getPermissionRow(name, cred.smackLabel, accessorLabel) )
955 return CKM_API_ERROR_INPUT_PARAM;
958 retCode = database.setPermission(name,
963 transaction.commit();
968 RawBuffer CKMLogic::setPermission(
969 const Credentials &cred,
973 const Label &accessorLabel,
974 const Permission reqRights)
978 retCode = setPermissionHelper(cred, name, accessorLabel, reqRights);
979 } Catch (CKM::Exception) {
980 LogError("Error in set row!");
981 retCode = CKM_API_ERROR_DB_ERROR;
984 return MessageBuffer::Serialize(command, msgID, retCode).Pop();