mirror of
https://gitee.com/openharmony/filemanagement_storage_service
synced 2025-02-17 05:20:39 +00:00
!16 fscrypt:add keymanager implementation and setting user directory fscrypt policy
Merge pull request !16 from qilongzhang/fscrypt_for_merge
This commit is contained in:
commit
e44131a8fc
@ -79,6 +79,7 @@ ohos_executable("sdc") {
|
||||
sources = [
|
||||
"ipc/src/storage_daemon_proxy.cpp",
|
||||
"client/storage_daemon_client.cpp",
|
||||
"utils/file_utils.cpp",
|
||||
"sdc.cpp"
|
||||
]
|
||||
|
||||
|
@ -35,6 +35,8 @@ public:
|
||||
static int32_t DestroyUserDirs(int32_t userId, u_int32_t flags);
|
||||
static int32_t InitGlobalKey(void);
|
||||
static int32_t InitGlobalUserKeys(void);
|
||||
static int32_t GenerateUserKeys(uint32_t userId, uint32_t flags);
|
||||
static int32_t DeleteUserKeys(uint32_t userId);
|
||||
|
||||
private:
|
||||
static sptr<IStorageDaemon> GetStorageDaemonProxy(void);
|
||||
|
@ -106,5 +106,26 @@ int32_t StorageDaemonClient::InitGlobalUserKeys(void)
|
||||
return client->InitGlobalUserKeys();
|
||||
}
|
||||
|
||||
int32_t StorageDaemonClient::GenerateUserKeys(uint32_t userId, uint32_t flags)
|
||||
{
|
||||
sptr<IStorageDaemon> client = GetStorageDaemonProxy();
|
||||
if (client == nullptr) {
|
||||
LOGE("get storage daemon service failed");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return client->GenerateUserKeys(userId, flags);
|
||||
}
|
||||
|
||||
int32_t StorageDaemonClient::DeleteUserKeys(uint32_t userId)
|
||||
{
|
||||
sptr<IStorageDaemon> client = GetStorageDaemonProxy();
|
||||
if (client == nullptr) {
|
||||
LOGE("get storage daemon service failed");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return client->DeleteUserKeys(userId);
|
||||
}
|
||||
}
|
||||
}
|
@ -385,6 +385,7 @@ bool BaseKey::ClearKey(const std::string& mnt)
|
||||
if (arg.removal_status_flags & FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS) {
|
||||
LOGE("Other users still have this key added");
|
||||
} else if (arg.removal_status_flags & FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY) {
|
||||
// is the key fully removed?
|
||||
LOGE("Some files using this key are still in-use");
|
||||
} else {
|
||||
LOGD("RemoveKey success");
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include <linux/keyctl.h>
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "securec.h"
|
||||
#include "file_ex.h"
|
||||
#include "string_ex.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
@ -128,5 +131,39 @@ bool KeyCtrl::GetPolicy(const std::string &path, fscrypt_get_policy_ex_arg &poli
|
||||
return FsIoctl(path, FS_IOC_GET_ENCRYPTION_POLICY_EX, reinterpret_cast<void *>(&policy));
|
||||
}
|
||||
|
||||
static bool ParseOption(const std::map<std::string, uint8_t> &policy, const std::string &defaultStr, uint8_t &value)
|
||||
{
|
||||
if (policy.find(defaultStr) != policy.end()) {
|
||||
LOGI("use default: %{public}s", defaultStr.c_str());
|
||||
value = policy.at(defaultStr);
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGE("bad default policy: %{public}s, value not filled!", defaultStr.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KeyCtrl::LoadAndSetPolicy(const std::string &keyIdPath, const std::string &policyFile, const std::string &toEncrypt)
|
||||
{
|
||||
LOGD("enter");
|
||||
std::string keyId;
|
||||
if (OHOS::LoadStringFromFile(keyIdPath, keyId) == false || keyId.length() != FSCRYPT_KEY_IDENTIFIER_SIZE) {
|
||||
LOGE("bad kid file content, length=%{public}d", keyId.length());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add parsing options from the policy file, now using default.
|
||||
(void)policyFile;
|
||||
|
||||
struct fscrypt_policy_v2 arg = {.version = FSCRYPT_POLICY_V2};
|
||||
(void)memcpy_s(arg.master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE, keyId.data(), keyId.length());
|
||||
if (!ParseOption(FILENAME_MODES, DEFAULT_POLICY.fileName, arg.filenames_encryption_mode) ||
|
||||
!ParseOption(CONTENTS_MODES, DEFAULT_POLICY.content, arg.contents_encryption_mode) ||
|
||||
!ParseOption(POLICY_FLAGS, DEFAULT_POLICY.flags, arg.flags)) {
|
||||
LOGE("parse option failed");
|
||||
return false;
|
||||
}
|
||||
return KeyCtrl::SetPolicy(toEncrypt, arg);
|
||||
}
|
||||
} // namespace StorageDaemon
|
||||
} // namespace OHOS
|
||||
|
@ -18,98 +18,495 @@
|
||||
|
||||
#include "directory_ex.h"
|
||||
#include "file_ex.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "utils/errno.h"
|
||||
#include "key_ctrl.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
const UserAuth NULL_KEY_AUTH = {
|
||||
.token = ""
|
||||
};
|
||||
const std::string DATA_EL0_DIR = std::string() + "/data/service/el0";
|
||||
const std::string STORAGE_DAEMON_DIR = DATA_EL0_DIR + "/storage_daemon";
|
||||
const std::string DEVICE_EL1_DIR = STORAGE_DAEMON_DIR + "/sd";
|
||||
|
||||
int KeyManager::GenerateDeviceKey(const std::string &dir)
|
||||
const std::string FSCRYPT_USER_EL1_PUBLIC = std::string() + "/data/service/el1/public";
|
||||
const std::string SERVICE_STORAGE_DAEMON_DIR = FSCRYPT_USER_EL1_PUBLIC + "/storage_daemon";
|
||||
const std::string FSCRYPT_EL_DIR = SERVICE_STORAGE_DAEMON_DIR + "/sd";
|
||||
const std::string USER_EL1_DIR = FSCRYPT_EL_DIR + "/el1";
|
||||
const std::string USER_EL2_DIR = FSCRYPT_EL_DIR + "/el2";
|
||||
|
||||
int KeyManager::GenerateAndInstallDeviceKey(const std::string &dir)
|
||||
{
|
||||
globalEl1Key_ = std::make_unique<BaseKey>(dir);
|
||||
LOGI("enter");
|
||||
globalEl1Key_ = std::make_shared<BaseKey>(dir);
|
||||
if (globalEl1Key_ == nullptr) {
|
||||
LOGE("No memory for device el1 key");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (globalEl1Key_->InitKey() == false) {
|
||||
globalEl1Key_ = nullptr;
|
||||
LOGE("global security key init failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (globalEl1Key_->StoreKey(NULL_KEY_AUTH) == false) {
|
||||
globalEl1Key_->ClearKey();
|
||||
globalEl1Key_ = nullptr;
|
||||
LOGE("global security key store failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (globalEl1Key_->ActiveKey() == false) {
|
||||
// should clear saved file ?
|
||||
globalEl1Key_->ClearKey();
|
||||
globalEl1Key_ = nullptr;
|
||||
LOGE("global security key active failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
hasGlobalDeviceKey_ = true;
|
||||
LOGI("key create success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::RestoreDeviceKey(const std::string &dir)
|
||||
{
|
||||
LOGI("enter");
|
||||
if (globalEl1Key_ != nullptr) {
|
||||
LOGD("device key has existed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
globalEl1Key_ = std::make_shared<BaseKey>(dir);
|
||||
if (globalEl1Key_ == nullptr) {
|
||||
LOGE("No memory for device el1 key");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (globalEl1Key_->InitKey() == false) {
|
||||
globalEl1Key_ = nullptr;
|
||||
LOGE("global security key init failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (globalEl1Key_->RestoreKey(NULL_KEY_AUTH) == false) {
|
||||
globalEl1Key_->ClearKey();
|
||||
globalEl1Key_ = nullptr;
|
||||
LOGE("global security key store failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (globalEl1Key_->ActiveKey() == false) {
|
||||
globalEl1Key_->ClearKey();
|
||||
globalEl1Key_ = nullptr;
|
||||
LOGE("global security key active failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
hasGlobalDeviceKey_ = true;
|
||||
LOGI("key restore success");
|
||||
|
||||
// GetFileEncryptPattern
|
||||
// SaveFileEncryptPatternToFile
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::InitGlobalDeviceKey(void)
|
||||
{
|
||||
LOGD("InitGlobalDeviceKey::start");
|
||||
LOGI("enter");
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
if (hasGlobalDeviceKey_ || globalEl1Key_ != nullptr) {
|
||||
LOGD("glabal device el1 have existed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = MkDir(STORAGE_DAEMON_DIR, 0700);
|
||||
if (ret && errno != EEXIST) {
|
||||
LOGE("create storage daemon dir error");
|
||||
return ret;
|
||||
}
|
||||
ret = MkDir(DEVICE_EL1_DIR, 0700);
|
||||
if (ret) {
|
||||
if (errno != EEXIST) {
|
||||
LOGE("make device el1 dir error");
|
||||
return ret;
|
||||
}
|
||||
return RestoreDeviceKey(DEVICE_EL1_DIR);
|
||||
}
|
||||
|
||||
return GenerateAndInstallDeviceKey(DEVICE_EL1_DIR);
|
||||
}
|
||||
|
||||
int KeyManager::GenerateAndInstallUserKey(uint32_t userId, const std::string &dir, const UserAuth &auth, KeyType type)
|
||||
{
|
||||
LOGI("enter");
|
||||
if (HasElkey(userId, type)) {
|
||||
LOGD("The user %{public}u el %{public}u have existed", userId, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseKey> elKey = std::make_shared<BaseKey>(dir);
|
||||
if (elKey == nullptr) {
|
||||
LOGE("No memory for device el1 key");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (elKey->InitKey() == false) {
|
||||
LOGE("global security key init failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (elKey->StoreKey(auth) == false) {
|
||||
elKey->ClearKey();
|
||||
LOGE("global security key store failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (elKey->ActiveKey() == false) {
|
||||
elKey->ClearKey();
|
||||
LOGE("global security key active failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (type == EL1_KEY) {
|
||||
userEl1Key_[userId] = elKey;
|
||||
} else if (type == EL2_KEY) {
|
||||
userEl2Key_[userId] = elKey;
|
||||
}
|
||||
LOGI("key create success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::RestoreUserKey(uint32_t userId, const std::string &dir, const UserAuth &auth, KeyType type)
|
||||
{
|
||||
LOGI("enter");
|
||||
if (HasElkey(userId, type)) {
|
||||
LOGD("The user %{public}u el %{public}u have existed", userId, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseKey> elKey = std::make_shared<BaseKey>(dir);
|
||||
if (elKey == nullptr) {
|
||||
LOGE("No memory for device el1 key");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (elKey->InitKey() == false) {
|
||||
LOGE("global security key init failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (elKey->RestoreKey(auth) == false) {
|
||||
elKey->ClearKey();
|
||||
LOGE("global security key store failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (elKey->ActiveKey() == false) {
|
||||
elKey->ClearKey();
|
||||
LOGE("global security key active failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (type == EL1_KEY) {
|
||||
userEl1Key_[userId] = elKey;
|
||||
} else if (type == EL2_KEY) {
|
||||
userEl2Key_[userId] = elKey;
|
||||
}
|
||||
LOGI("key restore success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool KeyManager::HasElkey(uint32_t userId, KeyType type)
|
||||
{
|
||||
LOGI("enter");
|
||||
if (type == EL1_KEY) {
|
||||
if (userEl1Key_.find(userId) != userEl1Key_.end()) {
|
||||
LOGD("user el1 key has existed");
|
||||
return true;
|
||||
}
|
||||
} else if (type == EL2_KEY) {
|
||||
if (userEl2Key_.find(userId) != userEl2Key_.end()) {
|
||||
LOGD("user el2 key has existed");
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
LOGE("key type error");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int KeyManager::LoadAllUsersEl1Key(void)
|
||||
{
|
||||
LOGI("enter");
|
||||
std::vector<FileList> dirInfo;
|
||||
ReadDigitDir(USER_EL1_DIR, dirInfo);
|
||||
for (auto item : dirInfo) {
|
||||
if (RestoreUserKey(item.userId, item.path, NULL_KEY_AUTH, EL1_KEY) != 0) {
|
||||
LOGE("user %{public}u el1 key restore error", item.userId);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::InitUserElkeyStorageDir(void)
|
||||
{
|
||||
int ret = MkDir(SERVICE_STORAGE_DAEMON_DIR, 0700);
|
||||
if (ret && errno != EEXIST) {
|
||||
LOGE("make service storage daemon dir error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = MkDir(FSCRYPT_EL_DIR, 0700);
|
||||
if (ret && errno != EEXIST) {
|
||||
LOGE("make service storage daemon dir error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = MkDir(USER_EL1_DIR, 0700);
|
||||
if (ret && errno != EEXIST) {
|
||||
LOGE("make el1 storage dir error");
|
||||
return ret;
|
||||
}
|
||||
ret = MkDir(USER_EL2_DIR, 0700);
|
||||
if (ret && errno != EEXIST) {
|
||||
LOGE("make el2 storage dir error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::InitGlobalUserKeys(void)
|
||||
{
|
||||
LOGD("InitGlobalUserKeys start");
|
||||
LOGI("enter");
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
int ret = InitUserElkeyStorageDir();
|
||||
if (ret) {
|
||||
LOGE("Init user el storage dir failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string globalUserEl1Path = USER_EL1_DIR + "/" + std::to_string(GLOBAL_USER_ID);
|
||||
if (IsDir(globalUserEl1Path)) {
|
||||
ret = RestoreUserKey(GLOBAL_USER_ID, globalUserEl1Path, NULL_KEY_AUTH, EL1_KEY);
|
||||
if (ret != 0) {
|
||||
LOGE("Restore el1 failed");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = GenerateAndInstallUserKey(GLOBAL_USER_ID, globalUserEl1Path, NULL_KEY_AUTH, EL1_KEY);
|
||||
if (ret != 0) {
|
||||
LOGE("Generate el1 failed");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
std::string globalUserEl2Path = USER_EL2_DIR + "/" + std::to_string(GLOBAL_USER_ID);
|
||||
if (!IsDir(globalUserEl2Path)) {
|
||||
ret = GenerateAndInstallUserKey(GLOBAL_USER_ID, globalUserEl2Path, NULL_KEY_AUTH, EL2_KEY);
|
||||
if (ret != 0) {
|
||||
DoDeleteUserKeys(GLOBAL_USER_ID);
|
||||
LOGE("Generate el2 failed");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = LoadAllUsersEl1Key();
|
||||
if (ret) {
|
||||
LOGE("Load all users el1 failed");
|
||||
return ret;
|
||||
}
|
||||
LOGI("Init global user key success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::CreateUserKeys(unsigned int user, bool isSave)
|
||||
int KeyManager::GenerateUserKeys(unsigned int user, uint32_t flags)
|
||||
{
|
||||
LOGD("start, user:%{public}d", user);
|
||||
LOGI("start, user:%{public}u", user);
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
if ((!IsDir(USER_EL1_DIR)) || (!IsDir(USER_EL2_DIR))) {
|
||||
LOGD("El storage dir is not existed, fbe may not be enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string el1Path = USER_EL1_DIR + "/" + std::to_string(user);
|
||||
std::string el2Path = USER_EL2_DIR + "/" + std::to_string(user);
|
||||
if (IsDir(el1Path) || IsDir(el2Path)) {
|
||||
LOGE("user %{public}d el key have existed, create error", user);
|
||||
return -EEXIST;
|
||||
}
|
||||
int ret = GenerateAndInstallUserKey(user, el1Path, NULL_KEY_AUTH, EL1_KEY);
|
||||
if (ret) {
|
||||
LOGE("user el1 create error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = GenerateAndInstallUserKey(user, el2Path, NULL_KEY_AUTH, EL2_KEY);
|
||||
if (ret) {
|
||||
DoDeleteUserKeys(user);
|
||||
LOGE("user el2 create error");
|
||||
return ret;
|
||||
}
|
||||
LOGI("Create user el success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KeyManager::DoDeleteUserKeys(unsigned int user)
|
||||
{
|
||||
auto it = userEl1Key_.find(user);
|
||||
if (it != userEl1Key_.end()) {
|
||||
auto elKey = it->second;
|
||||
elKey->ClearKey();
|
||||
std::string path = elKey->GetDir();
|
||||
RmDirRecurse(path);
|
||||
userEl1Key_.erase(user);
|
||||
}
|
||||
|
||||
it = userEl2Key_.find(user);
|
||||
if (it != userEl2Key_.end()) {
|
||||
auto elKey = it->second;
|
||||
elKey->ClearKey();
|
||||
std::string path = elKey->GetDir();
|
||||
RmDirRecurse(path);
|
||||
userEl2Key_.erase(user);
|
||||
}
|
||||
}
|
||||
|
||||
int KeyManager::DeleteUserKeys(unsigned int user)
|
||||
{
|
||||
LOGD("start, user:%{public}d", user);
|
||||
LOGI("start, user:%{public}d", user);
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
DoDeleteUserKeys(user);
|
||||
LOGI("delete user key success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::UpdateUserAuth(unsigned int user, const std::string &token)
|
||||
int KeyManager::UpdateUserAuth(unsigned int user, const std::string &token,
|
||||
const std::string &composePwd)
|
||||
{
|
||||
LOGD("start, user:%{public}d", user);
|
||||
LOGI("start, user:%{public}d", user);
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
if (userEl2Key_.find(user) == userEl2Key_.end()) {
|
||||
LOGE("Have not found user %{public}u el2 key", user);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
auto item = userEl2Key_[user];
|
||||
UserAuth auth = {
|
||||
.token = token,
|
||||
};
|
||||
if (item->RestoreKey(auth) == false) {
|
||||
LOGE("Restoore key error");
|
||||
return -EFAULT;
|
||||
}
|
||||
if (item->StoreKey(auth) == false) {
|
||||
LOGE("Store key error");
|
||||
return -EFAULT;
|
||||
}
|
||||
item->keyInfo_.key.Clear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::ActiveUserKey(unsigned int user)
|
||||
int KeyManager::ActiveUserKey(unsigned int user, const std::string &token,
|
||||
const std::string &secret)
|
||||
{
|
||||
LOGD("start");
|
||||
LOGI("start");
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
if (userEl2Key_.find(user) != userEl2Key_.end()) {
|
||||
LOGE("The user %{public}u el2 have been actived", user);
|
||||
return 0;
|
||||
}
|
||||
std::string keyDir = USER_EL2_DIR + "/" + std::to_string(user);
|
||||
if (!IsDir(keyDir)) {
|
||||
LOGE("Have not found user %{public}u el2", user);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseKey> elKey = std::make_shared<BaseKey>(keyDir);
|
||||
if (elKey->InitKey() == false) {
|
||||
LOGE("Init el failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
UserAuth auth = {
|
||||
.token = token
|
||||
};
|
||||
if (elKey->RestoreKey(auth) == false) {
|
||||
LOGE("Restore el failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
if (elKey->ActiveKey() == false) {
|
||||
LOGE("Active user %{public}u key failed", user);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
userEl2Key_[user] = elKey;
|
||||
LOGI("Active user %{public}u el2 success", user);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::InActiveUserKey(unsigned int user)
|
||||
int KeyManager::InActiveUserKey(unsigned int user, KeyType type)
|
||||
{
|
||||
LOGD("start");
|
||||
LOGI("start");
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
if (userEl2Key_.find(user) == userEl2Key_.end()) {
|
||||
LOGE("Have not found user %{public}u el2", user);
|
||||
return -ENOENT;
|
||||
}
|
||||
auto elKey = userEl2Key_[user];
|
||||
if (elKey->ClearKey() == false) {
|
||||
LOGE("Clear user %{public}u key failed", user);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
userEl2Key_.erase(user);
|
||||
LOGI("Inactive user %{public}u el2 success", user);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::UpdateKeyContext(unsigned int user)
|
||||
int KeyManager::SetDirectoryElPolicy(unsigned int user, KeyType type,
|
||||
const std::vector<FileList> &vec)
|
||||
{
|
||||
LOGD("start");
|
||||
return 0;
|
||||
}
|
||||
LOGI("start");
|
||||
std::string kidPath;
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
if (type == EL1_KEY) {
|
||||
if (userEl1Key_.find(user) == userEl1Key_.end()) {
|
||||
LOGE("Have not found user %{public}u el1 key", user);
|
||||
return -EINVAL;
|
||||
}
|
||||
kidPath = userEl1Key_[user]->GetKeyIdPath();
|
||||
} else if (type == EL2_KEY) {
|
||||
if (userEl2Key_.find(user) == userEl2Key_.end()) {
|
||||
LOGE("Have not found user %{public}u el2 key", user);
|
||||
return -EINVAL;
|
||||
}
|
||||
kidPath = userEl2Key_[user]->GetKeyIdPath();
|
||||
} else {
|
||||
LOGD("Not specify el flags, no need to crypt");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KeyManager::PrepareUserSpace(unsigned int user)
|
||||
{
|
||||
LOGD("start");
|
||||
return 0;
|
||||
}
|
||||
std::string policy = "";
|
||||
for (auto item : vec) {
|
||||
if(KeyCtrl::LoadAndSetPolicy(kidPath, policy, item.path) == false) {
|
||||
LOGE("Set directory el policy error!");
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
LOGI("Set user %{public}u el policy success", user);
|
||||
|
||||
std::string KeyManager::GetKeyDesc(unsigned int user)
|
||||
{
|
||||
LOGD("start");
|
||||
return "";
|
||||
return 0;
|
||||
}
|
||||
} // namespace StorageDaemon
|
||||
} // namespace OHOS
|
||||
|
@ -14,7 +14,6 @@
|
||||
*/
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "base_key.h"
|
||||
@ -38,9 +37,11 @@ std::string toEncryptMnt("/data");
|
||||
std::string toEncryptDirLegacy("/data/test/crypto_dir_legacy");
|
||||
std::string toEncryptDir("/data/test/crypto_dir");
|
||||
std::string testKeyPath("/data/test/sys_de");
|
||||
std::string policyPath("/data/test/policy");
|
||||
OHOS::StorageDaemon::BaseKey deKey {testKeyPath};
|
||||
void CryptoKeyTest::SetUpTestCase(void)
|
||||
{
|
||||
OHOS::RemoveFile(policyPath);
|
||||
// input testsuit setup step,setup invoked before all testcases
|
||||
}
|
||||
|
||||
@ -180,7 +181,6 @@ HWTEST_F(CryptoKeyTest, basekey_fscrypt_v1_policy_set, TestSize.Level1)
|
||||
EXPECT_EQ(true, OHOS::ForceCreateDirectory(toEncryptDirLegacy + "/test_dir"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDirLegacy + "/test_file1", "hello, world!\n"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDirLegacy + "/test_file2", "AA"));
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,7 +264,6 @@ HWTEST_F(CryptoKeyTest, basekey_fscrypt_v2_policy_set, TestSize.Level1)
|
||||
EXPECT_EQ(true, OHOS::ForceCreateDirectory(toEncryptDir + "/test_dir"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/test_file1", "hello, world!\n"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/test_file2", "AA"));
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -296,6 +295,7 @@ HWTEST_F(CryptoKeyTest, basekey_fscrypt_v2_policy_get, TestSize.Level1)
|
||||
HWTEST_F(CryptoKeyTest, basekey_fscrypt_v2_policy_clear, TestSize.Level1)
|
||||
{
|
||||
EXPECT_EQ(true, deKey.ClearKey(toEncryptMnt));
|
||||
// When the v2 policy removed, the files are encrypted.
|
||||
EXPECT_EQ(false, OHOS::FileExists(toEncryptDir + "/test_dir"));
|
||||
EXPECT_EQ(false, OHOS::FileExists(toEncryptDir + "/test_file1"));
|
||||
EXPECT_EQ(false, OHOS::FileExists(toEncryptDir + "/test_file2"));
|
||||
@ -328,3 +328,55 @@ HWTEST_F(CryptoKeyTest, basekey_fscrypt_v2_policy_restore, TestSize.Level1)
|
||||
EXPECT_EQ(true, deKey.ClearKey(toEncryptMnt));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: basekey_fscrypt_v2_load_and_set_policy_default
|
||||
* @tc.desc: Verify the KeyCtrl::LoadAndSetPolicy function.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000GK0BP
|
||||
*/
|
||||
HWTEST_F(CryptoKeyTest, basekey_fscrypt_v2_load_and_set_policy_default, TestSize.Level1)
|
||||
{
|
||||
EXPECT_EQ(true, deKey.InitKey());
|
||||
// the ext4 disk with `mke2fs -O encrypt` mounted for test
|
||||
EXPECT_EQ(true, deKey.StoreKey(emptyUserAuth));
|
||||
EXPECT_EQ(true, deKey.ActiveKey(toEncryptMnt));
|
||||
|
||||
OHOS::ForceRemoveDirectory(toEncryptDir);
|
||||
OHOS::ForceCreateDirectory(toEncryptDir);
|
||||
OHOS::ForceRemoveDirectory(policyPath);
|
||||
EXPECT_EQ(true, OHOS::StorageDaemon::KeyCtrl::LoadAndSetPolicy(testKeyPath + "/kid", policyPath, toEncryptDir));
|
||||
|
||||
EXPECT_EQ(true, OHOS::ForceCreateDirectory(toEncryptDir + "/test_dir"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/test_file1", "hello, world!\n"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/test_file2", "AA"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/1111111111111111111111111111111111111111111111111", "AA"));
|
||||
|
||||
EXPECT_EQ(true, deKey.ClearKey(toEncryptMnt));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: basekey_fscrypt_v2_load_and_set_policy_from_file
|
||||
* @tc.desc: Verify the fscrypt V2 setpolicy function.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: AR000GK0BP
|
||||
*/
|
||||
HWTEST_F(CryptoKeyTest, basekey_fscrypt_v2_load_and_set_policy_from_file, TestSize.Level1)
|
||||
{
|
||||
EXPECT_EQ(true, deKey.InitKey());
|
||||
// the ext4 disk with `mke2fs -O encrypt` mounted for test
|
||||
EXPECT_EQ(true, deKey.StoreKey(emptyUserAuth));
|
||||
EXPECT_EQ(true, deKey.ActiveKey(toEncryptMnt));
|
||||
|
||||
OHOS::ForceRemoveDirectory(toEncryptDir);
|
||||
OHOS::ForceCreateDirectory(toEncryptDir);
|
||||
// the `aes-128-cts/aes-128-cbc` need the CONFIG_CRYPTO_ESSIV, and the policy from file not finished yet
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(policyPath, "v2;aes-256-cts;aes-256-xts;padding-8"));
|
||||
EXPECT_EQ(true, OHOS::StorageDaemon::KeyCtrl::LoadAndSetPolicy(testKeyPath + "/kid", policyPath, toEncryptDir));
|
||||
|
||||
EXPECT_EQ(true, OHOS::ForceCreateDirectory(toEncryptDir + "/test_dir"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/test_file1", "hello, world!\n"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/test_file2", "AA"));
|
||||
EXPECT_EQ(true, OHOS::SaveStringToFile(toEncryptDir + "/1111111111111111111111111111111111111111111111111", "AA"));
|
||||
|
||||
EXPECT_EQ(true, deKey.ClearKey(toEncryptMnt));
|
||||
}
|
||||
|
@ -37,6 +37,14 @@ public:
|
||||
bool ClearKey(const std::string &mnt = "/data");
|
||||
|
||||
KeyInfo keyInfo_;
|
||||
std::string GetDir() const
|
||||
{
|
||||
return dir_;
|
||||
}
|
||||
std::string GetKeyIdPath() const
|
||||
{
|
||||
return dir_ + "/kid";
|
||||
}
|
||||
|
||||
private:
|
||||
bool DoStoreKey(const UserAuth &auth);
|
||||
|
@ -49,30 +49,45 @@ public:
|
||||
static bool SetPolicy(const std::string &path, fscrypt_policy_v2 &policy);
|
||||
static bool GetPolicy(const std::string &path, fscrypt_get_policy_ex_arg &options);
|
||||
|
||||
static bool LoadAndSetPolicy(const std::string &policy, const std::string &toEncrypt);
|
||||
static bool LoadAndSetPolicy(const std::string &keyIdPath, const std::string &policyFile, const std::string &toEncrypt);
|
||||
};
|
||||
|
||||
struct CryptoOptions {
|
||||
int version { 0 };
|
||||
int contentsMode { 0 };
|
||||
int filenamesMode { 0 };
|
||||
int flags { 0 };
|
||||
bool useHwWrappedKey { false };
|
||||
struct EncryptPolicy {
|
||||
std::string version;
|
||||
std::string fileName;
|
||||
std::string content;
|
||||
std::string flags;
|
||||
bool hwWrappedKey;
|
||||
};
|
||||
|
||||
static const EncryptPolicy DEFAULT_POLICY = {
|
||||
.version = "2",
|
||||
.fileName = "aes-256-cts",
|
||||
.content = "aes-256-xts",
|
||||
.flags = "padding-32",
|
||||
.hwWrappedKey = false,
|
||||
};
|
||||
|
||||
static const auto CONTENTS_MODES = std::map<std::string, uint8_t> {
|
||||
{"aes-256-xts", FSCRYPT_MODE_AES_256_XTS},
|
||||
{"software", FSCRYPT_MODE_AES_256_XTS},
|
||||
{"aes-128-cbc", FSCRYPT_MODE_AES_128_CBC},
|
||||
{"adiantum", FSCRYPT_MODE_ADIANTUM},
|
||||
// {"ice", FSCRYPT_MODE_PRIVATE}
|
||||
};
|
||||
|
||||
static const auto FILENAME_MODES = std::map<std::string, uint8_t> {
|
||||
{"aes-256-cts", FSCRYPT_MODE_AES_256_CTS},
|
||||
// {"aes-256-heh", FSCRYPT_MODE_AES_256_HEH}
|
||||
{"aes-128-cts", FSCRYPT_MODE_AES_128_CTS},
|
||||
{"adiantum", FSCRYPT_MODE_ADIANTUM},
|
||||
};
|
||||
|
||||
static const auto POLICY_FLAGS = std::map<std::string, uint8_t> {
|
||||
{"padding-4", FSCRYPT_POLICY_FLAGS_PAD_4},
|
||||
{"padding-8", FSCRYPT_POLICY_FLAGS_PAD_8},
|
||||
{"padding-16", FSCRYPT_POLICY_FLAGS_PAD_16},
|
||||
{"padding-32", FSCRYPT_POLICY_FLAGS_PAD_32},
|
||||
{"direct-key", FSCRYPT_POLICY_FLAG_DIRECT_KEY}, // use with adiantum
|
||||
};
|
||||
|
||||
} // namespace StorageDaemon
|
||||
} // namespace OHOS
|
||||
|
||||
|
@ -23,9 +23,16 @@
|
||||
|
||||
#include "key_utils.h"
|
||||
#include "base_key.h"
|
||||
#include "utils/file_utils.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
constexpr uint32_t GLOBAL_USER_ID = 0;
|
||||
enum KeyType {
|
||||
EL1_KEY = 1,
|
||||
EL2_KEY = 2,
|
||||
};
|
||||
|
||||
class KeyManager {
|
||||
public:
|
||||
static KeyManager *GetInstance(void)
|
||||
@ -35,14 +42,14 @@ public:
|
||||
}
|
||||
int InitGlobalDeviceKey(void);
|
||||
int InitGlobalUserKeys(void);
|
||||
int CreateUserKeys(unsigned int user, bool isSave);
|
||||
int GenerateUserKeys(unsigned int user, uint32_t flags);
|
||||
int DeleteUserKeys(unsigned int user);
|
||||
int UpdateUserAuth(unsigned int user, const std::string &token);
|
||||
int ActiveUserKey(unsigned int user);
|
||||
int InActiveUserKey(unsigned int user);
|
||||
int UpdateKeyContext(unsigned int user);
|
||||
std::string GetKeyDesc(unsigned int user);
|
||||
int PrepareUserSpace(unsigned int user);
|
||||
int UpdateUserAuth(unsigned int user, const std::string &token, const std::string &composePwd);
|
||||
int ActiveUserKey(unsigned int user, const std::string &token,
|
||||
const std::string &secret);
|
||||
int InActiveUserKey(unsigned int user, KeyType type);
|
||||
int SetDirectoryElPolicy(unsigned int user, KeyType type,
|
||||
const std::vector<FileList> &vec);
|
||||
|
||||
private:
|
||||
KeyManager()
|
||||
@ -50,11 +57,18 @@ private:
|
||||
hasGlobalDeviceKey_ = false;
|
||||
}
|
||||
~KeyManager() {}
|
||||
int GenerateDeviceKey(const std::string &dir);
|
||||
int GenerateAndInstallDeviceKey(const std::string &dir);
|
||||
int RestoreDeviceKey(const std::string &dir);
|
||||
int GenerateAndInstallUserKey(uint32_t userId, const std::string &dir, const UserAuth &auth, KeyType type);
|
||||
int RestoreUserKey(uint32_t userId, const std::string &dir, const UserAuth &auth, KeyType type);
|
||||
int LoadAllUsersEl1Key(void);
|
||||
int InitUserElkeyStorageDir(void);
|
||||
bool HasElkey(uint32_t userId, KeyType type);
|
||||
void DoDeleteUserKeys(unsigned int user);
|
||||
|
||||
std::map<unsigned int, std::unique_ptr<BaseKey>> userEl1Key_;
|
||||
std::map<unsigned int, std::unique_ptr<BaseKey>> userEl2Key_;
|
||||
std::unique_ptr<BaseKey> globalEl1Key_ { nullptr };
|
||||
std::map<unsigned int, std::shared_ptr<BaseKey>> userEl1Key_;
|
||||
std::map<unsigned int, std::shared_ptr<BaseKey>> userEl2Key_;
|
||||
std::shared_ptr<BaseKey> globalEl1Key_ { nullptr };
|
||||
|
||||
std::mutex keyMutex_;
|
||||
bool hasGlobalDeviceKey_;
|
||||
|
@ -87,14 +87,6 @@ struct KeyContext {
|
||||
KeyBlob aad;
|
||||
};
|
||||
|
||||
struct EncryptPolicy {
|
||||
std::string version;
|
||||
std::string fileName;
|
||||
std::string content;
|
||||
int flags;
|
||||
bool hwWrappedKey;
|
||||
};
|
||||
|
||||
struct UserAuth {
|
||||
std::string token;
|
||||
// synthetic
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
STOP_USER,
|
||||
INIT_GLOBAL_KEY,
|
||||
INIT_GLOBAL_USER_KEYS,
|
||||
CREATE_USER_KEYS,
|
||||
DELETE_USER_KEYS,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -59,6 +61,8 @@ public:
|
||||
// fscrypt api
|
||||
virtual int32_t InitGlobalKey(void) = 0;
|
||||
virtual int32_t InitGlobalUserKeys(void) = 0;
|
||||
virtual int32_t GenerateUserKeys(uint32_t userId, uint32_t flags) = 0;
|
||||
virtual int32_t DeleteUserKeys(uint32_t userId) = 0;
|
||||
|
||||
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.StorageDaemon");
|
||||
};
|
||||
|
@ -37,13 +37,14 @@ public:
|
||||
virtual int32_t PrepareUserDirs(int32_t userId, uint32_t flags) override;
|
||||
virtual int32_t DestroyUserDirs(int32_t userId, uint32_t flags) override;
|
||||
|
||||
// fscrypt api
|
||||
// fscrypt api, add fs mutex in KeyManager
|
||||
virtual int32_t InitGlobalKey(void) override;
|
||||
virtual int32_t InitGlobalUserKeys(void) override;
|
||||
virtual int32_t GenerateUserKeys(uint32_t userId, uint32_t flags) override;
|
||||
virtual int32_t DeleteUserKeys(uint32_t userId) override;
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::mutex keyMutex_;
|
||||
};
|
||||
} // StorageDaemon
|
||||
} // OHOS
|
||||
|
@ -39,6 +39,8 @@ public:
|
||||
// fscrypt api
|
||||
virtual int32_t InitGlobalKey(void) override;
|
||||
virtual int32_t InitGlobalUserKeys(void) override;
|
||||
virtual int32_t GenerateUserKeys(uint32_t userId, uint32_t flags) override;
|
||||
virtual int32_t DeleteUserKeys(uint32_t userId) override;
|
||||
|
||||
private:
|
||||
static inline BrokerDelegator<StorageDaemonProxy> delegator_;
|
||||
|
@ -42,6 +42,8 @@ private:
|
||||
// fscrypt api
|
||||
int32_t HandleInitGlobalKey(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleInitGlobalUserKeys(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleGenerateUserKeys(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleDeleteUserKeys(MessageParcel &data, MessageParcel &reply);
|
||||
};
|
||||
} // StorageDaemon
|
||||
} // OHOS
|
||||
|
@ -31,6 +31,7 @@ enum ErrNo {
|
||||
E_DESTROY_DIR = 8, // failed to destroy dir
|
||||
E_MOUNT, // mount error
|
||||
E_UMOUNT, // umount error
|
||||
E_SET_POLICY,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -17,17 +17,29 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
struct FileList {
|
||||
uint32_t userId;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
int32_t MkDir(const std::string &path, mode_t mode);
|
||||
bool IsDir(const std::string &path);
|
||||
bool PrepareDir(const std::string &path, mode_t mode, uid_t uid, gid_t gid);
|
||||
bool DestroyDir(const std::string &path);
|
||||
bool RmDirRecurse(const std::string &path);
|
||||
int32_t Mount(const std::string &source, const std::string &target, const char *type,
|
||||
unsigned long flags, const void *data);
|
||||
int32_t UMount(const std::string &path);
|
||||
void ReadDigitDir(const std::string &path, std::vector<FileList> &dirInfo);
|
||||
bool StringToUint32(const std::string &str, uint32_t &num);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "user/user_manager.h"
|
||||
#include "utils/errno.h"
|
||||
#include "crypto/key_manager.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
@ -71,15 +72,28 @@ int32_t StorageDaemon::StopUser(int32_t userId)
|
||||
|
||||
int32_t StorageDaemon::InitGlobalKey(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
return KeyManager::GetInstance()->InitGlobalDeviceKey();
|
||||
}
|
||||
|
||||
int32_t StorageDaemon::InitGlobalUserKeys(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(keyMutex_);
|
||||
return KeyManager::GetInstance()->InitGlobalUserKeys();
|
||||
int ret = KeyManager::GetInstance()->InitGlobalUserKeys();
|
||||
if (ret) {
|
||||
LOGE("Init global users els failed");
|
||||
return ret;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return UserManager::Instance()->PrepareUserDirs(GLOBAL_USER_ID, CRYPTO_FLAG_EL1 | CRYPTO_FLAG_EL2);
|
||||
}
|
||||
|
||||
int32_t StorageDaemon::GenerateUserKeys(uint32_t userId, uint32_t flags)
|
||||
{
|
||||
return KeyManager::GetInstance()->GenerateUserKeys(userId, flags);
|
||||
}
|
||||
|
||||
int32_t StorageDaemon::DeleteUserKeys(uint32_t userId)
|
||||
{
|
||||
return KeyManager::GetInstance()->DeleteUserKeys(userId);
|
||||
}
|
||||
} // StorageDaemon
|
||||
} // OHOS
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "ipc/storage_daemon_proxy.h"
|
||||
#include "utils/errno.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
@ -152,6 +153,7 @@ int32_t StorageDaemonProxy::InitGlobalUserKeys(void)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option(MessageOption::TF_SYNC);
|
||||
LOGI("start");
|
||||
if (!data.WriteInterfaceToken(StorageDaemonProxy::GetDescriptor())) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
@ -164,5 +166,50 @@ int32_t StorageDaemonProxy::InitGlobalUserKeys(void)
|
||||
return reply.ReadUint32();
|
||||
}
|
||||
|
||||
int32_t StorageDaemonProxy::GenerateUserKeys(uint32_t userId, uint32_t flags)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option(MessageOption::TF_SYNC);
|
||||
|
||||
LOGI("start");
|
||||
if (!data.WriteInterfaceToken(StorageDaemonProxy::GetDescriptor())) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
if(!data.WriteUint32(userId)) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
if (!data.WriteUint32(flags)) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
int err = Remote()->SendRequest(CREATE_USER_KEYS, data, reply, option);
|
||||
if (err != E_OK) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
return reply.ReadUint32();
|
||||
}
|
||||
|
||||
int32_t StorageDaemonProxy::DeleteUserKeys(uint32_t userId)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option(MessageOption::TF_SYNC);
|
||||
|
||||
if (!data.WriteInterfaceToken(StorageDaemonProxy::GetDescriptor())) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
if (!data.WriteUint32(userId)) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
int err = Remote()->SendRequest(DELETE_USER_KEYS, data, reply, option);
|
||||
if (err != E_OK) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
} // StorageDaemon
|
||||
} // OHOS
|
@ -50,6 +50,11 @@ int32_t StorageDaemonStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
|
||||
case INIT_GLOBAL_USER_KEYS:
|
||||
err = HandleInitGlobalUserKeys(data, reply);
|
||||
break;
|
||||
case CREATE_USER_KEYS:
|
||||
err = HandleGenerateUserKeys(data, reply);
|
||||
break;
|
||||
case DELETE_USER_KEYS:
|
||||
err = HandleDeleteUserKeys(data, reply);
|
||||
default: {
|
||||
LOGI(" use IPCObjectStub default OnRemoteRequest");
|
||||
err = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
|
||||
@ -137,7 +142,7 @@ int32_t StorageDaemonStub::HandleStopUser(MessageParcel &data, MessageParcel &re
|
||||
int32_t StorageDaemonStub::HandleInitGlobalKey(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
int err = InitGlobalKey();
|
||||
if (reply.WriteInt32(err)){
|
||||
if (!reply.WriteInt32(err)){
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
@ -147,12 +152,34 @@ int32_t StorageDaemonStub::HandleInitGlobalKey(MessageParcel &data, MessageParce
|
||||
int32_t StorageDaemonStub::HandleInitGlobalUserKeys(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
int err = InitGlobalUserKeys();
|
||||
if (reply.WriteInt32(err)){
|
||||
if (!reply.WriteInt32(err)){
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t StorageDaemonStub::HandleGenerateUserKeys(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
uint32_t userId = data.ReadUint32();
|
||||
uint32_t flags = data.ReadUint32();
|
||||
int err = GenerateUserKeys(userId, flags);
|
||||
if (!reply.WriteInt32(err)) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
int32_t StorageDaemonStub::HandleDeleteUserKeys(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
uint32_t userId = data.ReadUint32();
|
||||
int err = DeleteUserKeys(userId);
|
||||
if (!reply.WriteInt32(err)) {
|
||||
return E_IPC_ERROR;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
} // StorageDaemon
|
||||
} // OHOS
|
@ -18,11 +18,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "utils/file_utils.h"
|
||||
#include "storage_daemon_client.h"
|
||||
|
||||
static void HandleFileCrypt(const std::string &cmd, const std::vector<std::string> &args)
|
||||
{
|
||||
LOGI("fscrypt cmd: %s", cmd.c_str());
|
||||
LOGI("fscrypt cmd: %{public}s", cmd.c_str());
|
||||
if (cmd == "init_global_key") {
|
||||
// sdc filecrypt init_global_key /data
|
||||
int32_t ret = OHOS::StorageDaemon::StorageDaemonClient::InitGlobalKey();
|
||||
@ -37,6 +38,56 @@ static void HandleFileCrypt(const std::string &cmd, const std::vector<std::strin
|
||||
LOGE("Init global user keys failed");
|
||||
return;
|
||||
}
|
||||
} else if (cmd == "generate_user_keys") {
|
||||
// sdc filecrypt generate_user_keys userId flag
|
||||
if (args.size() < 5) {
|
||||
LOGE("Parameter nums is less than 5, please retry");
|
||||
return;
|
||||
}
|
||||
uint32_t userId, flags;
|
||||
if ((OHOS::StorageDaemon::StringToUint32(args[3], userId) == false) ||
|
||||
(OHOS::StorageDaemon::StringToUint32(args[4], flags) == false)) {
|
||||
LOGE("Parameter input error, please retry");
|
||||
return;
|
||||
}
|
||||
int32_t ret = OHOS::StorageDaemon::StorageDaemonClient::GenerateUserKeys(userId, flags);
|
||||
if (ret) {
|
||||
LOGE("Create user %{public}u el error", userId);
|
||||
return;
|
||||
}
|
||||
} else if (cmd == "prepare_user_storage") {
|
||||
// sdc filecrypt prepare_user_storage userId flag
|
||||
if (args.size() < 5) {
|
||||
LOGE("Parameter nums is less than 5, please retry");
|
||||
return;
|
||||
}
|
||||
uint32_t userId, flags;
|
||||
if ((OHOS::StorageDaemon::StringToUint32(args[3], userId) == false) ||
|
||||
(OHOS::StorageDaemon::StringToUint32(args[4], flags) == false)) {
|
||||
LOGE("Parameter input error, please retry");
|
||||
return;
|
||||
}
|
||||
int32_t ret = OHOS::StorageDaemon::StorageDaemonClient::PrepareUserDirs(userId, flags);
|
||||
if (ret) {
|
||||
LOGE("Prepare user %{public}u storage error", userId);
|
||||
return;
|
||||
}
|
||||
} else if (cmd == "delete_user_keys") {
|
||||
// sdc filecrypt delete_user_keys userId
|
||||
if (args.size() < 4) {
|
||||
LOGE("Parameter nums is less than 4, please retry");
|
||||
return;
|
||||
}
|
||||
uint32_t userId;
|
||||
if (OHOS::StorageDaemon::StringToUint32(args[3], userId) == false) {
|
||||
LOGE("Parameter input error, please retry");
|
||||
return;
|
||||
}
|
||||
int ret = OHOS::StorageDaemon::StorageDaemonClient::DeleteUserKeys(userId);
|
||||
if (ret) {
|
||||
LOGE("Delete user %{public}u key error", userId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "utils/string_utils.h"
|
||||
#include "utils/log.h"
|
||||
#include "ipc/istorage_daemon.h"
|
||||
#include "crypto/key_manager.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -113,12 +114,13 @@ int32_t UserManager::PrepareUserDirs(int32_t userId, uint32_t flags)
|
||||
if (err != E_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// get syspara: hmdfs
|
||||
err = PrepareHmdfsDirs(userId);
|
||||
if (err != E_OK) {
|
||||
return err;
|
||||
// get syspara: hmdfs
|
||||
err = PrepareHmdfsDirs(userId);
|
||||
if (err != E_OK) {
|
||||
LOGE("Prepare hmdfs dir error");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
@ -176,6 +178,24 @@ int32_t UserManager::PrepareDirsFromIdAndLevel(int32_t userId, const std::string
|
||||
}
|
||||
|
||||
// set policy here
|
||||
std::vector<FileList> list;
|
||||
for (auto item : rootDirVec_) {
|
||||
FileList temp;
|
||||
temp.userId = userId;
|
||||
temp.path = StringPrintf(item.path.c_str(), level.c_str(), userId);
|
||||
list.push_back(temp);
|
||||
}
|
||||
if (level == el1_) {
|
||||
if (KeyManager::GetInstance()->SetDirectoryElPolicy(userId, EL1_KEY, list)) {
|
||||
LOGE("Set user dir el1 policy error");
|
||||
return E_SET_POLICY;
|
||||
}
|
||||
} else if (level == el2_) {
|
||||
if (KeyManager::GetInstance()->SetDirectoryElPolicy(userId, EL2_KEY, list)) {
|
||||
LOGE("Set user dir el1 policy error");
|
||||
return E_SET_POLICY;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PrepareDirsFromVec(userId, level, subDirVec_)) {
|
||||
LOGE("failed to prepare %{public}s sub dirs for userid %{public}d", level.c_str(), userId);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include "utils/errno.h"
|
||||
#include "utils/log.h"
|
||||
#include "string_ex.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace StorageDaemon {
|
||||
@ -57,6 +58,18 @@ int32_t UMount(const std::string &path)
|
||||
return TEMP_FAILURE_RETRY(umount(path.c_str()));
|
||||
}
|
||||
|
||||
bool IsDir(const std::string &path)
|
||||
{
|
||||
// check whether the path exists
|
||||
struct stat st;
|
||||
int ret = TEMP_FAILURE_RETRY(lstat(path.c_str(), &st));
|
||||
if (ret) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
// On success, true is returned. On error, false is returned, and errno is set appropriately.
|
||||
bool PrepareDir(const std::string &path, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
@ -142,5 +155,62 @@ bool RmDirRecurse(const std::string &path)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StringToUint32(const std::string &str, uint32_t &num)
|
||||
{
|
||||
if (str.empty()) {
|
||||
return false;
|
||||
}
|
||||
if (!IsNumericStr(str)) {
|
||||
LOGE("Not numeric entry");
|
||||
return false;
|
||||
}
|
||||
|
||||
int value;
|
||||
if (!StrToInt(str, value)) {
|
||||
LOGE("String to int convert failed");
|
||||
return false;
|
||||
}
|
||||
num = static_cast<uint32_t>(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReadDigitDir(const std::string &path, std::vector<FileList> &dirInfo)
|
||||
{
|
||||
struct stat st;
|
||||
int ret = TEMP_FAILURE_RETRY(lstat(path.c_str(), &st));
|
||||
if (ret != 0 || ((st.st_mode & S_IFDIR) != S_IFDIR)) {
|
||||
LOGE("path is not dir");
|
||||
return;
|
||||
}
|
||||
|
||||
DIR *dir = opendir(path.c_str());
|
||||
if (!dir) {
|
||||
LOGE("failed to open dir %{public}s, errno %{public}d", path.c_str(), errno);
|
||||
return;
|
||||
}
|
||||
|
||||
for (struct dirent *ent = readdir(dir); ent != nullptr; ent = readdir(dir)) {
|
||||
if ((ent->d_type != DT_DIR) ||
|
||||
(strcmp(ent->d_name, ".") == 0) ||
|
||||
(strcmp(ent->d_name, "..") == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t userId;
|
||||
std::string name(ent->d_name);
|
||||
if (StringToUint32(name, userId) == false) {
|
||||
continue;
|
||||
}
|
||||
FileList entry = {
|
||||
.userId = userId,
|
||||
.path = path + "/" + name
|
||||
};
|
||||
dirInfo.push_back(entry);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
} // STORAGE_DAEMON
|
||||
} // OHOS
|
Loading…
x
Reference in New Issue
Block a user