Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Software encrypt/decrypt with cli tools #163

Merged
merged 3 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ SET(WITH_LOGDB TRUE CACHE BOOL "enable logdb")
SET(WITH_UNISTRING TRUE CACHE BOOL "enable unistring functions")
SET(WITH_WALLET TRUE CACHE BOOL "enable wallet")
SET(USE_SSE2 FALSE CACHE BOOL "enable scrypt sse2")
SET(USE_TPM2 FALSE CACHE BOOL "enable tpm_tests")
SET(USE_TPM2 TRUE CACHE BOOL "enable tpm2")
SET(USE_OPENENCLAVE FALSE CACHE BOOL "enable openenclave")
SET(TEST_PASSWD FALSE CACHE BOOL "enable test password")
SET(RANDOM_DEVICE "/dev/urandom" CACHE STRING "set the device to read random data from")

# Set a default build type if none was specified
Expand Down Expand Up @@ -110,6 +111,9 @@ ENDIF()
IF(USE_OPENENCLAVE)
ADD_DEFINITIONS(-DUSE_OPENENCLAVE=1)
ENDIF()
IF(TEST_PASSWD)
ADD_DEFINITIONS(-DTEST_PASSWD=1)
ENDIF()

MESSAGE(STATUS "")
MESSAGE(STATUS "Options used to compile and link:")
Expand All @@ -122,6 +126,7 @@ MESSAGE(STATUS " WITH_WALLET = ${WITH_WALLET}")
MESSAGE(STATUS "")
MESSAGE(STATUS " USE_SSE2 = ${USE_SSE2}")
MESSAGE(STATUS " USE_TPM2 = ${USE_TPM2}")
MESSAGE(STATUS " TEST_PASSWD = ${TEST_PASSWD}")
MESSAGE(STATUS "")
MESSAGE(STATUS " openenclave = ${USE_OPENENCLAVE}")
MESSAGE(STATUS "")
Expand Down Expand Up @@ -268,7 +273,7 @@ IF(USE_TESTS)
test/utils_tests.c
test/vector_tests.c
)
IF (USE_TPM2)
IF (WIN32 AND USE_TPM2)
TARGET_LINK_LIBRARIES(tests ${LIBDOGECOIN_NAME} ${LIBUNISTRING} tbs ncrypt crypt32)
ELSE()
TARGET_LINK_LIBRARIES(tests ${LIBDOGECOIN_NAME} ${LIBUNISTRING})
Expand Down Expand Up @@ -324,7 +329,7 @@ IF(WITH_NET)
src/spv.c
)

IF(USE_TPM2)
IF(WIN32 AND USE_TPM2)
TARGET_LINK_LIBRARIES(${LIBDOGECOIN_NAME} ${LIBEVENT} ${LIBEVENT_PTHREADS} ${LIBUNISTRING} ncrypt crypt32)
ELSE()
TARGET_LINK_LIBRARIES(${LIBDOGECOIN_NAME} ${LIBEVENT} ${LIBEVENT_PTHREADS} ${LIBUNISTRING})
Expand All @@ -347,7 +352,7 @@ IF(WITH_TOOLS)

ADD_EXECUTABLE(such src/cli/such.c)
INSTALL(TARGETS such RUNTIME)
IF (USE_TPM2)
IF (WIN32 AND USE_TPM2)
TARGET_LINK_LIBRARIES(such ${LIBDOGECOIN_NAME} ${LIBUNISTRING} tbs ncrypt crypt32)
ELSE()
TARGET_LINK_LIBRARIES(such ${LIBDOGECOIN_NAME} ${LIBUNISTRING})
Expand All @@ -362,7 +367,7 @@ IF(WITH_TOOLS)
ADD_EXECUTABLE(spvnode src/cli/spvnode.c)
INSTALL(TARGETS spvnode RUNTIME)

IF (USE_TPM2)
IF (WIN32 AND USE_TPM2)
TARGET_LINK_LIBRARIES(spvnode ${LIBDOGECOIN_NAME} tbs ncrypt crypt32)
ELSE()
TARGET_LINK_LIBRARIES(spvnode ${LIBDOGECOIN_NAME})
Expand Down
11 changes: 11 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ AC_ARG_ENABLE(tests,
[use_tests=$enableval],
[use_tests=yes])

AC_ARG_ENABLE([test-passwd],
[AS_HELP_STRING([--enable-test-passwd],
[enable test password for encrypt/decrypt])],
[test_passwd=$enableval],
[test_passwd=yes])

AC_MSG_CHECKING([for __builtin_expect])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])],
[ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ],
Expand Down Expand Up @@ -182,6 +188,10 @@ if test "x$enable_debug" = xyes; then
AC_DEFINE_UNQUOTED([ENABLE_DEBUG],[1],[Define to 1 to enable debug output])
fi

if test "x$test_passwd" = xyes; then
AC_DEFINE_UNQUOTED([TEST_PASSWD],[1],[Define to 1 to enable test password])
fi

if test "x$with_net" = xyes; then
AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),)
AC_CHECK_LIB([event_core],[main],EVENT_LIBS=-levent_core,AC_MSG_ERROR(libevent_core missing))
Expand Down Expand Up @@ -238,6 +248,7 @@ echo " with wallet = $with_wallet"
echo " with unistring = $with_unistring"
echo
echo " SSE2 Scrypt = $use_scrypt_sse2"
echo " test password = $test_passwd"
echo
echo " openenclave = $use_openenclave"
echo
Expand Down
31 changes: 20 additions & 11 deletions doc/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ The `such` tool can be used by simply running the command `./such` in the top le
- derive_child_keys
- generate_mnemonic
- list_encryption_keys_in_tpm
- decrypt_master_key_with_tpm
- decrypt_mnemonic_with_tpm
- decrypt_master_key
- decrypt_mnemonic
- mnemonic_to_key
- mnemonic_to_addresses
- print_keys
- sign
Expand All @@ -41,14 +42,15 @@ Most of these commands require a flag following them to denote things like exist
| -k, --pubkey | public_key | yes | p2pkh -k <public_key> |
| -m, --derived_path | derived_path | yes | derive_child_key -p <extended_private_key> -m <derived_path> |
| -e, --entropy | hex_entropy | yes | generate_mnemonic -e <hex_entropy> |
| -n, --mnemonic | seed_phrase | yes | mnemonic_to_addresses -n <seed_phrase> |
| -a, --pass_phrase | pass_phrase | yes | mnemonic_to_addresses -n <seed_phrase> -a <pass_phrase> |
| -o, --account_int | account_int | yes | mnemonic_to_addresses -n <seed_phrase> -o <account_int> |
| -g, --change_level | change_level | yes | mnemonic_to_addresses -n <seed_phrase> -g <change_level> |
| -i, --address_index | address_index | yes | mnemonic_to_addresses -n <seed_phrase> -i <address_index> |
| -y, --tpm_file | file_num | yes | generate_mnemonic, bip32_extended_master_key, decrypt_master_key_with_tpm, decrypt_mnemonic_with_tpm or mnemonic_to_addresses -y <file_num>
| -n, --mnemonic | seed_phrase | yes | mnemonic_to_key or mnemonic_to_addresses -n <seed_phrase> |
| -a, --pass_phrase | pass_phrase | yes | mnemonic_to_key or mnemonic_to_addresses -n <seed_phrase> -a <pass_phrase> |
| -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>
| -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 |
| -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 @@ -67,8 +69,9 @@ Below is a list of all the commands and the flags that they require. As a remind
| derive_child_keys | -p, -m | -t | Generates a child key derived from the specified private key using the specified derivation path.
| generate_mnemonic | None | -e, -y, -w, -b | Generates a 24-word english seed phrase randomly or from optional hex entropy. |
| list_encryption_keys_in_tpm | None | None | List the encryption keys in the TPM. |
| decrypt_master_key_with_tpm | -y | None | Decrypt the master key with the TPM. |
| decrypt_mnemonic_with_tpm | -y | None | Decrypt the mnemonic with 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. |
| 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.
| sign | -x, -s, -i, -h, -p | -t | See the definition of sign_raw_transaction in the Transaction API.
Expand Down Expand Up @@ -136,7 +139,13 @@ Below are some examples on how to use the `such` tool in practice.
./such -c generate_mnemonic
> they nuclear observe moral twenty gym hedgehog damage reveal syrup negative beach best silk alone feel vapor deposit belt host purity run clever deer

#### Geneate an HD address from the seed phrase for a given account (2), change level (1, internal) and index (0) for testnet
#### Generate a HD master key from the seed phrase for a given account (2), change level (1, internal) and index (0) for testnet

./such -c mnemonic_to_key -n "they nuclear observe moral twenty gym hedgehog damage reveal syrup negative beach best silk alone feel vapor deposit belt host purity run clever deer" -o 2 -g 1 -i 0 -t
> keypath: m/44'/1'/2'/1/0
> private key (wif): cniAjMkD7HpzQKw67ByNsyzqMF8MEJo2y4viH2WEZRXoKHNih1sH

#### Generate an HD address from the seed phrase for a given account (2), change level (1, internal) and index (0) for testnet

./such -c mnemonic_to_addresses -n "they nuclear observe moral twenty gym hedgehog damage reveal syrup negative beach best silk alone feel vapor deposit belt host purity run clever deer" -o 2 -g 1 -i 0 -t
> Address: nW7ndt4HZh8XwLYN6v6N2S4mZCbpZPuFxh
Expand Down
21 changes: 21 additions & 0 deletions include/dogecoin/seal.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,45 @@ LIBDOGECOIN_API dogecoin_bool dogecoin_encrypt_seed_with_tpm (const SEED seed, c
/* Decrypt a BIP32 seed with the TPM */
LIBDOGECOIN_API dogecoin_bool dogecoin_decrypt_seed_with_tpm (SEED seed, const int file_num);

/* Encrypt a BIP32 seed with software */
LIBDOGECOIN_API dogecoin_bool dogecoin_encrypt_seed_with_sw (const SEED seed, const size_t size, const int file_num, const dogecoin_bool overwrite);

/* Decrypt a BIP32 seed with software */
LIBDOGECOIN_API dogecoin_bool dogecoin_decrypt_seed_with_sw (SEED seed, const int file_num);

/* Generate a BIP39 mnemonic and encrypt it with the TPM */
LIBDOGECOIN_API dogecoin_bool dogecoin_generate_mnemonic_encrypt_with_tpm(MNEMONIC mnemonic, const int file_num, const dogecoin_bool overwrite, const char* lang, const char* space, const char* words);

/* Decrypt a BIP39 mnemonic with the TPM */
LIBDOGECOIN_API dogecoin_bool dogecoin_decrypt_mnemonic_with_tpm(MNEMONIC mnemonic, const int file_num);

/* Generate a BIP39 mnemonic and encrypt it with software */
LIBDOGECOIN_API dogecoin_bool dogecoin_generate_mnemonic_encrypt_with_sw(MNEMONIC mnemonic, const int file_num, const dogecoin_bool overwrite, const char* lang, const char* space, const char* words);

/* Decrypt a BIP39 mnemonic with software */
LIBDOGECOIN_API dogecoin_bool dogecoin_decrypt_mnemonic_with_sw(MNEMONIC mnemonic, const int file_num);

/* Generate a BIP32 HD node and encrypt it with the TPM */
LIBDOGECOIN_API dogecoin_bool dogecoin_generate_hdnode_encrypt_with_tpm(dogecoin_hdnode* out, const int file_num, const dogecoin_bool overwrite);

/* Decrypt a BIP32 HD node object with the TPM */
LIBDOGECOIN_API dogecoin_bool dogecoin_decrypt_hdnode_with_tpm(dogecoin_hdnode* out, const int file_num);

/* Generate a BIP32 HD node and encrypt it with software */
LIBDOGECOIN_API dogecoin_bool dogecoin_generate_hdnode_encrypt_with_sw(dogecoin_hdnode* out, const int file_num, const dogecoin_bool overwrite);

/* Decrypt a BIP32 HD node object with software */
LIBDOGECOIN_API dogecoin_bool dogecoin_decrypt_hdnode_with_sw(dogecoin_hdnode* out, const int file_num);

/* List all encryption keys in the TPM */
LIBDOGECOIN_API dogecoin_bool dogecoin_list_encryption_keys_in_tpm(wchar_t* names[], size_t* count);

/* Generate a 256-bit random english mnemonic with the TPM */
LIBDOGECOIN_API dogecoin_bool generateRandomEnglishMnemonicTPM(MNEMONIC mnemonic, const int file_num, const dogecoin_bool overwrite);

/* Generate a 256-bit random english mnemonic with software */
LIBDOGECOIN_API dogecoin_bool generateRandomEnglishMnemonicSW(MNEMONIC mnemonic, const int file_num, const dogecoin_bool overwrite);

LIBDOGECOIN_END_DECL

#endif // __LIBDOGECOIN_SEAL_H__
2 changes: 1 addition & 1 deletion include/dogecoin/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ 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 tpm, const int file_num);
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 void print_utxos(dogecoin_wallet* wallet);
LIBDOGECOIN_API void dogecoin_wallet_free(dogecoin_wallet* wallet);

Expand Down
5 changes: 4 additions & 1 deletion src/address.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ int verifyHDMasterPubKeypairFromEncryptedSeed(const char* wif_privkey_master, co
* @param account The BIP44 account to generate the derived address.
* @param index The BIP44 index to generate the derived address.
* @param change_level The BIP44 change level flag to generate derived address.
* @param pass The passphrase (optional).
* @param p2pkh_pubkey_master The generated master public key.
* @param is_testnet The flag denoting which network, 0 for mainnet and 1 for testnet.
* @param file_num The file number to store the encrypted seed.
Expand All @@ -788,7 +789,9 @@ int getDerivedHDAddressFromEncryptedMnemonic(const uint32_t account, const uint3
}

/* Generate the root key from the mnemonic */
dogecoin_seed_from_mnemonic(mnemonic, pass, seed);
if (dogecoin_seed_from_mnemonic(mnemonic, pass, seed) == -1) {
return -1;
}

/* Generate the root key from the seed */
dogecoin_hdnode_from_seed(seed, MAX_SEED_SIZE, &node);
Expand Down
21 changes: 16 additions & 5 deletions src/cli/spvnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ static struct option long_options[] = {
{"checkpoint", no_argument, NULL, 'p'},
{"wallet_file", required_argument, NULL, 'w'},
{"headers_file", required_argument, NULL, 'h'},
{"tpm_file", required_argument, NULL, 'y'},
{"encrypted_file", required_argument, NULL, 'y'},
{"use_tpm", no_argument, NULL, 'j'},
{"master_key", no_argument, NULL, 'k'},
{"daemon", no_argument, NULL, 'z'},
{NULL, 0, NULL, 0} };

Expand All @@ -196,7 +198,8 @@ static void print_version() {
static void print_usage() {
print_version();
printf("Usage: spvnode (-c|continuous) (-i|-ips <ip,ip,...]>) (-m[--maxpeers] <int>) (-t[--testnet]) (-f <headersfile|0 for in mem only>) \
(-n|-mnemonic <seed_phrase>) (-s|-pass_phrase <pass_phrase>) (-y|-tpm_file <file_num 0-999>) (-w|-wallet_file <filename>) (-h|-headers_file <filename>) (-r[--regtest]) (-d[--debug]) (-s[--timeout] <secs>) <command>\n");
(-n|-mnemonic <seed_phrase>) (-s|-pass_phrase <pass_phrase>) (-y|-encrypted_file <file_num 0-999>) (-w|-wallet_file <filename>) (-h|-headers_file <filename>) \
(-k[--master_key] (-j[--use_tpm]) (-r[--regtest]) (-d[--debug]) (-s[--timeout] <secs>) <command>\n");
printf("Supported commands:\n");
printf(" scan (scan blocks up to the tip, creates header.db file)\n");
printf("\nExamples: \n");
Expand Down Expand Up @@ -270,6 +273,8 @@ int main(int argc, char* argv[]) {
char* headers_name = 0;
dogecoin_bool full_sync = false;
dogecoin_bool have_decl_daemon = false;
dogecoin_bool encrypted = false;
dogecoin_bool master_key = false;
dogecoin_bool tpm = false;
int file_num = NO_FILE;

Expand All @@ -281,7 +286,7 @@ int main(int argc, char* argv[]) {
data = argv[argc - 1];

/* get arguments */
while ((opt = getopt_long_only(argc, argv, "i:ctrds:m:n:f:y:a:w:h:bpz:", long_options, &long_index)) != -1) {
while ((opt = getopt_long_only(argc, argv, "i:ctrds:m:n:f:y:a:w:h:bpzkj:", long_options, &long_index)) != -1) {
switch (opt) {
case 'c':
quit_when_synced = false;
Expand Down Expand Up @@ -320,9 +325,15 @@ int main(int argc, char* argv[]) {
headers_name = optarg;
break;
case 'y':
tpm = true;
encrypted = true;
file_num = (int)strtol(optarg, (char**)NULL, 10);
break;
case 'k':
master_key = true;
break;
case 'j':
tpm = true;
break;
case 'w':
name = optarg;
break;
Expand All @@ -346,7 +357,7 @@ int main(int argc, char* argv[]) {
client->sync_completed = spv_sync_completed;

#if WITH_WALLET
dogecoin_wallet* wallet = dogecoin_wallet_init(chain, address, name, mnemonic_in, pass, tpm, file_num);
dogecoin_wallet* wallet = dogecoin_wallet_init(chain, address, name, mnemonic_in, pass, encrypted, tpm, file_num, master_key);
print_utxos(wallet);
client->sync_transaction = dogecoin_wallet_check_transaction;
client->sync_transaction_ctx = wallet;
Expand Down
Loading