forked from lthn/blockchain
implemented secure api for configuring wallets data
This commit is contained in:
parent
c0f651ff33
commit
31e328768e
8 changed files with 150 additions and 86 deletions
66
src/common/config_encrypt_helper.h
Normal file
66
src/common/config_encrypt_helper.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) 2014-2020 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "wallet/view_iface.h"
|
||||
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct app_data_file_binary_header
|
||||
{
|
||||
uint64_t m_signature;
|
||||
uint64_t m_cb_body;
|
||||
};
|
||||
#pragma pack (pop)
|
||||
|
||||
inline
|
||||
std::string load_encrypted_file(const std::string& path, const std::string& key, std::string& body, uint64_t signature)
|
||||
{
|
||||
std::string app_data_buff;
|
||||
bool r = epee::file_io_utils::load_file_to_string(path, app_data_buff);
|
||||
if (!r)
|
||||
{
|
||||
return API_RETURN_CODE_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (app_data_buff.size() < sizeof(app_data_file_binary_header))
|
||||
{
|
||||
LOG_ERROR("app_data_buff.size()(" << app_data_buff.size() << ") < sizeof(app_data_file_binary_header) (" << sizeof(app_data_file_binary_header) << ") check failed while loading from " << path);
|
||||
return API_RETURN_CODE_INVALID_FILE;
|
||||
}
|
||||
|
||||
crypto::chacha_crypt(app_data_buff, key);
|
||||
|
||||
const app_data_file_binary_header* phdr = reinterpret_cast<const app_data_file_binary_header*>(app_data_buff.data());
|
||||
if (phdr->m_signature != signature)
|
||||
{
|
||||
return API_RETURN_CODE_WRONG_PASSWORD;
|
||||
}
|
||||
body = app_data_buff.substr(sizeof(app_data_file_binary_header)).c_str();
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
inline
|
||||
std::string store_encrypted_file(const std::string& path, const std::string& key, const std::string& body, uint64_t signature)
|
||||
{
|
||||
std::string buff(sizeof(app_data_file_binary_header), 0);
|
||||
app_data_file_binary_header* phdr = (app_data_file_binary_header*)buff.data();
|
||||
phdr->m_signature = signature;
|
||||
phdr->m_cb_body = 0; // for future use
|
||||
|
||||
buff.append(body);
|
||||
crypto::chacha_crypt(buff, key);
|
||||
|
||||
bool r = epee::file_io_utils::save_string_to_file(path, buff);
|
||||
if (r)
|
||||
return API_RETURN_CODE_OK;
|
||||
else
|
||||
return API_RETURN_CODE_FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
#include "string_coding.h"
|
||||
#include "gui_utils.h"
|
||||
#include "notification_helper.h"
|
||||
#include "common/config_encrypt_helper.h"
|
||||
|
||||
#define PREPARE_ARG_FROM_JSON(arg_type, var_name) \
|
||||
arg_type var_name = AUTO_VAL_INIT(var_name); \
|
||||
|
|
@ -1047,6 +1048,35 @@ void MainWindow::on_clear_events()
|
|||
CATCH_ENTRY2(void());
|
||||
}
|
||||
|
||||
|
||||
QString MainWindow::store_secure_app_data(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
if (!tools::create_directories_if_necessary(m_backend.get_config_folder()))
|
||||
{
|
||||
view::api_response ar;
|
||||
LOG_PRINT_L0("Failed to create data directory: " << m_backend.get_config_folder());
|
||||
ar.error_code = API_RETURN_CODE_FAIL;
|
||||
return MAKE_RESPONSE(ar);
|
||||
}
|
||||
|
||||
view::api_response ar = AUTO_VAL_INIT(ar);
|
||||
ar.error_code = tools::store_encrypted_file(m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME,
|
||||
m_master_password, param.toStdString(), APP_DATA_FILE_BINARY_SIGNATURE);
|
||||
if (ar.error_code != API_RETURN_CODE_OK)
|
||||
{
|
||||
return MAKE_RESPONSE(ar);
|
||||
}
|
||||
|
||||
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
|
||||
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
|
||||
LOG_PRINT_L0("store_secure_app_data, r = " << ar.error_code << ", pass hash: " << master_password_hash);
|
||||
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
QString MainWindow::get_secure_app_data(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
@ -1060,41 +1090,21 @@ QString MainWindow::get_secure_app_data(const QString& param)
|
|||
return MAKE_RESPONSE(ar);
|
||||
}
|
||||
|
||||
std::string app_data_buff;
|
||||
std::string filename = m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME;
|
||||
bool r = file_io_utils::load_file_to_string(filename, app_data_buff);
|
||||
if (!r)
|
||||
std::string res_body;
|
||||
std::string rsp_code = tools::load_encrypted_file(filename, pwd.pass, res_body, APP_DATA_FILE_BINARY_SIGNATURE);
|
||||
if (rsp_code != API_RETURN_CODE_OK)
|
||||
{
|
||||
LOG_PRINT_L1("gui secure config was not loaded from " << filename);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (app_data_buff.size() < sizeof(app_data_file_binary_header))
|
||||
{
|
||||
LOG_ERROR("app_data_buff.size() < sizeof(app_data_file_binary_header) check failed while loading from " << filename);
|
||||
view::api_response ar;
|
||||
ar.error_code = API_RETURN_CODE_FAIL;
|
||||
ar.error_code = rsp_code;
|
||||
return MAKE_RESPONSE(ar);
|
||||
}
|
||||
|
||||
crypto::chacha_crypt(app_data_buff, pwd.pass);
|
||||
|
||||
const app_data_file_binary_header* phdr = reinterpret_cast<const app_data_file_binary_header*>(app_data_buff.data());
|
||||
if (phdr->m_signature != APP_DATA_FILE_BINARY_SIGNATURE)
|
||||
{
|
||||
LOG_ERROR("gui secure config: password missmatch while loading from " << filename);
|
||||
view::api_response ar;
|
||||
ar.error_code = API_RETURN_CODE_WRONG_PASSWORD;
|
||||
return MAKE_RESPONSE(ar);
|
||||
}
|
||||
|
||||
m_master_password = pwd.pass;
|
||||
|
||||
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
|
||||
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
|
||||
LOG_PRINT_L0("gui secure config loaded ok from " << filename << ", pass hash: " << master_password_hash);
|
||||
|
||||
return app_data_buff.substr(sizeof(app_data_file_binary_header)).c_str();
|
||||
return res_body.c_str();
|
||||
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
|
|
@ -1267,40 +1277,6 @@ QString MainWindow::get_app_data()
|
|||
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
QString MainWindow::store_secure_app_data(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
if (!tools::create_directories_if_necessary(m_backend.get_config_folder()))
|
||||
{
|
||||
view::api_response ar;
|
||||
LOG_PRINT_L0("Failed to create data directory: " << m_backend.get_config_folder());
|
||||
return MAKE_RESPONSE(ar);
|
||||
}
|
||||
|
||||
|
||||
std::string buff(sizeof(app_data_file_binary_header), 0);
|
||||
app_data_file_binary_header* phdr = (app_data_file_binary_header*)buff.data();
|
||||
phdr->m_signature = APP_DATA_FILE_BINARY_SIGNATURE;
|
||||
phdr->m_cb_body = 0; // for future use
|
||||
|
||||
buff.append(param.toStdString());
|
||||
crypto::chacha_crypt(buff, m_master_password);
|
||||
|
||||
bool r = file_io_utils::save_string_to_file(m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME, buff);
|
||||
view::api_response ar;
|
||||
if (r)
|
||||
ar.error_code = API_RETURN_CODE_OK;
|
||||
else
|
||||
ar.error_code = API_RETURN_CODE_FAIL;
|
||||
|
||||
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
|
||||
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
|
||||
LOG_PRINT_L0("store_secure_app_data, r = " << r << ", pass hash: " << master_password_hash);
|
||||
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
QString MainWindow::have_secure_app_data()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <QWebChannel>
|
||||
|
||||
#include "wallet/view_iface.h"
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include "wallet/wallets_manager.h"
|
||||
#include "currency_core/offers_services_helpers.h"
|
||||
|
|
@ -18,13 +19,7 @@ class QWebEngineView;
|
|||
class QLineEdit;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct app_data_file_binary_header
|
||||
{
|
||||
uint64_t m_signature;
|
||||
uint64_t m_cb_body;
|
||||
};
|
||||
#pragma pack (pop)
|
||||
|
||||
#define APP_DATA_FILE_BINARY_SIGNATURE 0x1000111101101021LL
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#include "string_tools.h"
|
||||
#include "currency_core/currency_format_utils.h"
|
||||
#include "wallets_manager.h"
|
||||
#include "common/base58.h"
|
||||
#include "common/config_encrypt_helper.h"
|
||||
|
||||
#define ANDROID_PACKAGE_NAME "com.zano_mobile"
|
||||
#ifdef IOS_BUILD
|
||||
|
|
@ -22,7 +24,9 @@
|
|||
#endif
|
||||
#define WALLETS_FOLDER_NAME "wallets"
|
||||
#define APP_CONFIG_FOLDER "app_config"
|
||||
#define APP_CONFIG_FILENAME "app_cfg.json"
|
||||
#define APP_CONFIG_FILENAME "app_cfg.bin"
|
||||
|
||||
#define MOBILE_APP_DATA_FILE_BINARY_SIGNATURE 0x1000111201101011LL //Bender's nightmare
|
||||
|
||||
#define GENERAL_INTERNAL_ERRROR_INSTANCE "GENERAL_INTERNAL_ERROR: WALLET INSTNACE NOT FOUND"
|
||||
#define GENERAL_INTERNAL_ERRROR_INIT "Failed to intialize library"
|
||||
|
|
@ -155,20 +159,27 @@ namespace plain_wallet
|
|||
return epee::serialization::store_t_to_json(ok_response);
|
||||
}
|
||||
|
||||
std::string get_appconfig()
|
||||
std::string get_appconfig(const std::string& encryption_key)
|
||||
{
|
||||
std::string res_str = "{}";
|
||||
std::string res_str;
|
||||
std::string app_config_config_path = get_app_config_folder() + APP_CONFIG_FILENAME;
|
||||
epee::file_io_utils::load_file_to_string(app_config_config_path, res_str);
|
||||
return res_str;
|
||||
}
|
||||
std::string set_appconfig(const std::string& conf_str)
|
||||
{
|
||||
std::string app_config_config_path = get_app_config_folder() + APP_CONFIG_FILENAME;
|
||||
if (!epee::file_io_utils::save_string_to_file(app_config_config_path, conf_str))
|
||||
std::string ret_code = tools::load_encrypted_file(app_config_config_path, encryption_key, res_str, MOBILE_APP_DATA_FILE_BINARY_SIGNATURE);
|
||||
if (ret_code != API_RETURN_CODE_OK)
|
||||
{
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = API_RETURN_CODE_NOT_FOUND;
|
||||
err_result.error.code = ret_code;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
}
|
||||
return res_str;
|
||||
}
|
||||
std::string set_appconfig(const std::string& conf_str, const std::string& encryption_key)
|
||||
{
|
||||
std::string app_config_config_path = get_app_config_folder() + APP_CONFIG_FILENAME;
|
||||
std::string ret_code = tools::store_encrypted_file(app_config_config_path, encryption_key, conf_str, MOBILE_APP_DATA_FILE_BINARY_SIGNATURE);
|
||||
if (ret_code != API_RETURN_CODE_OK)
|
||||
{
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = ret_code;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
}
|
||||
else
|
||||
|
|
@ -177,7 +188,14 @@ namespace plain_wallet
|
|||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
}
|
||||
}
|
||||
|
||||
std::string generate_random_key(uint64_t lenght)
|
||||
{
|
||||
std::string buff;
|
||||
buff.resize(lenght);
|
||||
crypto::generate_random_bytes(lenght, const_cast<char*>(buff.data()));
|
||||
return tools::base58::encode(buff);
|
||||
}
|
||||
|
||||
std::string get_logs_buffer()
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ namespace plain_wallet
|
|||
std::string get_version();
|
||||
std::string get_wallet_files();
|
||||
|
||||
std::string get_appconfig();
|
||||
std::string set_appconfig(const std::string& conf_str);
|
||||
std::string get_appconfig(const std::string& encryption_key);
|
||||
std::string set_appconfig(const std::string& conf_str, const std::string& encryption_key);
|
||||
std::string generate_random_key(uint64_t lenght);
|
||||
std::string get_logs_buffer();
|
||||
std::string truncate_log();
|
||||
|
||||
|
|
|
|||
|
|
@ -779,6 +779,7 @@ public:
|
|||
#define API_RETURN_CODE_CORE_BUSY "CORE_BUSY"
|
||||
#define API_RETURN_CODE_OVERFLOW "OVERFLOW"
|
||||
#define API_RETURN_CODE_BUSY "BUSY"
|
||||
#define API_RETURN_CODE_INVALID_FILE "INVALID_FILE"
|
||||
|
||||
#define API_MAX_ALIASES_COUNT 10000
|
||||
|
||||
|
|
|
|||
|
|
@ -461,8 +461,7 @@ bool core_concurrency_test(boost::program_options::variables_map& vm, size_t wth
|
|||
|
||||
test_protocol_handler protocol_handler(c, core_listener.get());
|
||||
c.set_currency_protocol(&protocol_handler);
|
||||
tools::db::db_backend_selector dbbs;
|
||||
if (!c.init(vm, dbbs))
|
||||
if (!c.init(vm))
|
||||
{
|
||||
LOG_ERROR("Failed to init core");
|
||||
return false;
|
||||
|
|
@ -528,8 +527,7 @@ bool core_concurrency_test(boost::program_options::variables_map& vm, size_t wth
|
|||
|
||||
test_protocol_handler protocol_handler(c, core_listener.get());
|
||||
c.set_currency_protocol(&protocol_handler);
|
||||
tools::db::db_backend_selector dbbs;
|
||||
if (!c.init(vm, dbbs))
|
||||
if (!c.init(vm))
|
||||
{
|
||||
LOG_ERROR("Failed to init core");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -32,9 +32,18 @@ void run_plain_wallet_api_test()
|
|||
LOG_PRINT_L0("Creating instance...");
|
||||
std::string s = plain_wallet::init("195.201.107.230", "11211", 1);
|
||||
|
||||
std::string fres = plain_wallet::get_logs_buffer();
|
||||
std::string fres2 = plain_wallet::truncate_log();
|
||||
std::string fres3 = plain_wallet::get_logs_buffer();
|
||||
std::string key = plain_wallet::generate_random_key(10);
|
||||
std::string test_data = "1234567890 test test ";
|
||||
std::string res = plain_wallet::set_appconfig(test_data, key);
|
||||
std::string test_data2 = plain_wallet::get_appconfig(key);
|
||||
if (test_data2 != test_data)
|
||||
{
|
||||
LOG_ERROR("Error");
|
||||
}
|
||||
return;
|
||||
//std::string fres = plain_wallet::get_logs_buffer();
|
||||
//std::string fres2 = plain_wallet::truncate_log();
|
||||
//std::string fres3 = plain_wallet::get_logs_buffer();
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue