+RawBuffer CKMLogic::createSignature(
+ const Credentials &cred,
+ int commandId,
+ const Name &privateKeyName,
+ const Label & ownerLabel,
+ const Password &password, // password for private_key
+ const RawBuffer &message,
+ const HashAlgorithm hash,
+ const RSAPaddingAlgorithm padding)
+{
+ DB::Row row;
+ RawBuffer signature;
+ CryptoAlgorithm cryptoAlg;
+ cryptoAlg.setParam(ParamName::SV_HASH_ALGO, hash);
+ cryptoAlg.setParam(ParamName::SV_RSA_PADDING, padding);
+
+ int retCode = CKM_API_SUCCESS;
+
+ try {
+ retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row);
+ if(retCode == CKM_API_SUCCESS) {
+ signature = m_decider.getStore(row).getKey(row)->sign(cryptoAlg, message);
+ }
+ } catch (const DB::Crypto::Exception::Base &e) {
+ LogError("DB::Crypto failed with message: " << e.GetMessage());
+ retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const Exc::Exception &e) {
+ retCode = e.error();
+ } catch (const CKM::Exception &e) {
+ LogError("Unknown CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
+ }
+
+ auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE),
+ commandId,
+ retCode,
+ signature);
+ return response.Pop();
+}
+
+RawBuffer CKMLogic::verifySignature(
+ const Credentials &cred,
+ int commandId,
+ const Name &publicKeyOrCertName,
+ const Label & ownerLabel,
+ const Password &password, // password for public_key (optional)
+ const RawBuffer &message,
+ const RawBuffer &signature,
+ const HashAlgorithm hash,
+ const RSAPaddingAlgorithm padding)
+{
+ int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
+
+ try {
+ DB::Row row;
+
+ CryptoAlgorithm params;
+ params.setParam(ParamName::SV_HASH_ALGO, hash);
+ params.setParam(ParamName::SV_RSA_PADDING, padding);
+
+ // try certificate first - looking for a public key.
+ // in case of PKCS, pub key from certificate will be found first
+ // rather than private key from the same PKCS.
+ retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row);
+ if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
+ retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row);
+ }
+
+ if (retCode == CKM_API_SUCCESS) {
+ retCode = m_decider.getStore(row).getKey(row)->verify(params, message, signature);
+ }
+ } catch (const Exc::Exception &e) {
+ retCode = e.error();
+ } catch (const DB::Crypto::Exception::Base &e) {
+ LogError("DB::Crypto failed with message: " << e.GetMessage());
+ retCode = CKM_API_ERROR_DB_ERROR;
+ } catch (const CKM::Exception &e) {
+ LogError("Unknown CKM::Exception: " << e.GetMessage());
+ retCode = CKM_API_ERROR_SERVER_ERROR;
+ }
+
+ auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE),
+ commandId,
+ retCode);
+ return response.Pop();
+}
+
+int CKMLogic::setPermissionHelper(
+ const Credentials &cred, // who's the client
+ const Name &name,
+ const Label &label, // who's the owner
+ const Label &accessorLabel, // who will get the access
+ const PermissionMask permissionMask)
+{
+ auto &handler = selectDatabase(cred, label);
+
+ // we don't know the client
+ if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel))
+ return CKM_API_ERROR_INPUT_PARAM;
+
+ // use client label if not explicitly provided
+ const Label& ownerLabel = label.empty() ? cred.smackLabel : label;
+
+ // verify name and label are correct
+ if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel))
+ return CKM_API_ERROR_INPUT_PARAM;
+
+ // currently we don't support modification of owner's permissions to his own rows
+ if (ownerLabel==accessorLabel)
+ return CKM_API_ERROR_INPUT_PARAM;
+
+ // system database does not support write/remove permissions
+ if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
+ (permissionMask & Permission::REMOVE))
+ return CKM_API_ERROR_INPUT_PARAM;
+
+ // can the client modify permissions to owner's row?
+ int retCode = m_accessControl.canModify(cred, ownerLabel);
+ if(retCode != CKM_API_SUCCESS)
+ return retCode;
+
+ DB::Crypto::Transaction transaction(&handler.database);
+
+ if( !handler.database.isNameLabelPresent(name, ownerLabel) )
+ return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+
+ // removing non-existing permissions: fail
+ if(permissionMask == Permission::NONE)
+ {
+ if(!handler.database.getPermissionRow(name, ownerLabel, accessorLabel))
+ return CKM_API_ERROR_INPUT_PARAM;
+ }
+
+ // set permissions to the row owned by ownerLabel for accessorLabel
+ handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask);
+ transaction.commit();
+
+ return CKM_API_SUCCESS;
+}
+
+RawBuffer CKMLogic::setPermission(
+ const Credentials &cred,
+ const int command,
+ const int msgID,
+ const Name &name,
+ const Label &label,
+ const Label &accessorLabel,
+ const PermissionMask permissionMask)
+{
+ int retCode;
+ Try {
+ retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask);
+ } catch (const Exc::Exception &e) {
+ retCode = e.error();
+ } Catch (CKM::Exception) {
+ LogError("Error in set row!");
+ retCode = CKM_API_ERROR_DB_ERROR;
+ }
+
+ return MessageBuffer::Serialize(command, msgID, retCode).Pop();
+}
+