Skip to content

Commit

Permalink
Codesplit for ledger
Browse files Browse the repository at this point in the history
  • Loading branch information
brianp committed Mar 11, 2024
1 parent 6f7af0b commit 41934fb
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 13 deletions.
13 changes: 12 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions base_layer/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ futures = { version = "^0.3.16", features = ["async-await"] }
hex = "0.4.2"
integer-encoding = "3.0"
lmdb-zero = "0.4.4"
ledger-transport = { git = "https://github.com/Zondax/ledger-rs", version = "0.10" }
ledger-transport-hid = { git = "https://github.com/Zondax/ledger-rs", version = "0.10" }
log = "0.4"
log-mdc = "0.1.0"
monero = { version = "0.20.0", features = ["serde-crate"], optional = true }
Expand Down
31 changes: 31 additions & 0 deletions base_layer/core/src/transactions/key_manager/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use serde::{Deserialize, Serialize};
use tari_crypto::signatures::CommitmentAndPublicKeySignatureError;
use tari_key_manager::error::KeyManagerError;
use tari_utilities::ByteArrayError;
use thiserror::Error;

use crate::transactions::transaction_components::TransactionError;
Expand All @@ -41,3 +43,32 @@ impl From<CommitmentAndPublicKeySignatureError> for CoreKeyManagerError {
CoreKeyManagerError::CommitmentAndPublicKeySignatureError(err.to_string())
}
}

/// Ledger device errors.
#[derive(Debug, PartialEq, Error, Deserialize, Serialize, Clone, Eq)]
pub enum LedgerDeviceError {
/// HID API error
#[error("HID API error `{0}`")]
HidApi(String),
/// Native HID transport error
#[error("Native HID transport error `{0}`")]
NativeTransport(String),
/// Ledger application not started
#[error("Ledger application not started")]
ApplicationNotStarted,
/// Ledger application instruction error
#[error("Ledger application instruction error `{0}`")]
Instruction(String),
/// Ledger application processing error
#[error("Processing error `{0}`")]
Processing(String),
/// Conversion error to or from ledger
#[error("Conversion failed: {0}")]
ByteArrayError(String),
}

impl From<ByteArrayError> for LedgerDeviceError {
fn from(e: ByteArrayError) -> Self {
LedgerDeviceError::ByteArrayError(e.to_string())
}
}
62 changes: 52 additions & 10 deletions base_layer/core/src/transactions/key_manager/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,18 @@
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use std::{collections::HashMap, ops::Shl};
use std::{
collections::HashMap,
ops::Shl,
sync::{Arc, Mutex},
};

use blake2::Blake2b;
use digest::consts::U64;
use ledger_transport::APDUCommand;
use ledger_transport_hid::TransportNativeHID;
use log::*;
use once_cell::sync::Lazy;
use rand::rngs::OsRng;
use strum::IntoEnumIterator;
use tari_common_types::{
Expand Down Expand Up @@ -57,33 +64,32 @@ use tari_key_manager::{
use tari_utilities::{hex::Hex, ByteArray};
use tokio::sync::RwLock;

use crate::{
one_sided::diffie_hellman_stealth_domain_hasher,
transactions::{
transaction_components::{KernelFeatures, TransactionError, TransactionInput, TransactionInputVersion},
CryptoFactories,
},
};

const LOG_TARGET: &str = "key_manager::key_manager_service";
const KEY_MANAGER_MAX_SEARCH_DEPTH: u64 = 1_000_000;

use crate::{
common::ConfidentialOutputHasher,
one_sided::diffie_hellman_stealth_domain_hasher,
transactions::{
key_manager::{
interface::{TransactionKeyManagerBranch, TxoStage},
LedgerDeviceError,
TariKeyId,
},
tari_amount::MicroMinotari,
transaction_components::{
EncryptedData,
KernelFeatures,
RangeProofType,
TransactionError,
TransactionInput,
TransactionInputVersion,
TransactionKernel,
TransactionKernelVersion,
TransactionOutput,
TransactionOutputVersion,
},
CryptoFactories,
},
};

Expand All @@ -101,6 +107,8 @@ pub struct TransactionKeyManagerInner<TBackend> {
wallet_type: WalletType,
}

pub static TRANSPORT: Lazy<Arc<Mutex<Option<TransportNativeHID>>>> = Lazy::new(|| Arc::new(Mutex::new(None)));

impl<TBackend> TransactionKeyManagerInner<TBackend>
where TBackend: KeyManagerBackend<PublicKey> + 'static
{
Expand Down Expand Up @@ -435,6 +443,40 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
// Transaction input section (transactions > transaction_components > transaction_input)
// -----------------------------------------------------------------------------------------------------------------

pub async fn get_script_private_key(&self, script_key_id: &TariKeyId) -> Result<PrivateKey, TransactionError> {
match self.wallet_type {
WalletType::Software => self.get_private_key(script_key_id).await.map_err(|e| e.into()),
WalletType::Ledger(account) => {
let data = script_key_id.managed_index().expect("and index").to_le_bytes().to_vec();
let command = APDUCommand {
cla: 0x80,
ins: 0x02, // GetPrivateKey - see `./applications/mp_ledger/src/main.rs/Instruction`
p1: 0x00,
p2: 0x00,
data,
};
let binding = TRANSPORT.lock().expect("lock exists");
let transport = binding.as_ref().expect("transport exists");
match transport.exchange(&command) {
Ok(result) => {
if result.data().len() < 33 {
return Err(LedgerDeviceError::Processing(format!(
"'get_private_key' insufficient data - expected 33 got {} bytes ({:?})",
result.data().len(),
result
))
.into());
}
PrivateKey::from_canonical_bytes(&result.data()[1..33])
.map_err(|e| TransactionError::InvalidSignatureError(e.to_string()))
},
Err(e) => Err(LedgerDeviceError::Instruction(format!("GetPrivateKey: {}", e)).into()),
}
// end script private key
},
}
}

pub async fn get_script_signature(
&self,
script_key_id: &TariKeyId,
Expand All @@ -449,8 +491,8 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static
let ephemeral_commitment = self.crypto_factories.commitment.commit(&r_x, &r_a);
let ephemeral_pubkey = PublicKey::from_secret_key(&r_y);
let commitment = self.get_commitment(spend_key_id, value).await?;
let script_private_key = self.get_private_key(script_key_id).await?;
let spend_private_key = self.get_private_key(spend_key_id).await?;
let script_private_key = self.get_script_private_key(script_key_id).await?;

let challenge = TransactionInput::finalize_script_signature_challenge(
txi_version,
Expand Down
2 changes: 1 addition & 1 deletion base_layer/core/src/transactions/key_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ pub use memory_db_key_manager::{
};

mod error;
pub use error::CoreKeyManagerError;
pub use error::{CoreKeyManagerError, LedgerDeviceError};
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use tari_key_manager::key_manager_service::KeyManagerServiceError;
use tari_script::ScriptError;
use thiserror::Error;

use crate::transactions::transaction_components::EncryptedDataError;
use crate::transactions::{key_manager::LedgerDeviceError, transaction_components::EncryptedDataError};

//---------------------------------------- TransactionError ----------------------------------------------------//
#[derive(Clone, Debug, PartialEq, Error, Deserialize, Serialize, Eq)]
Expand Down Expand Up @@ -73,6 +73,8 @@ pub enum TransactionError {
KeyManagerError(String),
#[error("EncryptedData error: {0}")]
EncryptedDataError(String),
#[error("Ledger device error: {0}")]
LedgerDeviceError(#[from] LedgerDeviceError),
}

impl From<KeyManagerServiceError> for TransactionError {
Expand Down

0 comments on commit 41934fb

Please sign in to comment.