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";
36 bool isLabelValid(const CKM::Label &label) {
37 // TODO: copy code from libprivilege control (for check smack label)
38 if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos)
43 bool isNameValid(const CKM::Name &name) {
44 if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos)
49 } // anonymous namespace
55 if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
56 LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
59 m_accessControl.updateCCMode();
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);
98 } catch (const KeyProvider::Exception::PassWordError &e) {
99 LogError("Incorrect Password " << e.GetMessage());
100 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
101 } catch (const KeyProvider::Exception::Base &e) {
102 LogError("Error in KeyProvider " << e.GetMessage());
103 retCode = CKM_API_ERROR_SERVER_ERROR;
104 } catch (const CryptoLogic::Exception::Base &e) {
105 LogError("CryptoLogic error: " << e.GetMessage());
106 retCode = CKM_API_ERROR_SERVER_ERROR;
107 } catch (const CKM::Exception &e) {
108 LogError("CKM::Exception: " << e.GetMessage());
109 retCode = CKM_API_ERROR_SERVER_ERROR;
112 if(retCode != CKM_API_SUCCESS) {
113 // When not successful, UserData in m_userDataMap should be erased.
114 // Because other operations make decision based on the existence of UserData in m_userDataMap.
115 m_userDataMap.erase(user);
118 return MessageBuffer::Serialize(retCode).Pop();
121 RawBuffer CKMLogic::updateCCMode() {
122 m_accessControl.updateCCMode();
123 return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop();
126 RawBuffer CKMLogic::lockUserKey(uid_t user) {
127 int retCode = CKM_API_SUCCESS;
128 // TODO try catch for all errors that should be supported by error code
129 m_userDataMap.erase(user);
131 return MessageBuffer::Serialize(retCode).Pop();
135 RawBuffer CKMLogic::removeUserData(uid_t user) {
136 int retCode = CKM_API_SUCCESS;
137 // TODO try catch for all errors that should be supported by error code
138 m_userDataMap.erase(user);
143 return MessageBuffer::Serialize(retCode).Pop();
146 RawBuffer CKMLogic::changeUserPassword(
148 const Password &oldPassword,
149 const Password &newPassword)
151 int retCode = CKM_API_SUCCESS;
154 auto wrappedDomainKEK = fs.getDKEK();
155 if (wrappedDomainKEK.empty()) {
156 retCode = CKM_API_ERROR_BAD_REQUEST;
158 wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
159 fs.saveDKEK(wrappedDomainKEK);
161 } catch (const KeyProvider::Exception::PassWordError &e) {
162 LogError("Incorrect Password " << e.GetMessage());
163 retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
164 } catch (const KeyProvider::Exception::Base &e) {
165 LogError("Error in KeyProvider " << e.GetMessage());
166 retCode = CKM_API_ERROR_SERVER_ERROR;
167 } catch (const CKM::Exception &e) {
168 LogError("CKM::Exception: " << e.GetMessage());
169 retCode = CKM_API_ERROR_SERVER_ERROR;
172 return MessageBuffer::Serialize(retCode).Pop();
175 RawBuffer CKMLogic::resetUserPassword(
177 const Password &newPassword)
179 int retCode = CKM_API_SUCCESS;
181 if (0 == m_userDataMap.count(user)) {
182 retCode = CKM_API_ERROR_BAD_REQUEST;
184 auto &handler = m_userDataMap[user];
186 fs.saveDKEK(handler.keyProvider.getWrappedDomainKEK(newPassword));
189 return MessageBuffer::Serialize(retCode).Pop();
192 RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) {
193 int retCode = CKM_API_SUCCESS;
197 if (smackLabel.empty()) {
198 retCode = CKM_API_ERROR_INPUT_PARAM;
200 UidVector uids = FileSystem::getUIDsFromDBFile();
201 for (auto userId : uids) {
202 if (0 == m_userDataMap.count(userId)) {
203 FileSystem fs(userId);
204 fs.addRemovedApp(smackLabel);
206 auto &handle = m_userDataMap[userId];
207 handle.database.deleteKey(smackLabel);
212 } catch (const DBCrypto::Exception::InternalError &e) {
213 LogError("DBCrypto couldn't remove data: " << e.GetMessage());
214 retCode = CKM_API_ERROR_DB_ERROR;
215 } catch (const DBCrypto::Exception::TransactionError &e) {
216 LogError("DBCrypto transaction failed with message " << e.GetMessage());
217 retCode = CKM_API_ERROR_DB_ERROR;
220 return MessageBuffer::Serialize(retCode).Pop();
223 int CKMLogic::saveDataHelper(
224 const Credentials &cred,
228 const RawBuffer &key,
229 const PolicySerializable &policy)
231 // use client label if not explicitly provided
232 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
234 // verify name and label are correct
235 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
236 LogWarning("Invalid parameter passed to key-manager");
237 return CKM_API_ERROR_INPUT_PARAM;
240 // check if allowed to save using ownerLabel
241 int access_ec = m_accessControl.canSave(ownerLabel, cred.smackLabel);
242 if(access_ec != CKM_API_SUCCESS)
244 LogWarning("label " << cred.smackLabel << " can not save rows using label " << ownerLabel);
248 // proceed to data save
249 DBRow row = { name, cred.smackLabel,
250 policy.extractable, dataType, DBCMAlgType::NONE,
251 0, RawBuffer(), static_cast<int>(key.size()), key, RawBuffer() };
253 if (0 == m_userDataMap.count(cred.uid))
254 return CKM_API_ERROR_DB_LOCKED;
256 auto &handler = m_userDataMap[cred.uid];
257 DBCrypto::Transaction transaction(&handler.database);
259 // check if not a duplicate
260 if( handler.database.isNameLabelPresent(name, cred.smackLabel) )
261 return CKM_API_ERROR_DB_ALIAS_EXISTS;
263 // encryption section
264 if (!handler.crypto.haveKey(cred.smackLabel)) {
266 auto key_optional = handler.database.getKey(cred.smackLabel);
268 LogDebug("No Key in database found. Generating new one for label: "
270 got_key = handler.keyProvider.generateDEK(cred.smackLabel);
271 handler.database.saveKey(cred.smackLabel, got_key);
273 LogDebug("Key from DB");
274 got_key = *key_optional;
277 got_key = handler.keyProvider.getPureDEK(got_key);
278 handler.crypto.pushKey(cred.smackLabel, got_key);
281 // do not encrypt data with password during cc_mode on
282 if(m_accessControl.isCCMode()) {
283 handler.crypto.encryptRow("", row);
285 handler.crypto.encryptRow(policy.password, row);
288 handler.database.saveDBRow(row);
289 transaction.commit();
290 return CKM_API_SUCCESS;
293 void CKMLogic::verifyBinaryData(DBDataType dataType, const RawBuffer &input_data) const
295 // verify the data integrity
298 case DBDataType::KEY_RSA_PUBLIC:
299 case DBDataType::KEY_RSA_PRIVATE:
300 case DBDataType::KEY_ECDSA_PUBLIC:
301 case DBDataType::KEY_ECDSA_PRIVATE:
302 case DBDataType::KEY_DSA_PUBLIC:
303 case DBDataType::KEY_DSA_PRIVATE:
304 case DBDataType::KEY_AES:
306 KeyShPtr output_key = CKM::Key::create(input_data);
307 if(output_key.get() == NULL)
308 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid key data");
312 case DBDataType::CERTIFICATE:
314 CertificateShPtr cert = CKM::Certificate::create(input_data, DataFormat::FORM_DER);
315 if(cert.get() == NULL)
316 ThrowMsg(CKMLogic::Exception::InputDataInvalid, "provided binary data is not valid certificate data");
320 // TODO: add here BINARY_DATA verification, i.e: max size etc.
326 RawBuffer CKMLogic::saveData(
327 const Credentials &cred,
332 const RawBuffer &key,
333 const PolicySerializable &policy)
335 int retCode = CKM_API_SUCCESS;
337 verifyBinaryData(dataType, key);
339 retCode = saveDataHelper(cred, dataType, name, label, key, policy);
340 LogDebug("SaveDataHelper returned: " << retCode);
341 } catch (const CKMLogic::Exception::InputDataInvalid &e) {
342 LogError("Provided data invalid: " << e.GetMessage());
343 retCode = CKM_API_ERROR_INPUT_PARAM;
344 } catch (const KeyProvider::Exception::Base &e) {
345 LogError("KeyProvider failed with message: " << e.GetMessage());
346 retCode = CKM_API_ERROR_SERVER_ERROR;
347 } catch (const CryptoLogic::Exception::Base &e) {
348 LogError("CryptoLogic failed with message: " << e.GetMessage());
349 retCode = CKM_API_ERROR_SERVER_ERROR;
350 } catch (const DBCrypto::Exception::InternalError &e) {
351 LogError("DBCrypto failed with message: " << e.GetMessage());
352 retCode = CKM_API_ERROR_DB_ERROR;
353 } catch (const DBCrypto::Exception::TransactionError &e) {
354 LogError("DBCrypto transaction failed with message " << e.GetMessage());
355 retCode = CKM_API_ERROR_DB_ERROR;
358 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE),
361 static_cast<int>(dataType));
362 return response.Pop();
365 int CKMLogic::removeDataHelper(
366 const Credentials &cred,
368 const Label &ownerLabel)
370 if (0 == m_userDataMap.count(cred.uid))
371 return CKM_API_ERROR_DB_LOCKED;
373 if (!isNameValid(name) || !isLabelValid(ownerLabel)) {
374 LogError("Invalid label or name format");
375 return CKM_API_ERROR_INPUT_PARAM;
378 auto &database = m_userDataMap[cred.uid].database;
379 DBCrypto::Transaction transaction(&database);
381 // read and check permissions
382 PermissionOptional permissionRowOpt =
383 database.getPermissionRow(name, ownerLabel, cred.smackLabel);
384 int access_ec = m_accessControl.canDelete(ownerLabel, PermissionForLabel(cred.smackLabel, permissionRowOpt));
385 if(access_ec != CKM_API_SUCCESS)
387 LogWarning("access control check result: " << access_ec);
391 auto erased = database.deleteDBRow(name, ownerLabel);
392 // check if the data existed or not
394 transaction.commit();
396 LogError("No row for given name and label");
397 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
400 return CKM_API_SUCCESS;
403 RawBuffer CKMLogic::removeData(
404 const Credentials &cred,
412 // use client label if not explicitly provided
413 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
415 retCode = removeDataHelper(cred, name, ownerLabel);
416 } Catch (CKM::Exception) {
417 LogError("Error in deleting row!");
418 retCode = CKM_API_ERROR_DB_ERROR;
421 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE),
424 static_cast<int>(dataType));
425 return response.Pop();
428 int CKMLogic::readDataRowHelper(const Name &name,
429 const Label &ownerLabel,
435 DBCrypto::DBRowOptional row_optional;
436 // TODO: move this check into request deserialization
437 if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
438 (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
440 LogError("Unknown type of requested data: " << (int)dataType);
441 return CKM_API_ERROR_BAD_REQUEST;
443 // TODO: provide internal type rather than using DB types in socket comms
444 else if ((dataType >= DBDataType::DB_KEY_FIRST) &&
445 (dataType <= DBDataType::DB_KEY_LAST))
447 // read all key types
448 row_optional = database.getDBRow(name,
450 DBDataType::DB_KEY_FIRST,
451 DBDataType::DB_KEY_LAST);
454 // read anything else
455 row_optional = database.getDBRow(name,
461 LogError("No row for given name, label and type");
462 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
467 return CKM_API_SUCCESS;
470 int CKMLogic::checkDataPermissionsHelper(const Name &name,
471 const Label &ownerLabel,
472 const Label &accessorLabel,
477 PermissionOptional permissionRowOpt =
478 database.getPermissionRow(name, ownerLabel, accessorLabel);
481 return m_accessControl.canExport(row, PermissionForLabel(accessorLabel, permissionRowOpt));
482 return m_accessControl.canRead(row, PermissionForLabel(accessorLabel, permissionRowOpt));
485 int CKMLogic::readDataHelper(
487 const Credentials &cred,
491 const Password &password,
494 if (0 == m_userDataMap.count(cred.uid))
495 return CKM_API_ERROR_DB_LOCKED;
497 // use client label if not explicitly provided
498 const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
500 if (!isNameValid(name) || !isLabelValid(ownerLabel))
501 return CKM_API_ERROR_INPUT_PARAM;
503 auto &handler = m_userDataMap[cred.uid];
506 DBCrypto::Transaction transaction(&handler.database);
507 int ec = readDataRowHelper(name, ownerLabel, dataType, handler.database, row);
508 if(CKM_API_SUCCESS != ec)
512 // check access rights
513 ec = checkDataPermissionsHelper(name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database);
514 if(CKM_API_SUCCESS != ec)
518 if (!handler.crypto.haveKey(row.ownerLabel)) {
520 auto key_optional = handler.database.getKey(row.ownerLabel);
522 LogError("No key for given label in database");
523 return CKM_API_ERROR_DB_ERROR;
526 key = handler.keyProvider.getPureDEK(key);
527 handler.crypto.pushKey(row.ownerLabel, key);
529 handler.crypto.decryptRow(password, row);
531 return CKM_API_SUCCESS;
534 RawBuffer CKMLogic::getData(
535 const Credentials &cred,
540 const Password &password)
542 int retCode = CKM_API_SUCCESS;
546 retCode = readDataHelper(true, cred, dataType, name, label, password, row);
547 } catch (const KeyProvider::Exception::Base &e) {
548 LogError("KeyProvider failed with error: " << e.GetMessage());
549 retCode = CKM_API_ERROR_SERVER_ERROR;
550 } catch (const CryptoLogic::Exception::Base &e) {
551 LogError("CryptoLogic failed with message: " << e.GetMessage());
552 retCode = CKM_API_ERROR_SERVER_ERROR;
553 } catch (const DBCrypto::Exception::Base &e) {
554 LogError("DBCrypto failed with message: " << e.GetMessage());
555 retCode = CKM_API_ERROR_DB_ERROR;
558 if (CKM_API_SUCCESS != retCode) {
560 row.dataType = dataType;
563 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET),
566 static_cast<int>(row.dataType),
568 return response.Pop();
571 RawBuffer CKMLogic::getDataList(
572 const Credentials &cred,
576 int retCode = CKM_API_SUCCESS;
577 LabelNameVector labelNameVector;
579 if (0 < m_userDataMap.count(cred.uid)) {
580 auto &database = m_userDataMap[cred.uid].database;
584 // TODO: move this check into request deserialization
585 if((static_cast<int>(dataType)<static_cast<int>(DBDataType::DB_DATA_TYPE_FIRST)) ||
586 (static_cast<int>(dataType)>static_cast<int>(DBDataType::DB_DATA_TYPE_LAST)))
588 LogError("Unknown type of requested data: " << (int)dataType);
589 retCode = CKM_API_ERROR_BAD_REQUEST;
591 // TODO: provide internal type rather than using DB types in socket comms
592 else if ((dataType >= DBDataType::DB_KEY_FIRST) && (dataType <= DBDataType::DB_KEY_LAST))
594 // list all key types
595 database.listNames(cred.smackLabel,
597 DBDataType::DB_KEY_FIRST,
598 DBDataType::DB_KEY_LAST);
601 // list anything else
602 database.listNames(cred.smackLabel,
607 Catch (CKM::Exception) {
608 LogError("Failed to get names");
609 retCode = CKM_API_ERROR_DB_ERROR;
612 retCode = CKM_API_ERROR_DB_LOCKED;
615 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST),
618 static_cast<int>(dataType),
620 return response.Pop();
624 int CKMLogic::createKeyPairHelper(
625 const Credentials &cred,
626 const KeyType key_type,
627 const int additional_param,
628 const Name &namePrivate,
629 const Label &labelPrivate,
630 const Name &namePublic,
631 const Label &labelPublic,
632 const PolicySerializable &policyPrivate,
633 const PolicySerializable &policyPublic)
635 if (0 == m_userDataMap.count(cred.uid))
636 return CKM_API_ERROR_DB_LOCKED;
642 case KeyType::KEY_RSA_PUBLIC:
643 case KeyType::KEY_RSA_PRIVATE:
644 retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
647 case KeyType::KEY_DSA_PUBLIC:
648 case KeyType::KEY_DSA_PRIVATE:
649 retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
652 case KeyType::KEY_ECDSA_PUBLIC:
653 case KeyType::KEY_ECDSA_PRIVATE:
654 retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
658 return CKM_API_ERROR_INPUT_PARAM;
661 if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
663 LogDebug("CryptoService error with code: " << retCode);
664 return CKM_API_ERROR_SERVER_ERROR; // TODO error code
667 auto &database = m_userDataMap[cred.uid].database;
668 DBCrypto::Transaction transaction(&database);
669 retCode = saveDataHelper(cred,
670 toDBDataType(prv.getType()),
676 if (CKM_API_SUCCESS != retCode)
679 retCode = saveDataHelper(cred,
680 toDBDataType(pub.getType()),
686 if (CKM_API_SUCCESS != retCode)
689 transaction.commit();
694 RawBuffer CKMLogic::createKeyPair(
695 const Credentials &cred,
696 LogicCommand protocol_cmd,
698 const int additional_param,
699 const Name &namePrivate,
700 const Label &labelPrivate,
701 const Name &namePublic,
702 const Label &labelPublic,
703 const PolicySerializable &policyPrivate,
704 const PolicySerializable &policyPublic)
706 int retCode = CKM_API_SUCCESS;
708 KeyType key_type = KeyType::KEY_NONE;
711 case LogicCommand::CREATE_KEY_PAIR_RSA:
712 key_type = KeyType::KEY_RSA_PUBLIC;
714 case LogicCommand::CREATE_KEY_PAIR_DSA:
715 key_type = KeyType::KEY_DSA_PUBLIC;
717 case LogicCommand::CREATE_KEY_PAIR_ECDSA:
718 key_type = KeyType::KEY_ECDSA_PUBLIC;
725 retCode = createKeyPairHelper(
735 } catch (DBCrypto::Exception::TransactionError &e) {
736 LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
737 retCode = CKM_API_ERROR_DB_ERROR;
738 } catch (CKM::CryptoLogic::Exception::Base &e) {
739 LogDebug("CryptoLogic error: " << e.GetMessage());
740 retCode = CKM_API_ERROR_SERVER_ERROR;
741 } catch (DBCrypto::Exception::InternalError &e) {
742 LogDebug("DBCrypto internal error: " << e.GetMessage());
743 retCode = CKM_API_ERROR_DB_ERROR;
746 return MessageBuffer::Serialize(static_cast<int>(protocol_cmd), commandId, retCode).Pop();
749 RawBuffer CKMLogic::getCertificateChain(
750 const Credentials &cred,
752 const RawBuffer &certificate,
753 const RawBufferVector &untrustedRawCertVector)
757 CertificateImpl cert(certificate, DataFormat::FORM_DER);
758 CertificateImplVector untrustedCertVector;
759 CertificateImplVector chainVector;
760 RawBufferVector chainRawVector;
762 for (auto &e: untrustedRawCertVector)
763 untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
765 LogDebug("Cert is empty: " << cert.empty());
767 int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
769 if (retCode == CKM_API_SUCCESS) {
770 for (auto &e : chainVector)
771 chainRawVector.push_back(e.getDER());
774 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT),
778 return response.Pop();
781 int CKMLogic::getCertificateChainHelper(
782 const Credentials &cred,
783 const RawBuffer &certificate,
784 const LabelNameVector &labelNameVector,
785 RawBufferVector & chainRawVector)
787 CertificateImpl cert(certificate, DataFormat::FORM_DER);
788 CertificateImplVector untrustedCertVector;
789 CertificateImplVector chainVector;
793 return CKM_API_ERROR_SERVER_ERROR;
795 for (auto &i: labelNameVector) {
796 int ec = readDataHelper(false, cred, DBDataType::CERTIFICATE, i.second, i.first, Password(), row);
797 if (ec != CKM_API_SUCCESS)
800 untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
803 int ec = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
804 if (ec != CKM_API_SUCCESS)
807 for (auto &i: chainVector)
808 chainRawVector.push_back(i.getDER());
810 return CKM_API_SUCCESS;
813 RawBuffer CKMLogic::getCertificateChain(
814 const Credentials &cred,
816 const RawBuffer &certificate,
817 const LabelNameVector &labelNameVector)
819 int retCode = CKM_API_SUCCESS;
820 RawBufferVector chainRawVector;
823 retCode = getCertificateChainHelper(cred, certificate, labelNameVector, chainRawVector);
824 } catch (const CryptoLogic::Exception::Base &e) {
825 LogError("DBCyptorModule failed with message: " << e.GetMessage());
826 retCode = CKM_API_ERROR_SERVER_ERROR;
827 } catch (const DBCrypto::Exception::Base &e) {
828 LogError("DBCrypto failed with message: " << e.GetMessage());
829 retCode = CKM_API_ERROR_DB_ERROR;
831 LogError("Unknown error.");
834 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS),
838 return response.Pop();
841 RawBuffer CKMLogic::createSignature(
842 const Credentials &cred,
844 const Name &privateKeyName,
845 const Label & ownerLabel,
846 const Password &password, // password for private_key
847 const RawBuffer &message,
848 const HashAlgorithm hash,
849 const RSAPaddingAlgorithm padding)
855 int retCode = CKM_API_SUCCESS;
858 retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
859 if(retCode == CKM_API_SUCCESS)
861 KeyImpl keyParsed(row.data, Password());
862 if (keyParsed.empty())
863 retCode = CKM_API_ERROR_SERVER_ERROR;
865 retCode = cs.createSignature(keyParsed, message, hash, padding, signature);
867 } catch (const KeyProvider::Exception::Base &e) {
868 LogError("KeyProvider failed with message: " << e.GetMessage());
869 retCode = CKM_API_ERROR_SERVER_ERROR;
870 } catch (const CryptoLogic::Exception::Base &e) {
871 LogError("CryptoLogic failed with message: " << e.GetMessage());
872 retCode = CKM_API_ERROR_SERVER_ERROR;
873 } catch (const DBCrypto::Exception::Base &e) {
874 LogError("DBCrypto failed with message: " << e.GetMessage());
875 retCode = CKM_API_ERROR_DB_ERROR;
876 } catch (const CKM::Exception &e) {
877 LogError("Unknown CKM::Exception: " << e.GetMessage());
878 retCode = CKM_API_ERROR_SERVER_ERROR;
881 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
885 return response.Pop();
888 RawBuffer CKMLogic::verifySignature(
889 const Credentials &cred,
891 const Name &publicKeyOrCertName,
892 const Label & ownerLabel,
893 const Password &password, // password for public_key (optional)
894 const RawBuffer &message,
895 const RawBuffer &signature,
896 const HashAlgorithm hash,
897 const RSAPaddingAlgorithm padding)
899 int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
907 retCode = readDataHelper(false, cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
909 if (retCode == CKM_API_SUCCESS) {
910 key = KeyImpl(row.data);
911 } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
912 retCode = readDataHelper(false, cred, DBDataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
913 if (retCode != CKM_API_SUCCESS)
915 CertificateImpl cert(row.data, DataFormat::FORM_DER);
916 key = cert.getKeyImpl();
922 retCode = CKM_API_ERROR_SERVER_ERROR;
926 retCode = cs.verifySignature(key, message, signature, hash, padding);
928 } catch (const CryptoService::Exception::Crypto_internal &e) {
929 LogError("KeyProvider failed with message: " << e.GetMessage());
930 retCode = CKM_API_ERROR_SERVER_ERROR;
931 } catch (const CryptoService::Exception::opensslError &e) {
932 LogError("KeyProvider failed with message: " << e.GetMessage());
933 retCode = CKM_API_ERROR_SERVER_ERROR;
934 } catch (const KeyProvider::Exception::Base &e) {
935 LogError("KeyProvider failed with error: " << e.GetMessage());
936 retCode = CKM_API_ERROR_SERVER_ERROR;
937 } catch (const CryptoLogic::Exception::Base &e) {
938 LogError("CryptoLogic failed with message: " << e.GetMessage());
939 retCode = CKM_API_ERROR_SERVER_ERROR;
940 } catch (const DBCrypto::Exception::Base &e) {
941 LogError("DBCrypto failed with message: " << e.GetMessage());
942 retCode = CKM_API_ERROR_DB_ERROR;
943 } catch (const CKM::Exception &e) {
944 LogError("Unknown CKM::Exception: " << e.GetMessage());
945 retCode = CKM_API_ERROR_SERVER_ERROR;
948 auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
951 return response.Pop();
954 int CKMLogic::setPermissionHelper(
955 const Credentials &cred,
958 const Label &accessorLabel,
959 const Permission reqRights)
961 if (0 == m_userDataMap.count(cred.uid))
962 return CKM_API_ERROR_DB_LOCKED;
964 if(cred.smackLabel.empty() || cred.smackLabel==accessorLabel)
965 return CKM_API_ERROR_INPUT_PARAM;
967 // use client label if not explicitly provided
968 const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
970 // verify name and label are correct
971 if (!isNameValid(name) || !isLabelValid(ownerLabel))
972 return CKM_API_ERROR_INPUT_PARAM;
974 int access_ec = m_accessControl.canModify(ownerLabel, cred.smackLabel);
975 if(access_ec != CKM_API_SUCCESS)
978 auto &database = m_userDataMap[cred.uid].database;
979 DBCrypto::Transaction transaction(&database);
981 if( ! database.isNameLabelPresent(name, ownerLabel) )
982 return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
984 // removing non-existing permissions: fail
985 if(reqRights == Permission::NONE)
987 if( !database.getPermissionRow(name, ownerLabel, accessorLabel) )
988 return CKM_API_ERROR_INPUT_PARAM;
991 int retCode = database.setPermission(name,
996 transaction.commit();
1001 RawBuffer CKMLogic::setPermission(
1002 const Credentials &cred,
1007 const Label &accessorLabel,
1008 const Permission reqRights)
1012 retCode = setPermissionHelper(cred, name, label, accessorLabel, reqRights);
1013 } Catch (CKM::Exception) {
1014 LogError("Error in set row!");
1015 retCode = CKM_API_ERROR_DB_ERROR;
1018 return MessageBuffer::Serialize(command, msgID, retCode).Pop();