From bf39d37096226c7ee352b08e819064df7d71a71a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Apr 2026 21:19:45 +0300 Subject: [PATCH 1/2] fix(rs-sdk-ffi): zeroize private key arrays after use in crypto/signer FFI Private key byte arrays in non-shielded FFI functions were not being zeroized after use, leaving key material on the stack. The shielded crypto module already handles this correctly via zeroize::Zeroize. Wrap all `[u8; 32]` key arrays with `Zeroizing<>` so they are automatically zeroed on drop, covering all return paths including early returns. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/rs-sdk-ffi/src/crypto/mod.rs | 7 ++++--- packages/rs-sdk-ffi/src/signer_simple.rs | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/rs-sdk-ffi/src/crypto/mod.rs b/packages/rs-sdk-ffi/src/crypto/mod.rs index 91c5579facc..4ab971d8199 100644 --- a/packages/rs-sdk-ffi/src/crypto/mod.rs +++ b/packages/rs-sdk-ffi/src/crypto/mod.rs @@ -4,6 +4,7 @@ use crate::{DashSDKError, DashSDKErrorCode, DashSDKResult}; use dash_sdk::dpp::dashcore::Network; use dash_sdk::dpp::identity::KeyType; use std::ffi::{c_char, CStr}; +use zeroize::Zeroizing; /// Validate that a private key corresponds to a public key using DPP's public_key_data_from_private_key_data /// @@ -65,7 +66,7 @@ pub unsafe extern "C" fn dash_sdk_validate_private_key_for_public_key( } }; - let mut key_array = [0u8; 32]; + let mut key_array = Zeroizing::new([0u8; 32]); key_array.copy_from_slice(&private_key_bytes); // Parse key type @@ -176,7 +177,7 @@ pub unsafe extern "C" fn dash_sdk_private_key_to_wif( Network::Mainnet }; - let mut key_array = [0u8; 32]; + let mut key_array = Zeroizing::new([0u8; 32]); key_array.copy_from_slice(&private_key_bytes); match dash_sdk::dpp::dashcore::PrivateKey::from_byte_array(&key_array, network) { Ok(private_key) => { @@ -244,7 +245,7 @@ pub unsafe extern "C" fn dash_sdk_public_key_data_from_private_key_data( } }; - let mut key_array = [0u8; 32]; + let mut key_array = Zeroizing::new([0u8; 32]); key_array.copy_from_slice(&private_key_bytes); // Parse key type diff --git a/packages/rs-sdk-ffi/src/signer_simple.rs b/packages/rs-sdk-ffi/src/signer_simple.rs index f7156e7a157..67bff492ff8 100644 --- a/packages/rs-sdk-ffi/src/signer_simple.rs +++ b/packages/rs-sdk-ffi/src/signer_simple.rs @@ -6,6 +6,7 @@ use dash_sdk::dpp::dashcore::Network; use dash_sdk::dpp::identity::signer::Signer; use dash_sdk::dpp::identity::{IdentityPublicKey, KeyType, Purpose, SecurityLevel}; use simple_signer::SingleKeySigner; +use zeroize::Zeroizing; /// Create a signer from a private key /// @@ -32,9 +33,9 @@ pub unsafe extern "C" fn dash_sdk_signer_create_from_private_key( )); } - // Convert the pointer to an array + // Convert the pointer to an array (zeroized on drop to avoid key material lingering on stack) let key_slice = std::slice::from_raw_parts(private_key, 32); - let mut key_array: [u8; 32] = [0; 32]; + let mut key_array = Zeroizing::new([0u8; 32]); key_array.copy_from_slice(key_slice); // network won't matter here From 535132480721dee14343aa83ee569a467415236a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Apr 2026 21:51:07 +0300 Subject: [PATCH 2/2] chore(rs-scripts): remove unused serde_json dependency cargo-machete flagged serde_json as unused in rs-scripts, causing CI failure. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/rs-scripts/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/rs-scripts/Cargo.toml b/packages/rs-scripts/Cargo.toml index dc639760994..18bb06e33b9 100644 --- a/packages/rs-scripts/Cargo.toml +++ b/packages/rs-scripts/Cargo.toml @@ -15,4 +15,3 @@ base64 = "0.22" chrono = "0.4" hex = "0.4" clap = { version = "4", features = ["derive"] } -serde_json = "1"