From 474acaaf92f9169b5919f753326c1b087c1774e7 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Fri, 9 Sep 2022 16:30:13 -0400 Subject: [PATCH] Revert "remove YubiHSM support from keosd" --- .cicd/platforms/ubuntu18.Dockerfile | 3 + .cicd/platforms/ubuntu20.Dockerfile | 3 + .cicd/platforms/ubuntu22.Dockerfile | 3 + .gitmodules | 3 + CMakeLists.txt | 4 + README.md | 12 +- docs/03_keosd/10_usage.md | 5 + .../how-to-attach-a-yubihsm-hard-wallet.md | 73 +++++ docs/03_keosd/30_how-to-guides/index.md | 5 + libraries/CMakeLists.txt | 14 + libraries/yubihsm | 1 + plugins/wallet_plugin/CMakeLists.txt | 6 +- .../eosio/wallet_plugin/yubihsm_wallet.hpp | 41 +++ plugins/wallet_plugin/wallet_plugin.cpp | 14 + plugins/wallet_plugin/yubihsm_wallet.cpp | 268 ++++++++++++++++++ scripts/install_deps.sh | 2 +- 16 files changed, 451 insertions(+), 6 deletions(-) create mode 100644 docs/03_keosd/30_how-to-guides/how-to-attach-a-yubihsm-hard-wallet.md create mode 100644 docs/03_keosd/30_how-to-guides/index.md create mode 160000 libraries/yubihsm create mode 100644 plugins/wallet_plugin/include/eosio/wallet_plugin/yubihsm_wallet.hpp create mode 100644 plugins/wallet_plugin/yubihsm_wallet.cpp diff --git a/.cicd/platforms/ubuntu18.Dockerfile b/.cicd/platforms/ubuntu18.Dockerfile index 9620ac7891..256ba84186 100644 --- a/.cicd/platforms/ubuntu18.Dockerfile +++ b/.cicd/platforms/ubuntu18.Dockerfile @@ -7,10 +7,13 @@ RUN apt-get update && apt-get upgrade -y && \ g++-8 \ git \ jq \ + libcurl4-openssl-dev \ libgmp-dev \ libssl-dev \ + libusb-1.0-0-dev \ llvm-7-dev \ ninja-build \ + pkg-config \ python3 \ software-properties-common \ zlib1g-dev \ diff --git a/.cicd/platforms/ubuntu20.Dockerfile b/.cicd/platforms/ubuntu20.Dockerfile index e6d8d3b68f..a2fcb2763a 100644 --- a/.cicd/platforms/ubuntu20.Dockerfile +++ b/.cicd/platforms/ubuntu20.Dockerfile @@ -7,8 +7,11 @@ RUN apt-get update && apt-get upgrade -y && \ git \ jq \ libboost-all-dev \ + libcurl4-openssl-dev \ libgmp-dev \ libssl-dev \ + libusb-1.0-0-dev \ llvm-11-dev \ ninja-build \ + pkg-config \ zstd diff --git a/.cicd/platforms/ubuntu22.Dockerfile b/.cicd/platforms/ubuntu22.Dockerfile index 38aeaa40a4..a0c3b096a1 100644 --- a/.cicd/platforms/ubuntu22.Dockerfile +++ b/.cicd/platforms/ubuntu22.Dockerfile @@ -7,8 +7,11 @@ RUN apt-get update && apt-get upgrade -y && \ git \ jq \ libboost-all-dev \ + libcurl4-openssl-dev \ libgmp-dev \ libssl-dev \ + libusb-1.0-0-dev \ llvm-11-dev \ ninja-build \ + pkg-config \ zstd diff --git a/.gitmodules b/.gitmodules index 888b5d47d3..cd8c78f992 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,6 +16,9 @@ [submodule "libraries/rapidjson"] path = libraries/rapidjson url = https://github.com/Tencent/rapidjson/ +[submodule "libraries/yubihsm"] + path = libraries/yubihsm + url = https://github.com/Yubico/yubihsm-shell [submodule "tests/abieos"] path = tests/abieos url = https://github.com/AntelopeIO/abieos diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d9d0f8b96..74b4834731 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,6 +227,7 @@ configure_file(libraries/fc/src/network/LICENSE.go licenses configure_file(libraries/eos-vm/LICENSE licenses/leap/LICENSE.eos-vm COPYONLY) configure_file(libraries/fc/libraries/ff/LICENSE licenses/leap/LICENSE.libff COPYONLY) configure_file(programs/cleos/LICENSE.CLI11 licenses/leap/LICENSE.CLI11 COPYONLY) +configure_file(libraries/yubihsm/LICENSE licenses/leap/LICENSE.yubihsm COPYONLY) install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/licenses/leap" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/" COMPONENT base) @@ -237,6 +238,9 @@ add_custom_target(dev-install USES_TERMINAL ) +get_property(_CTEST_CUSTOM_TESTS_IGNORE GLOBAL PROPERTY CTEST_CUSTOM_TESTS_IGNORE) +file(WRITE "${CMAKE_BINARY_DIR}/CTestCustom.cmake" "SET(CTEST_CUSTOM_TESTS_IGNORE ${_CTEST_CUSTOM_TESTS_IGNORE})") + include(doxygen) include(package.cmake) diff --git a/README.md b/README.md index 27bf938e64..be3a9586f7 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Recent Ubuntu LTS releases are the only Linux distributions that we fully suppor * CMake 3.8+ * (for Linux only) LLVM 7 - 11 (newer versions do not work) -A few other common libraries are tools also required such as openssl 1.1+, curl, GMP, Python 3, and zlib. +A few other common libraries are tools also required such as openssl 1.1+, libcurl, curl, libusb, GMP, Python 3, and zlib. **A Warning On Parallel Compilation Jobs (`-j` flag)**: When building C/C++ software often the build is performed in parallel via a command such as `make -j $(nproc)` which uses the number of CPU cores as the number of compilation jobs to perform simultaneously. However, be aware that some compilation units (.cpp files) in Leap are extremely complex and will consume nearly 4GB of memory to compile. You may need to reduce the level of parallelization depending on the amount of memory on your build host. e.g. instead of `make -j $(nproc)` run `make -j2`. Failures due to memory exhaustion will typically but not always manifest as compiler crashes. @@ -33,8 +33,6 @@ The binary package will be produced in the Leap build directory that was supplie #### Manual (non "pinned") Build Instructions -These instructions are valid for this branch. Other release branches may have different requirements so ensure you follow the directions in the branch or release you intend to build. -
Ubuntu 20.04 & 22.04 Build Instructions @@ -46,9 +44,12 @@ apt-get update && apt-get install \ curl \ git \ libboost-all-dev \ + libcurl4-openssl-dev \ libgmp-dev \ libssl-dev \ - llvm-11-dev + libusb-1.0-0-dev \ + llvm-11-dev \ + pkg-config ``` and perform the build: ``` @@ -71,9 +72,12 @@ apt-get update && apt-get install \ curl \ g++-8 \ git \ + libcurl4-openssl-dev \ libgmp-dev \ libssl-dev \ + libusb-1.0-0-dev \ llvm-7-dev \ + pkg-config \ python3 \ zlib1g-dev diff --git a/docs/03_keosd/10_usage.md b/docs/03_keosd/10_usage.md index eecdaa2a94..b66775ddcf 100644 --- a/docs/03_keosd/10_usage.md +++ b/docs/03_keosd/10_usage.md @@ -91,6 +91,11 @@ Config Options for eosio::wallet_plugin: number of seconds of inactivity. Activity is defined as any wallet command e.g. list-wallets. + --yubihsm-url URL Override default URL of + http://localhost:12345 for connecting + to yubihsm-connector + --yubihsm-authkey key_num Enables YubiHSM support using given + Authkey Application Config Options: --plugin arg Plugin(s) to enable, may be specified diff --git a/docs/03_keosd/30_how-to-guides/how-to-attach-a-yubihsm-hard-wallet.md b/docs/03_keosd/30_how-to-guides/how-to-attach-a-yubihsm-hard-wallet.md new file mode 100644 index 0000000000..ab32720aad --- /dev/null +++ b/docs/03_keosd/30_how-to-guides/how-to-attach-a-yubihsm-hard-wallet.md @@ -0,0 +1,73 @@ +--- +content_title: How To Attach a YubiHSM Hard Wallet +link_text: How To Attach a YubiHSM Hard Wallet +--- + +## Goal + +Attach a YubiHSM as a hard wallet + +## Before you begin + +* Install the currently supported version of `keosd` + +* Install YubiHSM2 Software Toolkit (YubiHSM2 SDK) + +* Create an AuthKey with at least the following Capabilities: + + * sign-ecdsa + * generate-asymmetric-key + * export-wrapped + +* **Delete the default AuthKey** + +[[warning | Security]] +| It is extremely important to create a new AuthKey and remove the default AuthKey before proceed to the following steps. + +## Steps + +### Configure `keosd` + + There are two options to connect `keosd` to YubiHSM: + + #### Using a YubiHSM connector + + By default, `keosd` will connect to the YubiHSM connector on the default host and port. If a non-default URL is used, set the `--yubihsm-url` option or `yubihsm-url` in `config.ini` with the correct connector URL + + #### Directly connect via USB + + `keosd` also can directly connect to YubiHSM via USB protocol + + If this option is used, set `keosd` startup option as the below: + + ```sh + --yubihsm-url=ysb:// + ``` + +### Start `keosd` with AuthKey: + + ```sh + --yubihsm-authkey Your_AuthKey_Object_Number + ``` + + if a YubiHSM connector is used, check the YubiHSM connector is up and running by visiting YubiHSM URL: + http://YubiHSM_HOST:YubiHSM_PORT/connector/status ((Default HOST and Port: http://127.0.0.1:12345) + + You should see something like this: + + ```console + status=OK + serial=* + version=2.0.0 + pid=666 + address=localhost + port=12345 + ``` + +### Unlock YubiHSM wallet with the password of AuthKey using the following option: + + ```sh + cleos wallet unlock -n YubiHSM --password YOUR_AUTHKEY_PASSWORD + ``` + +After unlocking the wallet, you can use `cleos wallet` commands as usual. Beware as a part of security mechanism, some wallet subcommands, such as retrieve private keys, or remove a key, are not supported when a YubiHSM is used \ No newline at end of file diff --git a/docs/03_keosd/30_how-to-guides/index.md b/docs/03_keosd/30_how-to-guides/index.md new file mode 100644 index 0000000000..ec0bd09ccf --- /dev/null +++ b/docs/03_keosd/30_how-to-guides/index.md @@ -0,0 +1,5 @@ +--- +content_title: Keosd How-to Guides +--- + +* [How to attach a YubiHSM hard wallet](how-to-attach-a-yubihsm-hard-wallet.md) diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 1f74f8db08..9598cd4d1f 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -30,3 +30,17 @@ set(ENABLE_PROFILE OFF CACHE BOOL "Enable for profile builds") if(eos-vm IN_LIST EOSIO_WASM_RUNTIMES OR eos-vm-jit IN_LIST EOSIO_WASM_RUNTIMES) add_subdirectory( eos-vm ) endif() + +set(ENABLE_STATIC ON) +set(CMAKE_MACOSX_RPATH OFF) +set(BUILD_ONLY_LIB ON CACHE BOOL "Library only build") +message(STATUS "Starting yubihsm configuration...") +add_subdirectory( yubihsm EXCLUDE_FROM_ALL ) +target_compile_options(yubihsm_static PRIVATE -fno-lto -fcommon) +message(STATUS "yubihsm configuration complete") + +get_property(_CTEST_CUSTOM_TESTS_IGNORE GLOBAL PROPERTY CTEST_CUSTOM_TESTS_IGNORE) +set_property(GLOBAL PROPERTY CTEST_CUSTOM_TESTS_IGNORE + "change_authkey import_ed decrypt_ec decrypt_rsa ssh logs generate_rsa import_ec echo\ + yubico_otp wrap_data wrap info import_rsa import_authkey generate_hmac generate_ec\ + attest pbkdf2 parsing ${_CTEST_CUSTOM_TESTS_IGNORE}") diff --git a/libraries/yubihsm b/libraries/yubihsm new file mode 160000 index 0000000000..9189fdb92c --- /dev/null +++ b/libraries/yubihsm @@ -0,0 +1 @@ +Subproject commit 9189fdb92cc90840e51760de5f297ac7d908b3cd diff --git a/plugins/wallet_plugin/CMakeLists.txt b/plugins/wallet_plugin/CMakeLists.txt index 039b8ee190..27f0147c8d 100644 --- a/plugins/wallet_plugin/CMakeLists.txt +++ b/plugins/wallet_plugin/CMakeLists.txt @@ -19,7 +19,11 @@ add_library( wallet_plugin wallet_plugin.cpp wallet_manager.cpp ${SE_WALLET_SOURCES} + yubihsm_wallet.cpp ${HEADERS} ) -target_link_libraries( wallet_plugin eosio_chain appbase ${security_framework} ${corefoundation_framework} ${localauthentication_framework} ${cocoa_framework}) +target_link_libraries( wallet_plugin yubihsm_static eosio_chain appbase ${security_framework} ${corefoundation_framework} ${localauthentication_framework} ${cocoa_framework}) target_include_directories( wallet_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) + +#sadly old cmake 2.8 support in yubihsm cmake prevents usage of target_include_directories there +target_include_directories( wallet_plugin PRIVATE "${CMAKE_SOURCE_DIR}/libraries/yubihsm/lib" ) \ No newline at end of file diff --git a/plugins/wallet_plugin/include/eosio/wallet_plugin/yubihsm_wallet.hpp b/plugins/wallet_plugin/include/eosio/wallet_plugin/yubihsm_wallet.hpp new file mode 100644 index 0000000000..abafbe8478 --- /dev/null +++ b/plugins/wallet_plugin/include/eosio/wallet_plugin/yubihsm_wallet.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +using namespace std; +using namespace eosio::chain; + +namespace eosio { namespace wallet { + +namespace detail { +struct yubihsm_wallet_impl; +} + +class yubihsm_wallet final : public wallet_api { + public: + yubihsm_wallet(const string& connector, const uint16_t authkey); + ~yubihsm_wallet(); + + private_key_type get_private_key(public_key_type pubkey) const override; + + bool is_locked() const override; + void lock() override; + void unlock(string password) override; + void check_password(string password) override; + void set_password(string password) override; + + map list_keys() override; + flat_set list_public_keys() override; + + bool import_key(string wif_key) override; + string create_key(string key_type) override; + bool remove_key(string key) override; + + std::optional try_sign_digest(const digest_type digest, const public_key_type public_key) override; + + private: + std::unique_ptr my; +}; + +}} diff --git a/plugins/wallet_plugin/wallet_plugin.cpp b/plugins/wallet_plugin/wallet_plugin.cpp index 2b22adf4d5..519e8bbb92 100644 --- a/plugins/wallet_plugin/wallet_plugin.cpp +++ b/plugins/wallet_plugin/wallet_plugin.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -26,6 +27,10 @@ void wallet_plugin::set_program_options(options_description& cli, options_descri "Timeout for unlocked wallet in seconds (default 900 (15 minutes)). " "Wallets will automatically lock after specified number of seconds of inactivity. " "Activity is defined as any wallet command e.g. list-wallets.") + ("yubihsm-url", bpo::value()->value_name("URL"), + "Override default URL of http://localhost:12345 for connecting to yubihsm-connector") + ("yubihsm-authkey", bpo::value()->value_name("key_num"), + "Enables YubiHSM support using given Authkey") ; } @@ -48,6 +53,15 @@ void wallet_plugin::plugin_initialize(const variables_map& options) { std::chrono::seconds t(timeout); wallet_manager_ptr->set_timeout(t); } + if (options.count("yubihsm-authkey")) { + uint16_t key = options.at("yubihsm-authkey").as(); + string connector_endpoint = "http://localhost:12345"; + if(options.count("yubihsm-url")) + connector_endpoint = options.at("yubihsm-url").as(); + try { + wallet_manager_ptr->own_and_use_wallet("YubiHSM", make_unique(connector_endpoint, key)); + }FC_LOG_AND_RETHROW() + } } FC_LOG_AND_RETHROW() } diff --git a/plugins/wallet_plugin/yubihsm_wallet.cpp b/plugins/wallet_plugin/yubihsm_wallet.cpp new file mode 100644 index 0000000000..d2de96ae6d --- /dev/null +++ b/plugins/wallet_plugin/yubihsm_wallet.cpp @@ -0,0 +1,268 @@ +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +namespace eosio { namespace wallet { + +using namespace fc::crypto::r1; + +namespace detail { + +struct yubihsm_wallet_impl { + using key_map_type = map; + + yubihsm_wallet_impl(const string& ep, const uint16_t ak) : endpoint(ep), authkey(ak) { + yh_rc rc; + if((rc = yh_init())) + FC_THROW("yubihsm init failure: ${c}", ("c", yh_strerror(rc))); + } + + ~yubihsm_wallet_impl() { + lock(); + yh_exit(); + //bizarre, is there no way to destroy a yh_connector?? + + ///XXX Probably a race condition on timer shutdown and appbase destruction + } + + bool is_locked() const { + return !connector; + } + + key_map_type::iterator populate_key_map_with_keyid(const uint16_t key_id) { + yh_rc rc; + size_t blob_sz = 128; + uint8_t blob[blob_sz]; + if((rc = yh_util_get_public_key(session, key_id, blob, &blob_sz, nullptr))) + FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_get_public_key failed: ${m}", ("m", yh_strerror(rc))); + if(blob_sz != 64) + FC_THROW_EXCEPTION(chain::wallet_exception, "unexpected pubkey size from yh_util_get_public_key"); + + ///XXX This is junky and common with SE wallet; commonize it + char serialized_pub_key[sizeof(public_key_data) + 1]; + serialized_pub_key[0] = 0x01; //means R1 key + serialized_pub_key[1] = 0x02 + (blob[63]&1); //R1 header; even or odd Y + memcpy(serialized_pub_key+2, blob, 32); //copy in the 32 bytes of X + + public_key_type pub_key; + fc::datastream ds(serialized_pub_key, sizeof(serialized_pub_key)); + fc::raw::unpack(ds, pub_key); + + return _keys.emplace(pub_key, key_id).first; + } + + void unlock(const string& password) { + yh_rc rc; + + try { + if((rc = yh_init_connector(endpoint.c_str(), &connector))) + FC_THROW_EXCEPTION(chain::wallet_exception, "Failled to initialize yubihsm connector URL: ${c}", ("c", yh_strerror(rc))); + if((rc = yh_connect(connector, 0))) + FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to connect to YubiHSM connector: ${m}", ("m", yh_strerror(rc))); + if((rc = yh_create_session_derived(connector, authkey, (const uint8_t *)password.data(), password.size(), false, &session))) + FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to create YubiHSM session: ${m}", ("m", yh_strerror(rc))); + if((rc = yh_authenticate_session(session))) + FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to authenticate YubiHSM session: ${m}", ("m", yh_strerror(rc))); + + yh_object_descriptor authkey_desc; + if((rc = yh_util_get_object_info(session, authkey, YH_AUTHENTICATION_KEY, &authkey_desc))) + FC_THROW_EXCEPTION(chain::wallet_exception, "Failed to get authkey info: ${m}", ("m", yh_strerror(rc))); + + authkey_caps = authkey_desc.capabilities; + authkey_domains = authkey_desc.domains; + + if(!yh_check_capability(&authkey_caps, "sign-ecdsa")) + FC_THROW_EXCEPTION(chain::wallet_exception, "Given authkey cannot perform signing"); + + size_t found_objects_n = 64*1024; + yh_object_descriptor found_objs[found_objects_n]; + yh_capabilities find_caps; + yh_string_to_capabilities("sign-ecdsa", &find_caps); + if((rc = yh_util_list_objects(session, 0, YH_ASYMMETRIC_KEY, 0, &find_caps, YH_ALGO_EC_P256, nullptr, found_objs, &found_objects_n))) + FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_list_objects failed: ${m}", ("m", yh_strerror(rc))); + + for(size_t i = 0; i < found_objects_n; ++i) + populate_key_map_with_keyid(found_objs[i].id); + } + catch(chain::wallet_exception& e) { + lock(); + throw; + } + + prime_keepalive_timer(); + } + + void lock() { + if(session) { + yh_util_close_session(session); + yh_destroy_session(&session); + } + session = nullptr; + if(connector) + yh_disconnect(connector); + //it would seem like this would leak-- there is no destroy() call for it. But I clearly can't reuse connectors + // as that fails with a "Unable to find a suitable connector" + connector = nullptr; + + _keys.clear(); + keepalive_timer.cancel(); + } + + void prime_keepalive_timer() { + keepalive_timer.expires_at(std::chrono::steady_clock::now() + std::chrono::seconds(20)); + keepalive_timer.async_wait([this](const boost::system::error_code& ec){ + if(ec || !session) + return; + + uint8_t data, resp; + yh_cmd resp_cmd; + size_t resp_sz = 1; + if(yh_send_secure_msg(session, YHC_ECHO, &data, 1, &resp_cmd, &resp, &resp_sz)) + lock(); + else + prime_keepalive_timer(); + }); + } + + std::optional try_sign_digest(const digest_type d, const public_key_type public_key) { + auto it = _keys.find(public_key); + if(it == _keys.end()) + return std::optional(); + + size_t der_sig_sz = 128; + uint8_t der_sig[der_sig_sz]; + yh_rc rc; + if((rc = yh_util_sign_ecdsa(session, it->second, (uint8_t*)d.data(), d.data_size(), der_sig, &der_sig_sz))) { + lock(); + FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_sign_ecdsa failed: ${m}", ("m", yh_strerror(rc))); + } + + ///XXX a lot of this below is similar to SE wallet; commonize it in non-junky way + fc::ecdsa_sig sig = ECDSA_SIG_new(); + BIGNUM *r = BN_new(), *s = BN_new(); + BN_bin2bn(der_sig+4, der_sig[3], r); + BN_bin2bn(der_sig+6+der_sig[3], der_sig[4+der_sig[3]+1], s); + ECDSA_SIG_set0(sig, r, s); + + char pub_key_shim_data[64]; + fc::datastream eds(pub_key_shim_data, sizeof(pub_key_shim_data)); + fc::raw::pack(eds, it->first); + public_key_data* kd = (public_key_data*)(pub_key_shim_data+1); + + compact_signature compact_sig; + compact_sig = signature_from_ecdsa(key, *kd, sig, d); + + char serialized_signature[sizeof(compact_sig) + 1]; + serialized_signature[0] = 0x01; + memcpy(serialized_signature+1, compact_sig.data, sizeof(compact_sig)); + + signature_type final_signature; + fc::datastream ds(serialized_signature, sizeof(serialized_signature)); + fc::raw::unpack(ds, final_signature); + return final_signature; + } + + public_key_type create() { + if(!yh_check_capability(&authkey_caps, "generate-asymmetric-key")) + FC_THROW_EXCEPTION(chain::wallet_exception, "Given authkey cannot create keys"); + + yh_rc rc; + uint16_t new_key_id = 0; + yh_capabilities creation_caps = {}; + if(yh_string_to_capabilities("sign-ecdsa:export-wrapped", &creation_caps)) + FC_THROW_EXCEPTION(chain::wallet_exception, "Cannot create caps mask"); + + try { + if((rc = yh_util_generate_ec_key(session, &new_key_id, "keosd created key", authkey_domains, &creation_caps, YH_ALGO_EC_P256))) + FC_THROW_EXCEPTION(chain::wallet_exception, "yh_util_generate_ec_key failed: ${m}", ("m", yh_strerror(rc))); + return populate_key_map_with_keyid(new_key_id)->first; + } + catch(chain::wallet_exception& e) { + lock(); + throw; + } + } + + yh_connector* connector = nullptr; + yh_session* session = nullptr; + string endpoint; + uint16_t authkey; + + map _keys; + + yh_capabilities authkey_caps; + uint16_t authkey_domains; + + boost::asio::steady_timer keepalive_timer{appbase::app().get_io_service()}; + fc::ec_key key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); +}; + + +} + +yubihsm_wallet::yubihsm_wallet(const string& connector, const uint16_t authkey) : my(new detail::yubihsm_wallet_impl(connector, authkey)) { +} + +yubihsm_wallet::~yubihsm_wallet() { +} + +private_key_type yubihsm_wallet::get_private_key(public_key_type pubkey) const { + FC_THROW_EXCEPTION(chain::wallet_exception, "Obtaining private key for a key stored in YubiHSM is impossible"); +} + +bool yubihsm_wallet::is_locked() const { + return my->is_locked(); +} +void yubihsm_wallet::lock() { + FC_ASSERT(!is_locked()); + my->lock(); +} + +void yubihsm_wallet::unlock(string password) { + my->unlock(password); +} +void yubihsm_wallet::check_password(string password) { + //just leave this as a noop for now; remove_key from wallet_mgr calls through here +} +void yubihsm_wallet::set_password(string password) { + FC_THROW_EXCEPTION(chain::wallet_exception, "YubiHSM wallet cannot have a password set"); +} + +map yubihsm_wallet::list_keys() { + FC_THROW_EXCEPTION(chain::wallet_exception, "Getting the private keys from the YubiHSM wallet is impossible"); +} +flat_set yubihsm_wallet::list_public_keys() { + flat_set keys; + boost::copy(my->_keys | boost::adaptors::map_keys, std::inserter(keys, keys.end())); + return keys; +} + +bool yubihsm_wallet::import_key(string wif_key) { + FC_THROW_EXCEPTION(chain::wallet_exception, "It is not possible to import a key in to the YubiHSM wallet"); +} + +string yubihsm_wallet::create_key(string key_type) { + EOS_ASSERT(key_type.empty() || key_type == "R1", chain::unsupported_key_type_exception, "YubiHSM wallet only supports R1 keys"); + return my->create().to_string(); +} + +bool yubihsm_wallet::remove_key(string key) { + FC_ASSERT(!is_locked()); + FC_THROW_EXCEPTION(chain::wallet_exception, "YubiHSM wallet does not currently support removal of keys"); + return true; +} + +std::optional yubihsm_wallet::try_sign_digest(const digest_type digest, const public_key_type public_key) { + return my->try_sign_digest(digest, public_key); +} + +}} diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index 919cdbda55..da3587f4e7 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -3,4 +3,4 @@ apt-get update apt-get update --fix-missing DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata -apt-get -y install zip unzip libncurses5 wget git build-essential cmake curl libgmp-dev libssl-dev libzstd-dev time zlib1g-dev libtinfo-dev bzip2 libbz2-dev python3 file +apt-get -y install zip unzip libncurses5 wget git build-essential cmake curl libcurl4-openssl-dev libgmp-dev libssl-dev libusb-1.0.0-dev libzstd-dev time pkg-config zlib1g-dev libtinfo-dev bzip2 libbz2-dev python3 file