Skip to content

Commit 62589ff

Browse files
add checks to backup/restore
1 parent 4f9c092 commit 62589ff

File tree

5 files changed

+211
-27
lines changed

5 files changed

+211
-27
lines changed

keychain_lib/include/keychain_lib/keychain_commands.hpp

Lines changed: 105 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
#include "version_info.hpp"
5656
#include <arpa/inet.h>
57-
57+
#include "keydata_singleton.hpp"
5858

5959
#ifdef __linux__
6060
# define KEY_DEFAULT_PATH "/var/keychain"
@@ -241,7 +241,7 @@ enum struct command_te {
241241
version,
242242
sign_trx,
243243
sign_hash,
244-
// create,
244+
create,
245245
select_key,
246246
import_cmd,
247247
export_cmd,
@@ -252,6 +252,7 @@ enum struct command_te {
252252
list,
253253
public_key,
254254
set_unlock_time,
255+
backup,
255256
last
256257
};
257258

@@ -830,11 +831,41 @@ struct keychain_command<command_te::seed>: keychain_command_base
830831
{
831832
keychain_command(): keychain_command_base(command_te::seed){}
832833
virtual ~keychain_command(){}
833-
struct params {std::string entropy;};
834-
using params_t = params;
835834
virtual std::string operator()(keychain_base* keychain, const fc_light::variant& params_variant, int id) const override
836835
{
837836
FC_LIGHT_THROW_EXCEPTION(fc_light::command_depreciated, "");
837+
838+
/*
839+
dev::bytes ue;
840+
auto seed = keydata::seed(ue);
841+
std::string filename ("/var/keychain/seed");
842+
std::ofstream file(filename);
843+
if (!file.is_open())
844+
FC_LIGHT_THROW_EXCEPTION(fc_light::internal_error_exception, filename);
845+
file << seed << std::endl;
846+
847+
std::string pass("blank");
848+
auto res = keydata::derive_masterkey(seed, pass);
849+
if (res)
850+
{
851+
keydata::create_t params;
852+
try
853+
{
854+
params = params_variant.as<keydata::create_t>();
855+
}
856+
FC_LIGHT_CAPTURE_TYPECHANGE_AND_RETHROW (fc_light::invalid_arg_exception, error, "cannot parse command params")
857+
auto json = fc_light::json::to_string(params);
858+
keydata::derive_key(pass, json);
859+
json_response response(seed.c_str(), 0);
860+
return fc_light::json::to_string(response);
861+
}
862+
else
863+
{
864+
json_response response("error to derive master_key", 0);
865+
return fc_light::json::to_string(response);
866+
}
867+
*/
868+
838869
}
839870
};
840871

@@ -844,11 +875,76 @@ struct keychain_command<command_te::restore>: keychain_command_base
844875
{
845876
keychain_command(): keychain_command_base(command_te::restore){}
846877
virtual ~keychain_command(){}
847-
struct params {std::string seed;};
878+
struct params {std::string filename; std::string seed;};
848879
using params_t = params;
849880
virtual std::string operator()(keychain_base* keychain, const fc_light::variant& params_variant, int id) const override
850881
{
851882
FC_LIGHT_THROW_EXCEPTION(fc_light::command_depreciated, "");
883+
/*
884+
params_t params;
885+
try
886+
{
887+
params = params_variant.as<params_t>();
888+
}
889+
FC_LIGHT_CAPTURE_TYPECHANGE_AND_RETHROW (fc_light::invalid_arg_exception, error, "cannot parse command params")
890+
std::string pass("blank");
891+
auto count = keydata::restore(params.filename.c_str(), params.seed, pass);
892+
893+
json_response response(std::to_string(count)+" keys are restored", 0);
894+
return fc_light::json::to_string(response);
895+
*/
896+
}
897+
};
898+
899+
900+
template<>
901+
struct keychain_command<command_te::backup>: keychain_command_base
902+
{
903+
keychain_command(): keychain_command_base(command_te::backup){}
904+
virtual ~keychain_command(){}
905+
struct params {std::string filename;};
906+
using params_t = params;
907+
virtual std::string operator()(keychain_base* keychain, const fc_light::variant& params_variant, int id) const override
908+
{
909+
FC_LIGHT_THROW_EXCEPTION(fc_light::command_depreciated, "");
910+
/*
911+
params_t params;
912+
try
913+
{
914+
params = params_variant.as<params_t>();
915+
}
916+
FC_LIGHT_CAPTURE_TYPECHANGE_AND_RETHROW (fc_light::invalid_arg_exception, error, "cannot parse command params")
917+
auto count = keydata::backup(params.filename.c_str());
918+
919+
json_response response("backup "+std::to_string(count)+" keys", 0);
920+
return fc_light::json::to_string(response);
921+
*/
922+
}
923+
};
924+
925+
926+
template<>
927+
struct keychain_command<command_te::create>: keychain_command_base
928+
{
929+
keychain_command(): keychain_command_base(command_te::create){}
930+
virtual ~keychain_command(){}
931+
virtual std::string operator()(keychain_base* keychain, const fc_light::variant& params_variant, int id) const override
932+
{
933+
FC_LIGHT_THROW_EXCEPTION(fc_light::command_depreciated, "");
934+
/*
935+
keydata::create_t params;
936+
try
937+
{
938+
params = params_variant.as<keydata::create_t>();
939+
}
940+
FC_LIGHT_CAPTURE_TYPECHANGE_AND_RETHROW (fc_light::invalid_arg_exception, error, "cannot parse command params")
941+
std::string pass = "blank";
942+
auto json = fc_light::json::to_string(params);
943+
auto res = keydata::derive_key(pass, json);
944+
945+
json_response response(res?"done":"error", 0);
946+
return fc_light::json::to_string(response);
947+
*/
852948
}
853949
};
854950

@@ -939,7 +1035,7 @@ FC_LIGHT_REFLECT_ENUM(
9391035
(version)
9401036
(sign_trx)
9411037
(sign_hash)
942-
// (create)
1038+
// (create)
9431039
(select_key)
9441040
(import_cmd)
9451041
(export_cmd)
@@ -950,6 +1046,7 @@ FC_LIGHT_REFLECT_ENUM(
9501046
(list)
9511047
(public_key)
9521048
(set_unlock_time)
1049+
(backup)
9531050
(last)
9541051
)
9551052

@@ -959,8 +1056,8 @@ FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::sign_h
9591056
FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::public_key>::params_t, (keyname))
9601057
FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::set_unlock_time>::params_t, (seconds))
9611058
FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::unlock>::params_t, (public_key)(unlock_time))
962-
FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::seed>::params_t, (entropy))
963-
FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::restore>::params_t, (seed))
1059+
FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::backup>::params_t, (filename))
1060+
FC_LIGHT_REFLECT(keychain_app::keychain_command<keychain_app::command_te::restore>::params_t, (filename) (seed))
9641061
FC_LIGHT_REFLECT(keychain_app::keychain_command_common, (command)(id)(params))
9651062
FC_LIGHT_REFLECT(keychain_app::json_response, (id)(result))
9661063
FC_LIGHT_REFLECT(keychain_app::json_error::error_t, (code)(name)(message)(trace))

keychain_lib/include/keychain_lib/keydata_singleton.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ namespace keydata
2222
{
2323

2424
std::string seed(dev::bytes& );
25-
void derive_masterkey(std::string&, std::string&);
26-
void derive_key(std::string&, std::string& );
27-
void restore(const char *, std::string&, std::string& );
28-
void backup(const char * );
25+
bool derive_masterkey(std::string&, std::string&);
26+
bool derive_key(std::string&, std::string& );
27+
int restore(const char *, std::string&, std::string& );
28+
int backup(const char * );
2929
std::pair<dev::Secret, dev::bytes> get_master_key(get_password_create_f&& );
3030
std::vector<char> pbkdf2(std::string const& _pass);
3131

keychain_lib/include/keychain_lib/keyfile_singleton.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,13 @@ class keyfile_singleton
184184
void update(keyfile_format::keyfile_t&& keyfile);
185185

186186
bool is_exist(const prim_key_type& key) const;
187+
bool is_exist(const second_key_type& key);
187188
void flush_keyfile(const prim_key_type& key) const;
188189
void flush_keyfile(const second_key_type& key) const;
189190
// void flush_logrecords(const prim_key_type& key) const;
190191
void flush_all() const;
192+
int count(const keyfile_singleton::second_key_type& );
193+
191194

192195
};
193196

keychain_lib/src/keydata_singleton.cpp

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,24 @@ std::vector<char> keydata::pbkdf2(std::string const& _pass)
8484
}
8585

8686

87-
void keydata::derive_masterkey(std::string& mnemonics, std::string& pass)
87+
bool keydata::derive_masterkey(std::string& mnemonics, std::string& pass)
8888
{
89+
auto& log = logger_singleton::instance();
90+
auto& keyfiles = keyfile_singleton::instance();
91+
if (keyfiles.is_exist("master_key"))
92+
{
93+
BOOST_LOG_SEV(log.lg, info) << "error create master_key: master_key already exist";
94+
return false;
95+
}
96+
8997
std::regex re(" +");
9098
std::string mnemonics_ = std::regex_replace(mnemonics, re, "");
9199

92100
std::vector<char> key = std::move(pbkdf2(mnemonics_));
93101
dev::bytes priv_key(key.begin(), key.begin()+32);
94102
dev::bytes chain_code(key.begin()+32, key.end());
95103

96-
auto & keyfiles = keyfile_singleton::instance();
97-
keyfiles.create(std::bind(create_new_keyfile,
104+
auto res = keyfiles.create(std::bind(create_new_keyfile,
98105
"master_key", "master_key", true, keyfile_format::cipher_etype::aes256,
99106
keyfile_format::curve_etype::secp256k1,
100107
[&pass](const std::string& keyname)->byte_seq_t{
@@ -105,14 +112,32 @@ void keydata::derive_masterkey(std::string& mnemonics, std::string& pass)
105112
priv_key,
106113
chain_code
107114
));
108-
auto& log = logger_singleton::instance();
109-
BOOST_LOG_SEV(log.lg, info) << "create master key";
115+
if (res)
116+
BOOST_LOG_SEV(log.lg, info) << "create master key";
117+
else
118+
BOOST_LOG_SEV(log.lg, info) << "error to create master key";
119+
120+
return res;
110121
}
111122

112-
void keydata::derive_key(std::string& masterkey_pass, std::string& json)
123+
bool keydata::derive_key(std::string& masterkey_pass, std::string& json)
113124
{
114125
using namespace keydata;
115126
auto& log = logger_singleton::instance();
127+
bool res = false;
128+
129+
auto& keyfiles = keyfile_singleton::instance();
130+
auto count = keyfiles.count("master_key");
131+
if (count >1)
132+
{
133+
{BOOST_LOG_SEV(log.lg, info) << "error derive keys: master key is not the only one" ;}
134+
return false;
135+
}
136+
else if (count <1)
137+
{
138+
{BOOST_LOG_SEV(log.lg, info) << "error derive keys: master key not found" ;}
139+
return false;
140+
}
116141

117142
auto password = [&masterkey_pass](const std::string& keyname)->byte_seq_t{
118143
byte_seq_t res;
@@ -130,10 +155,14 @@ void keydata::derive_key(std::string& masterkey_pass, std::string& json)
130155
catch (const std::exception &e) {throw std::runtime_error(e.what());}
131156
catch (const fc_light::exception &e) {throw std::runtime_error(e.what());}
132157

158+
if (params_.keyname == "master_key")
159+
{
160+
BOOST_LOG_SEV(log.lg, info) << "keyname \"master_key\"is not may be used for private key";
161+
return false;
162+
}
133163

134164
FC_LIGHT_ASSERT(path.root == "m");
135165

136-
auto & keyfiles = keyfile_singleton::instance();
137166
auto secret = get_master_key(password);
138167
dev::bytes priv_key(secret.first.data(), secret.first.data()+32);
139168

@@ -153,7 +182,7 @@ void keydata::derive_key(std::string& masterkey_pass, std::string& json)
153182
}
154183
hd = hd.getChild(0x80000000|value);
155184
if (level == levels_te::address_index) {
156-
keyfiles.create(std::bind(create_new_keyfile,
185+
res = keyfiles.create(std::bind(create_new_keyfile,
157186
params_.keyname, params_.description, params_.encrypted,
158187
params_.cipher, params_.curve,
159188
password,
@@ -164,9 +193,13 @@ void keydata::derive_key(std::string& masterkey_pass, std::string& json)
164193
backup_t backup(params_.keyname, params_.path);
165194
sql.insert_path(backup);
166195
auto json = fc_light::json::to_string(backup);
167-
BOOST_LOG_SEV(log.lg, info) << "derive key: " << json;
196+
if (res)
197+
{BOOST_LOG_SEV(log.lg, info) << "derive key: " << json;}
198+
else
199+
{BOOST_LOG_SEV(log.lg, info) << "error to derive key: " << json;}
168200
}
169201
});
202+
return res;
170203
}
171204

172205

@@ -209,16 +242,24 @@ std::pair<dev::Secret, dev::bytes> keydata::get_master_key( get_password_create_
209242
}
210243

211244

212-
void keydata::restore(const char * filename, std::string& mnemonics, std::string& masterkey_pass)
245+
int keydata::restore(const char * filename, std::string& mnemonics, std::string& masterkey_pass)
213246
{
214247
using namespace keydata;
215248

249+
auto& log = logger_singleton::instance();
250+
auto& keyfiles = keyfile_singleton::instance();
251+
if (keyfiles.is_exist("master_key"))
252+
{
253+
BOOST_LOG_SEV(log.lg, info) << "error restore: master_key already exist";
254+
return false;
255+
}
256+
257+
int count = 0;
216258
auto file = std::ifstream(filename);
217259
if(!file.is_open())
218260
FC_LIGHT_THROW_EXCEPTION(fc_light::internal_error_exception,
219261
"Cannot open restore file ${filename}", ("filename", filename));
220262

221-
auto& log = logger_singleton::instance();
222263
BOOST_LOG_SEV(log.lg, info) << "restore keydata";
223264

224265
const int buf_size = 1000;
@@ -232,7 +273,12 @@ void keydata::restore(const char * filename, std::string& mnemonics, std::string
232273
BOOST_LOG_SEV(log.lg, info) << "restore path: " << json.back();
233274
}
234275

235-
derive_masterkey(mnemonics, masterkey_pass);
276+
auto res = derive_masterkey(mnemonics, masterkey_pass);
277+
if (!res)
278+
{
279+
BOOST_LOG_SEV(log.lg, info) << "restore error ";
280+
return count;
281+
}
236282

237283
for (auto &a: json)
238284
{
@@ -253,13 +299,16 @@ void keydata::restore(const char * filename, std::string& mnemonics, std::string
253299
params.path = backup.path;
254300

255301
auto params_json = fc_light::json::to_string(params);
256-
derive_key(masterkey_pass, params_json);
302+
if (derive_key(masterkey_pass, params_json))
303+
count++;
257304
}
305+
return count;
258306
}
259307

260308

261-
void keydata::backup(const char * filename)
309+
int keydata::backup(const char * filename)
262310
{
311+
int count = 0;
263312
auto file = std::ofstream(filename);
264313
if (!file.is_open())
265314
FC_LIGHT_THROW_EXCEPTION(fc_light::internal_error_exception, "Cannot open backup file (${filename})", ("filename", filename));
@@ -270,5 +319,13 @@ void keydata::backup(const char * filename)
270319
auto& sql = sql_singleton::instance();
271320
auto backup_list = std::move(sql.select_path());
272321
for (auto& a : backup_list)
273-
file << fc_light::json::to_string(a) << std::endl;
322+
{
323+
auto json = fc_light::json::to_string(a);
324+
BOOST_LOG_SEV(log.lg, info) << json;
325+
file << json << std::endl;
326+
count++;
327+
}
328+
BOOST_LOG_SEV(log.lg, info) << "backup "+std::to_string(count)+" keys";
329+
330+
return count;
274331
}

0 commit comments

Comments
 (0)