19#include <boost/range/adaptor/map.hpp>
20#include <boost/range/algorithm/copy.hpp>
23# include <sys/types.h>
29namespace sysio {
namespace wallet {
36 std::string sequence_string = std::to_string(sequence_number);
44 void enable_umask_protection() {
46 _old_umask = umask( S_IRWXG | S_IRWXO );
50 void disable_umask_protection() {
90 wlog(
"backing up wallet ${src} to ${dest}",
92 (
"dest", dest_path) );
97 enable_umask_protection();
101 disable_umask_protection();
105 disable_umask_protection();
120 auto it =
_keys.find(
id);
121 if( it !=
_keys.end() )
123 return std::optional<private_key_type>();
128 if( it ==
_keys.end() )
129 return std::optional<signature_type>();
130 return it->second.sign(
digest);
136 SYS_ASSERT( has_key, chain::key_nonexistent_exception,
"Key doesn't exist!" );
150 auto itr =
_keys.find(wif_pub_key);
151 if( itr ==
_keys.end() ) {
152 _keys[wif_pub_key] = priv;
155 SYS_THROW( chain::key_exist_exception,
"Key already in wallet" );
165 if( itr !=
_keys.end() ) {
169 SYS_THROW( chain::key_nonexistent_exception,
"Key not in wallet" );
183 SYS_THROW(chain::unsupported_key_type_exception,
"Key type \"${kt}\" not supported by software wallet", (
"kt",
key_type));
193 if( wallet_filename ==
"" )
215 if( wallet_filename ==
"" )
218 wlog(
"saving wallet to file ${fn}", (
"fn", wallet_filename) );
223 enable_umask_protection();
230 ofstream outfile{ wallet_filename };
232 elog(
"Unable to open file: ${fn}", (
"fn", wallet_filename));
233 SYS_THROW(wallet_exception,
"Unable to open file: ${fn}", (
"fn", wallet_filename));
235 outfile.write( data.c_str(), data.length() );
238 disable_umask_protection();
242 disable_umask_protection();
250 map<public_key_type,private_key_type>
_keys;
264namespace sysio {
namespace wallet {
267 : my(new
detail::soft_wallet_impl(*this, initial_data))
274 return my->copy_wallet_file(destination_filename);
279 return my->get_wallet_filename();
284 SYS_ASSERT(!
is_locked(), wallet_locked_exception,
"Unable to import key on a locked wallet");
286 if(
my->import_key(wif_key) )
296 SYS_ASSERT(!
is_locked(), wallet_locked_exception,
"Unable to remove key from a locked wallet");
298 if(
my->remove_key(key) )
308 SYS_ASSERT(!
is_locked(), wallet_locked_exception,
"Unable to create key on a locked wallet");
317 return my->load_wallet_file( wallet_filename );
322 my->save_wallet_file( wallet_filename );
327 return my->is_locked();
332 return my->_wallet.cipher_keys.size() == 0;
344 for(
auto key :
my->_keys )
358 my->_keys = std::move(pk.keys);
359 my->_checksum = pk.checksum;
361 "Invalid password for wallet: \"${wallet_name}\"", (
"wallet_name",
get_wallet_filename())) }
371 "Invalid password for wallet: \"${wallet_name}\"", (
"wallet_name",
get_wallet_filename())) }
376 SYS_ASSERT( !
is_locked(), wallet_locked_exception,
"The wallet must be unlocked before the password can be set" );
383 SYS_ASSERT(!
is_locked(), wallet_locked_exception,
"Unable to list public keys of a locked wallet");
388 SYS_ASSERT(!
is_locked(), wallet_locked_exception,
"Unable to list private keys of a locked wallet");
389 flat_set<public_key_type> keys;
390 boost::copy(
my->_keys | boost::adaptors::map_keys, std::inserter(keys, keys.end()));
396 return my->get_private_key(
pubkey );
404 auto seed = account + role +
password;
405 SYS_ASSERT( seed.size(), wallet_exception,
"seed should not be empty" );
408 return std::make_pair( priv.get_public_key(), priv );
413 my->_wallet_filename = wallet_filename;
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
#define SYS_RETHROW_EXCEPTIONS(exception_type, FORMAT,...)
std::string to_string(const fc::yield_function_t &yield=fc::yield_function_t()) const
static private_key generate()
public_key get_public_key() const
static private_key regenerate(const typename KeyType::data_type &data)
std::string to_string(const fc::yield_function_t &yield=fc::yield_function_t()) const
contains only the public point of an elliptic curve key.
static variant from_file(const fc::path &p, const parse_type ptype=parse_type::legacy_parser, const uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
static string to_pretty_string(const variant &v, const yield_function_t &yield, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
wraps boost::filesystem::path to provide platform independent path manipulation.
fc::path parent_path() const
static sha256 hash(const char *d, uint32_t dlen)
static sha512 hash(const char *d, uint32_t dlen)
bool import_key(string wif_key)
void save_wallet_file(string wallet_filename="")
soft_wallet_impl(soft_wallet &s, const wallet_data &initial_data)
map< public_key_type, private_key_type > _keys
virtual ~soft_wallet_impl()
private_key_type get_private_key(const public_key_type &id) const
string get_wallet_filename() const
bool copy_wallet_file(string destination_filename)
bool remove_key(string key)
const string _wallet_filename_extension
bool load_wallet_file(string wallet_filename="")
string create_key(string key_type)
std::optional< private_key_type > try_get_private_key(const public_key_type &id) const
const string _default_key_type
std::optional< signature_type > try_sign_digest(const digest_type digest, const public_key_type public_key)
void set_wallet_filename(string wallet_filename)
void unlock(string password) override
bool is_locked() const override
map< public_key_type, private_key_type > list_keys() override
private_key_type get_private_key(public_key_type pubkey) const override
std::shared_ptr< detail::soft_wallet_impl > my
string get_wallet_filename() const
bool load_wallet_file(string wallet_filename="")
soft_wallet(const wallet_data &initial_data)
void check_password(string password) override
string create_key(string key_type) override
pair< public_key_type, private_key_type > get_private_key_from_password(string account, string role, string password) const
void set_password(string password) override
flat_set< public_key_type > list_public_keys() override
bool import_key(string wif_key) override
bool copy_wallet_file(string destination_filename)
std::optional< signature_type > try_sign_digest(const digest_type digest, const public_key_type public_key) override
void save_wallet_file(string wallet_filename="")
bool remove_key(string key) override
#define FC_CAPTURE_AND_RETHROW(...)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
void unpack(Stream &s, std::deque< T > &value)
void pack(Stream &s, const std::deque< T > &value)
fc::sha256 digest(const T &value)
unsigned aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
bool exists(const path &p)
unsigned aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
void create_directories(const path &p)
void copy(const path &from, const path &to)
path absolute(const path &p)
fc::crypto::private_key private_key_type
private_key_type derive_private_key(const std::string &prefix_string, int sequence_number)
map< public_key_type, private_key_type > keys
vector< char > cipher_keys