!105 improve openssl usage

Merge pull request !105 from CheungVane/master
This commit is contained in:
openharmony_ci 2024-09-05 11:42:19 +00:00 committed by Gitee
commit 5b9cde6674
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
18 changed files with 114 additions and 68 deletions

View File

@ -18,7 +18,7 @@
use asset_definition::{log_throw_error, ErrCode, Result};
use std::{fs, path::Path};
use crate::common::{get_user_dbs, DB_KEY, is_file_exist};
use crate::common::{get_user_dbs, is_file_exist, DB_KEY};
fn construct_ce_db_dir(user_id: i32) -> String {
format!("data/service/el2/{}/asset_service", user_id)
@ -76,10 +76,11 @@ pub fn remove_ce_files(user_id: i32) -> Result<()> {
Err(e) => {
return log_throw_error!(
ErrCode::FileOperationError,
"[FATAL]Remove [{}] failed, error code:[{}]", file.path().to_string_lossy().to_string(),
"[FATAL]Remove [{}] failed, error code:[{}]",
file.path().to_string_lossy().to_string(),
e
)
}
},
}
}
Ok(())

View File

@ -15,7 +15,7 @@
//! This file implements ce file operations.
use asset_definition::{log_throw_error, Result, ErrCode};
use asset_definition::{log_throw_error, ErrCode, Result};
use std::{fs, path::Path};
/// Suffix for backup database files.
@ -56,4 +56,4 @@ pub fn is_file_exist(path_str: &str) -> Result<bool> {
)
},
}
}
}

View File

@ -16,5 +16,5 @@
//! This file implements file operations.
pub mod ce_operator;
pub mod common;
pub mod de_operator;
pub mod common;

View File

@ -25,6 +25,8 @@ extern "C" {
// The caller should ensure the memory safety, that the points should point at valid memory.
void Sha256(const uint8_t *input, uint32_t intputLen, uint8_t *output);
int32_t GenerateRandom(uint8_t *random, uint32_t randomLen);
#ifdef __cplusplus
}
#endif

View File

@ -15,6 +15,7 @@
#include "openssl_wrapper.h"
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <stdlib.h>
#include <string.h>
@ -33,3 +34,12 @@ void Sha256(const uint8_t *input, uint32_t intputLen, uint8_t *output)
(void)SHA256((const unsigned char *)input, intputLen, (unsigned char *)output);
}
int32_t GenerateRandom(uint8_t *random, uint32_t randomLen)
{
if (RAND_priv_bytes(random, randomLen) < 0) {
LOGE("Generate random failed!");
return -1;
}
return 0;
}

View File

@ -25,11 +25,15 @@ use std::{
use asset_common::{AutoCounter, CallingInfo, OwnerType};
use asset_crypto_manager::{crypto_manager::CryptoManager, secret_key::SecretKey};
use asset_db_operator::{
database::Database, database_file_upgrade::construct_splited_db_name, types::{column, DbMap}
database::Database,
database_file_upgrade::construct_splited_db_name,
types::{column, DbMap},
};
use asset_definition::{log_throw_error, ErrCode, Result, SyncType, Value};
use asset_file_operator::{
ce_operator::is_db_key_cipher_file_exist, common::{BACKUP_SUFFIX, CE_ROOT_PATH, DB_SUFFIX, DE_ROOT_PATH}, de_operator::delete_user_de_dir
ce_operator::is_db_key_cipher_file_exist,
common::{BACKUP_SUFFIX, CE_ROOT_PATH, DB_SUFFIX, DE_ROOT_PATH},
de_operator::delete_user_de_dir,
};
use asset_log::{loge, logi, logw};
use asset_plugin::asset_plugin::AssetPlugin;
@ -54,7 +58,7 @@ fn remove_db(file_path: &str, calling_info: &CallingInfo, is_ce: bool) -> Result
Ok(_) => (),
Err(e) => {
logw!("[WARNING]Remove db:[{}] failed, error code:[{}]", db_file_name, e);
}
},
}
}
}
@ -65,7 +69,7 @@ fn delete_in_de_db_on_package_removed(
calling_info: &CallingInfo,
delete_cond: &DbMap,
reverse_condition: &DbMap,
check_cond: &DbMap
check_cond: &DbMap,
) -> Result<bool> {
// Delete non-persistent data in de db.
let mut de_db = Database::build(calling_info, false)?;
@ -73,7 +77,7 @@ fn delete_in_de_db_on_package_removed(
let de_db_data_exists = de_db.is_data_exists(check_cond, false)?;
// remove db and backup db
if !de_db_data_exists {
remove_db(&format!("{}/{}", DE_ROOT_PATH,calling_info.user_id()), calling_info, false)?;
remove_db(&format!("{}/{}", DE_ROOT_PATH, calling_info.user_id()), calling_info, false)?;
}
Ok(de_db_data_exists)
}
@ -104,10 +108,12 @@ fn delete_on_package_removed(owner: Vec<u8>, calling_info: &CallingInfo) -> Resu
reverse_condition.insert(column::SYNC_TYPE, Value::Number(SyncType::TrustedAccount as u32));
let mut check_cond = delete_cond.clone();
check_cond.remove(column::IS_PERSISTENT);
let de_db_data_exists = delete_in_de_db_on_package_removed(calling_info, &delete_cond, &reverse_condition, &check_cond)?;
let de_db_data_exists =
delete_in_de_db_on_package_removed(calling_info, &delete_cond, &reverse_condition, &check_cond)?;
if is_db_key_cipher_file_exist(calling_info.user_id())? {
let ce_db_data_exists = delete_in_ce_db_on_package_removed(calling_info, &delete_cond, &reverse_condition, &check_cond)?;
let ce_db_data_exists =
delete_in_ce_db_on_package_removed(calling_info, &delete_cond, &reverse_condition, &check_cond)?;
Ok(de_db_data_exists || ce_db_data_exists)
} else {
Ok(de_db_data_exists)

View File

@ -15,7 +15,10 @@
//! This module implements the Asset service.
use std::{fs, time::{Duration, Instant}};
use std::{
fs,
time::{Duration, Instant},
};
use asset_db_operator::database_file_upgrade::check_and_split_db;
use samgr::manage::SystemAbilityManager;
@ -107,7 +110,7 @@ impl Ability for AssetAbility {
async fn upgrade_process() -> Result<()> {
let _counter_user = AutoCounter::new();
for entry in fs::read_dir(DE_ROOT_PATH)? {
let entry = entry?;
let entry = entry?;
if let Ok(user_id) = entry.file_name().to_string_lossy().parse::<i32>() {
check_and_split_db(user_id)?;
}
@ -119,7 +122,8 @@ fn start_service(handler: Handler) -> Result<()> {
let asset_plugin = AssetPlugin::get_instance();
match asset_plugin.load_plugin() {
Ok(loader) => {
let _tr = loader.init(Box::new(AssetContext { user_id: 0, calling_info: CallingInfo::new(0, OwnerType::Hap, vec![]) }));
let _tr = loader
.init(Box::new(AssetContext { user_id: 0, calling_info: CallingInfo::new(0, OwnerType::Hap, vec![]) }));
logi!("load plugin success.");
},
Err(_) => loge!("load plugin failed."),

View File

@ -29,9 +29,7 @@ use asset_definition::{
};
use asset_log::{loge, logi};
use asset_plugin::asset_plugin::AssetPlugin;
use asset_sdk::plugin_interface::{
EventType, ExtDbMap, PARAM_NAME_BUNDLE_NAME, PARAM_NAME_USER_ID,
};
use asset_sdk::plugin_interface::{EventType, ExtDbMap, PARAM_NAME_BUNDLE_NAME, PARAM_NAME_USER_ID};
const TAG_COLUMN_TABLE: [(Tag, &str); 20] = [
(Tag::Secret, column::SECRET),

View File

@ -17,7 +17,10 @@
use asset_common::CallingInfo;
use asset_crypto_manager::{crypto::Crypto, crypto_manager::CryptoManager, secret_key::SecretKey};
use asset_db_operator::{database::create_db_instance, types::{column, DbMap}};
use asset_db_operator::{
database::create_db_instance,
types::{column, DbMap},
};
use asset_definition::{log_throw_error, Accessibility, AssetMap, AuthType, ErrCode, Extension, Result, Tag, Value};
use crate::operations::common;

View File

@ -16,7 +16,10 @@
//! This module is used to delete the Asset, including single and batch deletion.
use asset_common::CallingInfo;
use asset_db_operator::{database::create_db_instance, types::{column, DbMap}};
use asset_db_operator::{
database::create_db_instance,
types::{column, DbMap},
};
use asset_definition::{log_throw_error, AssetMap, ErrCode, Result, SyncStatus, SyncType, Value};
use asset_log::logi;
use asset_utils::time;

View File

@ -17,7 +17,10 @@
use asset_common::CallingInfo;
use asset_crypto_manager::crypto::Crypto;
use asset_db_operator::{database::create_db_instance, types::{column, DbMap, DB_DATA_VERSION}};
use asset_db_operator::{
database::create_db_instance,
types::{column, DbMap, DB_DATA_VERSION},
};
use asset_definition::{log_throw_error, AssetMap, ErrCode, Extension, LocalStatus, Result, SyncStatus, Tag, Value};
use asset_utils::time;

View File

@ -82,7 +82,7 @@ impl SecretKey {
alias: Option<Vec<u8>>,
) -> Result<Self> {
if let Some(alias) = alias {
return Ok(Self { auth_type, access_type, require_password_set, alias, calling_info: calling_info.clone() })
return Ok(Self { auth_type, access_type, require_password_set, alias, calling_info: calling_info.clone() });
}
// Check whether new key exists.

View File

@ -16,10 +16,10 @@ import("//build/ohos.gni")
ohos_rust_static_library("asset_db_key_operator") {
sources = [ "src/lib.rs" ]
deps = [
"../../../../../third_party/rust/crates/rust-openssl/openssl:lib",
"../../frameworks/definition:asset_definition",
"../../frameworks/os_dependency/file:asset_file_operator",
"../../frameworks/os_dependency/log:asset_log",
"../../frameworks/os_dependency/openssl:asset_openssl_wrapper",
"../common:asset_common",
"../crypto_manager:asset_crypto_manager",
]

View File

@ -15,12 +15,11 @@
//! This module implements functions related to Asset database key.
use asset_common::CallingInfo;
use asset_common::{CallingInfo, SUCCESS};
use asset_crypto_manager::{crypto::Crypto, secret_key::SecretKey};
use asset_definition::{Accessibility, AuthType, Result};
use asset_definition::{log_throw_error, Accessibility, AuthType, ErrCode, Result};
use asset_file_operator::ce_operator::{is_db_key_cipher_file_exist, read_db_key_cipher, write_db_key_cipher};
use asset_log::logi;
use openssl::rand::rand_bytes;
use std::sync::Mutex;
fn build_db_key_secret_key(calling_info: &CallingInfo) -> Result<SecretKey> {
@ -54,6 +53,10 @@ pub fn generate_secret_key_if_needed(secret_key: &SecretKey) -> Result<()> {
}
}
extern "C" {
fn GenerateRandom(random: *mut u8, random_len: u32) -> i32;
}
/// db key obj
pub struct DbKey {
/// db key
@ -72,7 +75,10 @@ impl DbKey {
fn generate_db_key() -> Result<DbKey> {
const KEY_LEN_IN_BYTES: usize = 32; // aes-256-gcm requires key length 256 bits = 32 bytes.
let mut db_key = [0; KEY_LEN_IN_BYTES];
rand_bytes(&mut db_key).unwrap();
if unsafe { GenerateRandom(db_key.as_mut_ptr(), db_key.len() as u32) } != SUCCESS {
return log_throw_error!(ErrCode::CryptoError, "[FATAL]Generate random failed!");
}
Ok(Self { db_key: db_key.to_vec() })
}
@ -110,7 +116,7 @@ impl DbKey {
write_db_key_cipher(calling_info.user_id(), &db_key_cipher)?;
Ok(db_key)
},
Err(e) => Err(e)
Err(e) => Err(e),
}
},
Err(e) => Err(e),

View File

@ -20,19 +20,19 @@ use core::ffi::c_void;
use std::{ffi::CStr, fs, ptr::null_mut, sync::Mutex};
use asset_common::{CallingInfo, OwnerType};
use asset_db_key_operator::DbKey;
use asset_definition::{log_throw_error, AssetMap, ErrCode, Extension, Result, Tag, Value};
use asset_file_operator::{ce_operator::remove_ce_files, common::is_file_exist};
use asset_log::{loge, logi};
use asset_db_key_operator::DbKey;
use crate::{
database_file_upgrade::{check_and_split_db, construct_splited_db_name, fmt_old_de_db_path},
statement::Statement,
table::Table,
types::{
column, sqlite_err_handle, DbMap, QueryOptions, COLUMN_INFO, DB_UPGRADE_VERSION, DB_UPGRADE_VERSION_V1,
DB_UPGRADE_VERSION_V2, SQLITE_OK, TABLE_NAME, UPGRADE_COLUMN_INFO, UPGRADE_COLUMN_INFO_V2,
},
database_file_upgrade::{check_and_split_db, construct_splited_db_name, fmt_old_de_db_path},
};
extern "C" {
@ -63,9 +63,7 @@ pub(crate) fn get_split_db_lock_by_user_id(user_id: i32) -> &'static UserDbLock
return f;
}
}
let nf = Box::new(
UserDbLock { user_id, mtx: Mutex::new(user_id), db_file_name: OLD_DB_NAME.clone().to_string() }
);
let nf = Box::new(UserDbLock { user_id, mtx: Mutex::new(user_id), db_file_name: OLD_DB_NAME.clone().to_string() });
// SAFETY: We just push item into USER_DB_LOCK_LIST, never remove item or modify item,
// so return a reference of leak item is safe.
let nf: &'static UserDbLock = Box::leak(nf);
@ -134,29 +132,28 @@ fn check_validity_of_db_key(path: &str, user_id: i32) -> Result<()> {
if is_file_exist(path)? && !DbKey::check_existance(user_id)? {
loge!("[FATAL]There is database bot no database key. Now all data should be cleared and restart over.");
remove_ce_files(user_id)?;
return log_throw_error!(ErrCode::DataCorrupted, "[FATAL]All data is cleared in {}.", user_id)
return log_throw_error!(ErrCode::DataCorrupted, "[FATAL]All data is cleared in {}.", user_id);
}
Ok(())
}
pub(crate) fn get_db(user_id: i32, db_name: &str, is_ce: bool) -> Result<Database> {
let path = if is_ce {
fmt_ce_db_path_with_name(user_id, db_name)
} else {
fmt_de_db_path_with_name(user_id, db_name)
};
let path =
if is_ce { fmt_ce_db_path_with_name(user_id, db_name) } else { fmt_de_db_path_with_name(user_id, db_name) };
let db_key = if is_ce {
check_validity_of_db_key(&path, user_id)?;
let calling_info = CallingInfo::new_part_info(user_id);
match DbKey::get_db_key(&calling_info) {
Ok(res) => Some(res),
Err(e) if e.code == ErrCode::NotFound || e.code == ErrCode::DataCorrupted => {
loge!("[FATAL]The key is corrupted. Now all data should be cleared and restart over, err is {}.",
e.code);
loge!(
"[FATAL]The key is corrupted. Now all data should be cleared and restart over, err is {}.",
e.code
);
remove_ce_files(user_id)?;
return log_throw_error!(ErrCode::DataCorrupted, "[FATAL]All data is cleared in {}.", user_id)
}
Err(e) => return Err(e)
return log_throw_error!(ErrCode::DataCorrupted, "[FATAL]All data is cleared in {}.", user_id);
},
Err(e) => return Err(e),
}
} else {
None
@ -196,8 +193,8 @@ impl Database {
}
get_db(
calling_info.user_id(),
&construct_splited_db_name(calling_info.owner_type_enum(),
calling_info.owner_info(), is_ce)?, is_ce
&construct_splited_db_name(calling_info.owner_type_enum(), calling_info.owner_info(), is_ce)?,
is_ce,
)
}
@ -264,7 +261,8 @@ impl Database {
/// Encrypt/Decrypt CE database.
pub fn set_db_key(&mut self, db_key: &DbKey) -> Result<()> {
let ret = unsafe { SqliteKey(self.handle as _, db_key.db_key.as_ptr() as *const c_void, db_key.db_key.len() as i32) };
let ret =
unsafe { SqliteKey(self.handle as _, db_key.db_key.as_ptr() as *const c_void, db_key.db_key.len() as i32) };
if ret == SQLITE_OK {
Ok(())
} else {
@ -550,10 +548,7 @@ impl Database {
}
/// query how many data fit the query condition
pub fn query_data_count(
&mut self,
condition: &DbMap,
) -> Result<u32> {
pub fn query_data_count(&mut self, condition: &DbMap) -> Result<u32> {
let _lock = self.db_lock.mtx.lock().unwrap();
let closure = |e: &Table| e.count_datas(condition, false);
self.restore_if_exec_fail(closure)

View File

@ -23,9 +23,11 @@ use asset_definition::{log_throw_error, ErrCode, Extension, Result, Value};
use asset_log::logi;
use crate::{
database::{fmt_backup_path, fmt_de_db_path_with_name, get_db, get_split_db_lock_by_user_id, Database, OLD_DB_NAME, DE_ROOT_PATH}, types::{
column, DbMap, QueryOptions,
}
database::{
fmt_backup_path, fmt_de_db_path_with_name, get_db, get_split_db_lock_by_user_id, Database, DE_ROOT_PATH,
OLD_DB_NAME,
},
types::{column, DbMap, QueryOptions},
};
const MINIM_OWNER_INFO_LEN: usize = 3;
@ -62,7 +64,7 @@ pub fn construct_splited_db_name(owner_type: OwnerType, owner_info: &[u8], is_ce
},
OwnerType::Native => {
format!("Native_{}", String::from_utf8_lossy(owner_info))
}
},
};
if is_ce {
res = format!("enc_{}", res)
@ -77,7 +79,7 @@ fn get_db_before_split(user_id: i32) -> Result<Database> {
fn get_value_from_db_map(db_map: &DbMap, key: &str) -> Result<Value> {
match db_map.get(key) {
Some(value) => Ok(value.clone()),
_ => log_throw_error!(ErrCode::DatabaseError, "[FATAL]Get value from {} failed.", key)
_ => log_throw_error!(ErrCode::DatabaseError, "[FATAL]Get value from {} failed.", key),
}
}
@ -113,12 +115,16 @@ fn calculate_batch_split_times(old_data_query_condition: &DbMap, old_db: &mut Da
Ok(query_times)
}
fn migrate_data(old_db: &mut Database, new_db: &mut Database, split_time: u32, old_data_query_condition: &DbMap) -> Result<()> {
fn migrate_data(
old_db: &mut Database,
new_db: &mut Database,
split_time: u32,
old_data_query_condition: &DbMap,
) -> Result<()> {
// 3.1 query data in old db
let query_options = QueryOptions {offset: None, limit: Some(MAX_BATCH_NUM), order_by: None, order: None};
let query_options = QueryOptions { offset: None, limit: Some(MAX_BATCH_NUM), order_by: None, order: None };
let old_data_vec =
old_db.query_datas(&vec![], old_data_query_condition, Some(&query_options), false)?;
let old_data_vec = old_db.query_datas(&vec![], old_data_query_condition, Some(&query_options), false)?;
// 3.2 insert data in new db
for data in &old_data_vec {
let mut condition = DbMap::new();
@ -142,7 +148,7 @@ fn split_db(user_id: i32) -> Result<()> {
// 2. get split db info
let empty_condition = DbMap::new();
let owner_info_db_list =
old_db.query_datas(&vec![column::OWNER_TYPE, column::OWNER], &empty_condition, None, false)?;
old_db.query_datas(&vec![column::OWNER_TYPE, column::OWNER], &empty_condition, None, false)?;
for info_map in &owner_info_db_list {
// 1. get new db
let mut new_db = get_new_db(user_id, info_map)?;
@ -168,4 +174,4 @@ pub fn check_and_split_db(user_id: i32) -> Result<()> {
}
}
Ok(())
}
}

View File

@ -16,10 +16,10 @@
//! This module encapsulates the database operation function based on sqlite.
pub mod database;
pub mod database_file_upgrade;
mod statement;
mod table;
mod transaction;
pub mod database_file_upgrade;
pub mod types;
#[cfg(test)]

View File

@ -14,7 +14,11 @@
*/
use asset_common::{CallingInfo, Counter, OwnerType};
use asset_db_operator::{database::{get_path, Database}, database_file_upgrade::construct_splited_db_name, types::column};
use asset_db_operator::{
database::{get_path, Database},
database_file_upgrade::construct_splited_db_name,
types::column,
};
use asset_definition::{log_throw_error, ErrCode, Extension, Result};
use asset_file_operator::de_operator::create_user_de_dir;
use asset_log::{loge, logi};
@ -22,7 +26,10 @@ use asset_sdk::{
plugin_interface::{ExtDbMap, IAssetPlugin, IAssetPluginCtx},
Value,
};
use std::{cell::RefCell, sync::{Arc, Mutex}};
use std::{
cell::RefCell,
sync::{Arc, Mutex},
};
/// The asset_ext plugin.
#[derive(Default)]
@ -202,7 +209,8 @@ impl IAssetPluginCtx for AssetContext {
let mut total_remove_count = 0;
for db_name in de_dbs {
let mut db = Database::build_with_file_name(self.user_id, &db_name, false).map_err(|e| e.code as u32)?;
total_remove_count += db.delete_specific_condition_datas(specific_cond, condition_value).map_err(|e| e.code as u32)?;
total_remove_count +=
db.delete_specific_condition_datas(specific_cond, condition_value).map_err(|e| e.code as u32)?;
}
Ok(total_remove_count)
}
@ -217,7 +225,8 @@ impl IAssetPluginCtx for AssetContext {
let mut total_remove_count = 0;
for db_name in ce_dbs {
let mut db = Database::build_with_file_name(self.user_id, &db_name, true).map_err(|e| e.code as u32)?;
total_remove_count += db.delete_specific_condition_datas(specific_cond, condition_value).map_err(|e| e.code as u32)?;
total_remove_count +=
db.delete_specific_condition_datas(specific_cond, condition_value).map_err(|e| e.code as u32)?;
}
Ok(total_remove_count)
}