From d8944812f79b9eef5de69213265a33ba0f3abb2f Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko Date: Tue, 10 Oct 2023 12:46:12 +0300 Subject: [PATCH 1/3] deps: add zeroize --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 21e96446c6..6de72615fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,6 +69,7 @@ thiserror = { version = "1.0.47", default-features = false } tokio = { version = "1.31.0", default-features = false } trybuild = "1.0.82" which = { version = "4.4.0", default-features = false } +zeroize = "1.6.0" # Dependencies from the `fuel-core` repository: fuel-core = { version = "0.20.4", default-features = false } From 28ee2ce369d975d485b57ac64cd55d732a61b0fd Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko Date: Tue, 10 Oct 2023 12:46:21 +0300 Subject: [PATCH 2/3] feat(accounts): zeroize SecretKey in WalletUnlocked --- packages/fuels-accounts/Cargo.toml | 1 + packages/fuels-accounts/src/wallet.rs | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/fuels-accounts/Cargo.toml b/packages/fuels-accounts/Cargo.toml index f4603e084a..8ec391efd2 100644 --- a/packages/fuels-accounts/Cargo.toml +++ b/packages/fuels-accounts/Cargo.toml @@ -26,6 +26,7 @@ rand = { workspace = true, default-features = false } tai64 = { workspace = true, features = ["serde"] } thiserror = { workspace = true, default-features = false } tokio = { workspace = true, features = ["full"] } +zeroize = { workspace = true, features = ["derive"] } [dev-dependencies] hex = { workspace = true, default-features = false, features = ["std"] } diff --git a/packages/fuels-accounts/src/wallet.rs b/packages/fuels-accounts/src/wallet.rs index 907abc63f1..1c587e3f2a 100644 --- a/packages/fuels-accounts/src/wallet.rs +++ b/packages/fuels-accounts/src/wallet.rs @@ -16,6 +16,7 @@ use fuels_core::{ }; use rand::{CryptoRng, Rng}; use thiserror::Error; +use zeroize::{Zeroize, ZeroizeOnDrop}; use crate::{ accounts_utils::{adjust_inputs, adjust_outputs, calculate_base_amount_with_fee}, @@ -71,8 +72,11 @@ pub struct Wallet { /// A `WalletUnlocked` is equivalent to a [`Wallet`] whose private key is known and stored /// alongside in-memory. Knowing the private key allows a `WalletUlocked` to sign operations, send /// transactions, and more. -#[derive(Clone, Debug)] +/// +/// `private_key` will be zeroed out on calling `lock()` or `drop`ping a `WalletUnlocked`. +#[derive(Clone, Debug, Zeroize, ZeroizeOnDrop)] pub struct WalletUnlocked { + #[zeroize(skip)] wallet: Wallet, pub(crate) private_key: SecretKey, } @@ -118,9 +122,10 @@ impl ViewOnlyAccount for Wallet { } impl WalletUnlocked { - /// Lock the wallet by `drop`ping the private key from memory. - pub fn lock(self) -> Wallet { - self.wallet + /// Lock the wallet by securely `zeroize`-ing and `drop`ping the private key from memory. + pub fn lock(mut self) -> Wallet { + self.private_key.zeroize(); + self.wallet.clone() } // NOTE: Rather than providing a `DerefMut` implementation, we wrap the `set_provider` method From d0f675f2188326afd519dbc36c3ec0cca18f8f56 Mon Sep 17 00:00:00 2001 From: Oleksii Filonenko Date: Tue, 10 Oct 2023 12:59:09 +0300 Subject: [PATCH 3/3] feat(core): zeroize keys in `UnresolvedSignatures` --- packages/fuels-core/Cargo.toml | 1 + packages/fuels-core/src/types/transaction_builders.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/fuels-core/Cargo.toml b/packages/fuels-core/Cargo.toml index 9afe9a7172..615d9f3d83 100644 --- a/packages/fuels-core/Cargo.toml +++ b/packages/fuels-core/Cargo.toml @@ -28,6 +28,7 @@ serde_json = { workspace = true, default-features = true } sha2 = { workspace = true } thiserror = { workspace = true, default-features = false } uint = { version = "0.9.5", default-features = false } +zeroize = { workspace = true, features = ["derive"] } [dev-dependencies] fuels-macros = { workspace = true } diff --git a/packages/fuels-core/src/types/transaction_builders.rs b/packages/fuels-core/src/types/transaction_builders.rs index 076c076c8c..375b44afe5 100644 --- a/packages/fuels-core/src/types/transaction_builders.rs +++ b/packages/fuels-core/src/types/transaction_builders.rs @@ -11,6 +11,7 @@ use fuel_tx::{ }; use fuel_types::{bytes::padded_len_usize, Bytes32, ChainId, MemLayout, Salt}; use fuel_vm::{checked_transaction::EstimatePredicates, gas::GasCosts}; +use zeroize::{Zeroize, ZeroizeOnDrop}; use crate::{ constants::{BASE_ASSET_ID, WORD_SIZE}, @@ -53,8 +54,9 @@ impl NetworkInfo { } } -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Zeroize, ZeroizeOnDrop)] struct UnresolvedSignatures { + #[zeroize(skip)] addr_idx_offset_map: HashMap, secret_keys: Vec, }