Skip to content

Commit

Permalink
Merge pull request #185 from edtubbs/0.1.3-dev-overwrite-prompt
Browse files Browse the repository at this point in the history
wallet: added prompt to dogecoin_wallet_load
  • Loading branch information
michilumin authored Jan 23, 2024
2 parents 78c63fc + 5db1a5e commit 3ec0148
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 54 deletions.
17 changes: 13 additions & 4 deletions doc/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The `such` tool can be used by simply running the command `./such` in the top le
- list_encryption_keys_in_tpm
- decrypt_master_key
- decrypt_mnemonic
- seed_to_master_key
- mnemonic_to_key
- mnemonic_to_addresses
- print_keys
Expand Down Expand Up @@ -47,10 +48,10 @@ Most of these commands require a flag following them to denote things like exist
| -o, --account_int | account_int | yes | mnemonic_to_key or mnemonic_to_addresses -n <seed_phrase> -o <account_int> |
| -g, --change_level | change_level | yes | mnemonic_to_key or mnemonic_to_addresses -n <seed_phrase> -g <change_level> |
| -i, --address_index | address_index | yes | mnemonic_to_key or mnemonic_to_addresses -n <seed_phrase> -i <address_index> |
| -y, --encrypted_file | file_num | yes | generate_mnemonic, bip32_extended_master_key, decrypt_master_key, decrypt_mnemonic, mnemonic_to_key or mnemonic_to_addresses -y <file_num>
| -y, --encrypted_file | file_num | yes | generate_mnemonic, bip32_extended_master_key, decrypt_master_key, decrypt_mnemonic, seed_to_master_key, mnemonic_to_key or mnemonic_to_addresses -y <file_num>
| -w, --overwrite | overwrite | no | generate_mnemonic or bip32_extended_master_key -w |
| -b, --silent | silent | no | generate_mnemonic or bip32_extended_master_key -b |
| -j, --use_tpm | use_tpm | no | generate_mnemonic, bip32_extended_master_key, decrypt_master_key, decrypt_mnemonic, mnemonic_to_key or mnemonic_to_addresses -j |
| -j, --use_tpm | use_tpm | no | generate_mnemonic, bip32_extended_master_key, decrypt_master_key, decrypt_mnemonic, seed_to_master_key, mnemonic_to_key or mnemonic_to_addresses -j |
| -t, --testnet | designate_testnet | no | generate_private_key -t |
| -s | script_hex | yes | comp2der -s <compact_signature> |
| -x | transaction_hex | yes | sign -x <transaction_hex> -s <pubkey_script> -i <index_of_utxo_to_sign> -h <sig_hash_type> |
Expand All @@ -71,6 +72,7 @@ Below is a list of all the commands and the flags that they require. As a remind
| list_encryption_keys_in_tpm | None | None | List the encryption keys in the TPM. |
| decrypt_master_key | -y | -j | Decrypt the master key with the TPM or SW. |
| decrypt_mnemonic | -y | -j | Decrypt the mnemonic with the TPM or SW. |
| seed_to_master_key | -y | -j, -t | Generates an extended master private key from a seed for either mainnet or testnet. |
| mnemonic_to_key | -n | -a, -y, -o, g, -i, -t | Generates a private key from a seed phrase with a default path or specified account, change level and index for either mainnet or testnet. |
| mnemonic_to_addresses | -n | -a, -y, -o, g, -i, -t | Generates an address from a seed phrase with a default path or specified account, change level and index for either mainnet or testnet. |
| print_keys | -p | -t | Print all keys associated with the provided private key.
Expand Down Expand Up @@ -172,9 +174,9 @@ Below are some examples on how to use the `such` tool in practice.
./such -c verifymessage -x bleh -s ICrbftD0KamyaB68IoXbeke3w4CpcIvv+Q4pncBNpMk8fF5+xsR9H9gqmfM0JrjlfzZZA3E8AJ0Nug1KWeoVw3g= -k D8mQ2sKYpLbFCQLhGeHCPBmkLJRi6kRoSg
Message is verified!

## Encrypted Mnemonics and Key Backups
## Encrypted Mnemonics, Key and Seed Backups

The `such` tool provides functionality to securely manage your encrypted mnemonics and key backups. With the ability to generate mnemonics and encrypt them for safe storage, and to decrypt them when needed, managing your cryptographic assets is made easier. To use encrypted files with `spvnode`, you must first use the `such` tool to generate and encrypt your mnemonic or master key. You can then use the `spvnode` tool to import the encrypted file and use it to connect to the network.
The `such` tool provides functionality to securely manage your encrypted mnemonics, key and seed backups. With the ability to generate mnemonics and encrypt them for safe storage, and to decrypt them when needed, managing your cryptographic assets is made easier. To use encrypted files with `spvnode`, you must first use the `such` tool to generate and encrypt your mnemonic or master key. You can then use the `spvnode` tool to import the encrypted file and use it to connect to the network.

### Generating and Encrypting Mnemonics

Expand Down Expand Up @@ -218,6 +220,12 @@ And to decrypt it back when required:

Always ensure to replace `<file_num>` with the actual number of the encrypted file.

### Handling Seed Backups

You can also decrypt your seed backups using the `seed_to_master_key` command. This command will decrypt the seed and generate a master key from it. If the seed was encrypted using TPM (Trusted Platform Module), you can use the `-j` flag as shown:

./such -c seed_to_master_key -y <file_num> -j

### Overwriting Encrypted Files

If you want to overwrite an existing encrypted file, you can use the `-w` flag as shown:
Expand Down Expand Up @@ -361,6 +369,7 @@ To utilize checkpoints for faster initial sync, apply the -p flag:
| `-p`, `--checkpoint` | Checkpoint | No | Enable checkpoint sync: `./spvnode -p scan` |
| `-w`, `--wallet_file` | Wallet File | Yes | Specify wallet file: `./spvnode -w "./wallet.db" scan` |
| `-h`, `--headers_file` | Headers File | Yes | Specify headers DB file: `./spvnode -h "./headers.db" scan` |
| `-l`, `--no_prompt` | No Prompt | No | Load wallet and headers without prompt: `./spvnode -l scan` |
| `-y`, `--encrypted_file` | Encrypted File | Yes | Use encrypted file: `./spvnode -y 0 scan` |
| `-j`, `--use_tpm` | Use TPM | No | Utilize TPM for decryption: `./spvnode -j scan` |
| `-k`, `--master_key` | Master Key | No | Use master key decryption: `./spvnode -k scan` |
Expand Down
2 changes: 1 addition & 1 deletion include/dogecoin/headersdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ typedef struct dogecoin_headers_db_interface_
{
void* (*init)(const dogecoin_chainparams* chainparams, dogecoin_bool inmem_only);
void (*free)(void *db);
dogecoin_bool (*load)(void *db, const char *filename);
dogecoin_bool (*load)(void *db, const char *filename, dogecoin_bool prompt);
void (*fill_blocklocator_tip)(void* db, vector *blocklocators);
dogecoin_blockindex *(*connect_hdr)(void* db, struct const_buffer *buf, dogecoin_bool load_process, dogecoin_bool *connected);
dogecoin_blockindex* (*getchaintip)(void *db);
Expand Down
4 changes: 2 additions & 2 deletions include/dogecoin/headersdb_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ typedef struct dogecoin_headers_db_

dogecoin_headers_db *dogecoin_headers_db_new(const dogecoin_chainparams* chainparams, dogecoin_bool inmem_only);
void dogecoin_headers_db_free(dogecoin_headers_db *db);
dogecoin_bool dogecoin_headers_db_load(dogecoin_headers_db* db, const char *filename);
dogecoin_bool dogecoin_headers_db_load(dogecoin_headers_db* db, const char *filename, dogecoin_bool prompt);
dogecoin_blockindex * dogecoin_headers_db_connect_hdr(dogecoin_headers_db* db, struct const_buffer *buf, dogecoin_bool load_process, dogecoin_bool *connected);
void dogecoin_headers_db_fill_block_locator(dogecoin_headers_db* db, vector *blocklocators);
dogecoin_blockindex * dogecoin_headersdb_find(dogecoin_headers_db* db, uint256 hash);
Expand All @@ -68,7 +68,7 @@ void dogecoin_headersdb_set_checkpoint_start(dogecoin_headers_db* db, uint256 ha
static const dogecoin_headers_db_interface dogecoin_headers_db_interface_file = {
(void* (*)(const dogecoin_chainparams*, dogecoin_bool))dogecoin_headers_db_new,
(void (*)(void *))dogecoin_headers_db_free,
(dogecoin_bool (*)(void *, const char *))dogecoin_headers_db_load,
(dogecoin_bool (*)(void *, const char *, dogecoin_bool))dogecoin_headers_db_load,
(void (*)(void* , vector *))dogecoin_headers_db_fill_block_locator,
(dogecoin_blockindex *(*)(void* , struct const_buffer *, dogecoin_bool , dogecoin_bool *))dogecoin_headers_db_connect_hdr,
(dogecoin_blockindex* (*)(void *))dogecoin_headersdb_getchaintip,
Expand Down
2 changes: 1 addition & 1 deletion include/dogecoin/spv.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ typedef struct dogecoin_spv_client_

LIBDOGECOIN_API dogecoin_spv_client* dogecoin_spv_client_new(const dogecoin_chainparams *params, dogecoin_bool debug, dogecoin_bool headers_memonly, dogecoin_bool use_checkpoints, dogecoin_bool full_sync);
LIBDOGECOIN_API void dogecoin_spv_client_free(dogecoin_spv_client *client);
LIBDOGECOIN_API dogecoin_bool dogecoin_spv_client_load(dogecoin_spv_client *client, const char *file_path);
LIBDOGECOIN_API dogecoin_bool dogecoin_spv_client_load(dogecoin_spv_client *client, const char *file_path, dogecoin_bool prompt);
LIBDOGECOIN_API void dogecoin_spv_client_discover_peers(dogecoin_spv_client *client, const char *ips);
LIBDOGECOIN_API void dogecoin_spv_client_runloop(dogecoin_spv_client *client);
LIBDOGECOIN_API dogecoin_bool dogecoin_net_spv_request_headers(dogecoin_spv_client *client);
Expand Down
4 changes: 2 additions & 2 deletions include/dogecoin/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ LIBDOGECOIN_API void dogecoin_wallet_output_free(dogecoin_output* output);
/** ------------------------------------ */

LIBDOGECOIN_API dogecoin_wallet* dogecoin_wallet_new(const dogecoin_chainparams *params);
LIBDOGECOIN_API dogecoin_wallet* dogecoin_wallet_init(const dogecoin_chainparams* chain, const char* address, const char* name, const char* mnemonic_in, const char* pass, const dogecoin_bool encrypted, const dogecoin_bool tpm, const int file_num, const dogecoin_bool master_key);
LIBDOGECOIN_API dogecoin_wallet* dogecoin_wallet_init(const dogecoin_chainparams* chain, const char* address, const char* name, const char* mnemonic_in, const char* pass, const dogecoin_bool encrypted, const dogecoin_bool tpm, const int file_num, const dogecoin_bool master_key, const dogecoin_bool prompt);
LIBDOGECOIN_API void print_utxos(dogecoin_wallet* wallet);
LIBDOGECOIN_API void dogecoin_wallet_free(dogecoin_wallet* wallet);

/** load the wallet, sets masterkey, sets next_childindex */
LIBDOGECOIN_API dogecoin_bool dogecoin_wallet_load(dogecoin_wallet* wallet, const char* file_path, int *error, dogecoin_bool *created);
LIBDOGECOIN_API dogecoin_bool dogecoin_wallet_load(dogecoin_wallet* wallet, const char* file_path, int *error, dogecoin_bool *created, dogecoin_bool prompt);

/** load the wallet and replace a record */
LIBDOGECOIN_API dogecoin_bool dogecoin_wallet_replace(dogecoin_wallet* wallet, const char* file_path, cstring* record, uint8_t record_type, int *error);
Expand Down
33 changes: 26 additions & 7 deletions src/cli/spvnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#endif

#include <inttypes.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -179,6 +180,7 @@ static struct option long_options[] = {
{"checkpoint", no_argument, NULL, 'p'},
{"wallet_file", required_argument, NULL, 'w'},
{"headers_file", required_argument, NULL, 'h'},
{"no_prompt", no_argument, NULL, 'l'},
{"encrypted_file", required_argument, NULL, 'y'},
{"use_tpm", no_argument, NULL, 'j'},
{"master_key", no_argument, NULL, 'k'},
Expand All @@ -199,7 +201,7 @@ static void print_usage() {
print_version();
printf("Usage: spvnode (-c|continuous) (-i|-ips <ip,ip,...]>) (-m[--maxpeers] <int>) (-f <headersfile|0 for in mem only>) \
(-a[--address] <address>) (-n|-mnemonic <seed_phrase>) (-s|-pass_phrase) (-y|-encrypted_file <file_num 0-999>) \
(-w|-wallet_file <filename>) (-h|-headers_file <filename>) (-b[--full_sync]) (-p[--checkpoint]) (-k[--master_key] (-j[--use_tpm]) \
(-w|-wallet_file <filename>) (-h|-headers_file <filename>) (-l|[--no_prompt]) (-b[--full_sync]) (-p[--checkpoint]) (-k[--master_key] (-j[--use_tpm]) \
(-t[--testnet]) (-r[--regtest]) (-d[--debug]) <command>\n");
printf("Supported commands:\n");
printf(" scan (scan blocks up to the tip, creates header.db file)\n");
Expand Down Expand Up @@ -273,6 +275,16 @@ void spv_sync_completed(dogecoin_spv_client* client) {
}
}

// Signal handler for SIGINT
void handle_sigint() {
// Reset standard input back to blocking mode
#ifndef _WIN32
int stdin_flags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, stdin_flags & ~O_NONBLOCK);
#endif
exit(0);
}

int main(int argc, char* argv[]) {
int ret = 0;
int long_index = 0;
Expand All @@ -290,6 +302,7 @@ int main(int argc, char* argv[]) {
char* headers_name = 0;
dogecoin_bool full_sync = false;
dogecoin_bool have_decl_daemon = false;
dogecoin_bool prompt = true;
dogecoin_bool encrypted = false;
dogecoin_bool master_key = false;
dogecoin_bool tpm = false;
Expand All @@ -303,7 +316,7 @@ int main(int argc, char* argv[]) {
data = argv[argc - 1];

/* get arguments */
while ((opt = getopt_long_only(argc, argv, "i:ctrdsm:n:f:y:w:h:a:bpzkj:", long_options, &long_index)) != -1) {
while ((opt = getopt_long_only(argc, argv, "i:ctrdsm:n:f:y:w:h:a:lbpzkj:", long_options, &long_index)) != -1) {
switch (opt) {
case 'c':
quit_when_synced = false;
Expand Down Expand Up @@ -341,6 +354,9 @@ int main(int argc, char* argv[]) {
case 'h':
headers_name = optarg;
break;
case 'l':
prompt = false;
break;
case 'y':
encrypted = true;
file_num = (int)strtol(optarg, (char**)NULL, 10);
Expand Down Expand Up @@ -372,16 +388,19 @@ int main(int argc, char* argv[]) {
dogecoin_spv_client* client = dogecoin_spv_client_new(chain, debug, (dbfile && (dbfile[0] == '0' || (strlen(dbfile) > 1 && dbfile[0] == 'n' && dbfile[0] == 'o'))) ? true : false, use_checkpoint, full_sync);
client->header_message_processed = spv_header_message_processed;
client->sync_completed = spv_sync_completed;
signal(SIGINT, handle_sigint);

#if WITH_WALLET
dogecoin_wallet* wallet = dogecoin_wallet_init(chain, address, name, mnemonic_in, pass, encrypted, tpm, file_num, master_key);
dogecoin_wallet* wallet = dogecoin_wallet_init(chain, address, name, mnemonic_in, pass, encrypted, tpm, file_num, master_key, prompt);
if (!wallet) {
printf("Could not initialize wallet...\n");
// clear and free the passphrase
if (pass) {
dogecoin_mem_zero (pass, strlen(pass));
dogecoin_free(pass);
}
dogecoin_spv_client_free(client);
dogecoin_ecc_stop();
return EXIT_FAILURE;
}
// clear and free the passphrase
Expand All @@ -405,19 +424,19 @@ int main(int argc, char* argv[]) {
dogecoin_free(header_type_prefix);
if (headers_name) {
// Load headers file name with headers name:
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headers_name));
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headers_name), prompt);
} else {
// Otherwise, use default headers file name:
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headersfile));
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headersfile), prompt);
}
}
else if (headers_name) {
// Load headers file name with headers name:
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headers_name));
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headers_name), prompt);
} else {
// Otherwise, use default headers file name:
headersfile = concat(header_prefix, header_suffix);
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headersfile));
response = dogecoin_spv_client_load(client, (dbfile ? dbfile : headersfile), prompt);
}

dogecoin_free(headersfile);
Expand Down
46 changes: 46 additions & 0 deletions src/cli/such.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ static void print_usage()
printf("list_encryption_keys_in_tpm,\n");
printf("decrypt_master_key (requires -y <file_num>, -j (use_tpm) optional),\n");
printf("decrypt_mnemonic (requires -y <file_num>, -j (use_tpm) optional),\n");
printf("seed_to_master_key (-y <file_num>, -j (use_tpm) optional),\n");
printf("mnemonic_to_key (requires -n <seed_phrase> or -y <file_num>, -j (use_tpm), -o <account_int>, -g <change_level>, -i <address_index> and -a, all optional),\n");
printf("mnemonic_to_addresses (requires -n <seed_phrase> or -y <file_num>, -j (use_tpm), -o <account_int>, -g <change_level>, -i <address_index> and -a, all optional),\n");
printf("print_keys (requires -p <private key hex>),\n");
Expand Down Expand Up @@ -688,6 +689,7 @@ int main(int argc, char* argv[])
char* pass = 0;
char* entropy = 0;
MNEMONIC mnemonic = {0};
SEED seed = {0};
dogecoin_bool tpm = false;
dogecoin_bool encrypted = false;
dogecoin_bool overwrite = false;
Expand Down Expand Up @@ -1292,6 +1294,50 @@ int main(int argc, char* argv[])
return showError("decrypt_mnemonic (requires -y <file_num>, -j (use_tpm) optional\n");
}
}
else if (strcmp(cmd, "seed_to_master_key") == 0) { /* Creating a bip32 master key from a seed. */

/* if tpm is enabled, get seed from tpm */
if (encrypted) {
printf("Decrypt seed for master key? Y/N\n");

char buffer[MAX_LEN];
/* get user input */
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
if (buffer[0] != 'Y' && buffer[0] != 'y') {

/* if not confirmed, abort */
printf("aborted\n");
dogecoin_ecc_stop();
return 1;
}
}

if (tpm) {
/* get seed from tpm */
if (!dogecoin_decrypt_seed_with_tpm (seed, file_num)) {
printf("seed_to_master_key (requires -y <file_num>, -j (use_tpm) optional),\n");
return showError("failed to decrypt seed with tpm\n");
}
}

else {
/* get seed from software */
if (dogecoin_decrypt_seed_with_sw (seed, file_num, NULL) == false) {
printf("seed_to_master_key (requires -y <file_num>, -j (use_tpm) optional),\n");
return showError("failed to decrypt seed with software\n");
}
}
}

/* print master key from seed */
dogecoin_hdnode node;
char masterkey[HDKEYLEN];
dogecoin_hdnode_from_seed(seed, sizeof(seed), &node);
dogecoin_hdnode_serialize_private(&node, chain, masterkey, sizeof(masterkey));
printf("bip32 extended master key: %s\n", masterkey);
dogecoin_mem_zero(masterkey, strlen(masterkey));
dogecoin_mem_zero(seed, sizeof(seed));
}
else if (strcmp(cmd, "mnemonic_to_key") == 0) { /* Creating a bip32 master key from a mnemonic. */

/* if tpm is enabled, get mnemonic from tpm */
Expand Down
Loading

0 comments on commit 3ec0148

Please sign in to comment.