@@ -15,22 +15,45 @@ namespace llarp
1515 {
1616 log::trace (logcat, " {} called" , __PRETTY_FUNCTION__);
1717
18- // TODO FIXME: do we want to allow hex or other non-binary encodings here?
19- auto tmp = util::file_to_string (fname, 64 );
20- if (tmp.size () != 64 )
21- throw std::invalid_argument{" Invalid key file {}: Expected 64 bytes, not {}" _format (fname, tmp.size ())};
18+ auto tmp = util::file_to_string (fname);
19+ if ((tmp.size () == 128 or (tmp.size () == 129 and tmp.ends_with (" \n " ))
20+ or (tmp.size () == 130 and tmp.ends_with (" \r\n " )))
21+ and oxenc::is_hex (tmp.begin (), tmp.begin () + 128 ))
22+ oxenc::from_hex (tmp.begin (), tmp.begin () + 128 , key.data ());
23+ else if (tmp.size () == 64 )
24+ std::memcpy (key.data (), tmp.data (), 64 );
25+ else if (tmp.starts_with (' d' ) and tmp.ends_with (' e' )) {
26+ // Old Lokinet keys were bt-dicts with the key we care about in the 's' key:
27+ oxenc::bt_dict_consumer old{tmp};
28+ auto oldkey = old.require_span <unsigned char , 64 >(" s" );
29+ std::memcpy (key.data (), oldkey.data (), 64 );
30+ old.finish ();
31+ }
32+ else
33+ throw std::invalid_argument{
34+ " Invalid key file {} ({}B): Expected 64 bytes, 128 hex, or legacy lokinet key file" _format (fname, tmp.size ())};
2235
23- std::memcpy (key.data (), tmp.data (), 64 );
2436 if (!key.check_pubkey ())
2537 throw std::invalid_argument{" Invalid key file {}: Keypair seed and pubkey do not match" };
2638 }
2739
28- bool KeyManager::write_to_file (const Ed25519SecretKey& key, const std::filesystem::path& fname)
40+ bool KeyManager::write_to_file (const Ed25519SecretKey& key, const std::filesystem::path& fname, bool hex )
2941 {
3042 log::trace (logcat, " {} called" , __PRETTY_FUNCTION__);
3143 try
3244 {
33- util::buffer_to_file (fname, key.to_view ());
45+ if (hex)
46+ {
47+ std::string out;
48+ out.reserve (129 );
49+ oxenc::to_hex (key.begin (), key.end (), std::back_inserter (out));
50+ out += ' \n ' ;
51+ util::buffer_to_file (fname, out);
52+ }
53+ else
54+ {
55+ util::buffer_to_file (fname, key.to_view ());
56+ }
3457 }
3558 catch (const std::exception& e)
3659 {
@@ -45,7 +68,7 @@ namespace llarp
4568 {
4669 if (not is_relay)
4770 {
48- if (config.network .keyfile )
71+ if (config.network .keyfile and std::filesystem::exists (*config. network . keyfile ) )
4972 {
5073 load_from_file (secret_key, *config.network .keyfile );
5174 log::info (logcat, " Successfully loaded persistent client key from config path" );
@@ -54,6 +77,12 @@ namespace llarp
5477 {
5578 log::debug (logcat, " Client generating secret key..." );
5679 secret_key = crypto::generate_ed25519 ();
80+
81+ if (config.network .keyfile && !write_to_file (secret_key, *config.network .keyfile ))
82+ {
83+ log::critical (logcat, " Failed to save persistent key to {}" , *config.network .keyfile );
84+ throw std::runtime_error{" Failed to save configured persistent key file" };
85+ }
5786 }
5887
5988 public_key.assign (secret_key.pubkey_span ());
0 commit comments