Skip to content

Commit

Permalink
Merge pull request #28 from Zondax/ledger-v5
Browse files Browse the repository at this point in the history
Upgrade to handle v5 transactions
  • Loading branch information
becominginsane authored Nov 11, 2023
2 parents 82181e2 + 8b441b7 commit febfcf7
Show file tree
Hide file tree
Showing 16 changed files with 988 additions and 376 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v2
with:
submodules: true
- run: sudo apt-get install -y libudev-dev libusb-1.0-0-dev
- run: sudo apt-get update && sudo apt-get install -y libudev-dev libusb-1.0-0-dev
- name: show versions
run: |
rustup show
Expand Down Expand Up @@ -57,7 +57,7 @@ jobs:
# setup sharedKey to share cache with other jobs
sharedKey: ${{ github.run_id }}-${{ github.run_attempt }}

- run: sudo apt-get install -y libudev-dev libusb-1.0.0-dev
- run: sudo apt-get update && sudo apt-get install -y libudev-dev libusb-1.0.0-dev
- name: test
run: |
#with --lib we only test the unit tests
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"
members = [
"ledger-zcash",
"zcash-hsmbuilder"
Expand Down
81 changes: 81 additions & 0 deletions ledger-zcash/src/apdu_extra.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*******************************************************************************
* (c) 2023 Zondax AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/

use ledger_transport::{APDUAnswer, APDUCommand, APDUErrorCode, Exchange};
use ledger_zondax_generic::{ChunkPayloadType, LedgerAppError};

use crate::ZcashApp;

impl<E> ZcashApp<E>
where
E: Exchange,
E::Error: std::error::Error,
{
/// Variant of [`ledger_zondax_generic::AppExt::send_chunks`] which sends P2 on all messages
pub(crate) async fn send_chunks_p2_all<I: std::ops::Deref<Target = [u8]> + Send + Sync>(
transport: &E,
command: APDUCommand<I>,
message: &[u8],
) -> Result<APDUAnswer<E::AnswerType>, LedgerAppError<E::Error>> {
const USER_MESSAGE_CHUNK_SIZE: usize = 250;

let chunks = message.chunks(USER_MESSAGE_CHUNK_SIZE);
match chunks.len() {
0 => return Err(LedgerAppError::InvalidEmptyMessage),
n if n > 255 => return Err(LedgerAppError::InvalidMessageSize),
_ => (),
}

if command.p1 != ChunkPayloadType::Init as u8 {
return Err(LedgerAppError::InvalidChunkPayloadType);
}

let p2 = command.p2;

let mut response = transport.exchange(&command).await?;
match response.error_code() {
Ok(APDUErrorCode::NoError) => {}
Ok(err) => return Err(LedgerAppError::AppSpecific(err as _, err.description())),
Err(err) => return Err(LedgerAppError::Unknown(err)),
}

// Send message chunks
let last_chunk_index = chunks.len() - 1;
for (packet_idx, chunk) in chunks.enumerate() {
let mut p1 = ChunkPayloadType::Add as u8;
if packet_idx == last_chunk_index {
p1 = ChunkPayloadType::Last as u8
}

let command = APDUCommand {
cla: command.cla,
ins: command.ins,
p1,
p2,
data: chunk.to_vec(),
};

response = transport.exchange(&command).await?;
match response.error_code() {
Ok(APDUErrorCode::NoError) => {}
Ok(err) => return Err(LedgerAppError::AppSpecific(err as _, err.description())),
Err(err) => return Err(LedgerAppError::Unknown(err)),
}
}

Ok(response)
}
}
27 changes: 21 additions & 6 deletions ledger-zcash/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use crate::zcash::primitives::{
},
transaction::{
components::{Amount, OutPoint},
Transaction,
Transaction, TxVersion,
},
};

Expand Down Expand Up @@ -478,20 +478,33 @@ where
pub async fn checkandsign(
&self,
data: HsmTxData,
tx_version: TxVersion,
) -> Result<[u8; 32], LedgerAppError<E::Error>> {
//this is actually infallible
let data = data.to_hsm_bytes().unwrap();

let hex_tx_version = match tx_version {
TxVersion::Zip225 => 0x05,
TxVersion::Sapling => 0x04,
_ => 0u8,
};
if hex_tx_version == 0u8 {
return Err(LedgerAppError::AppSpecific(
0,
String::from("Unsupported transaction version"),
));
}
let start_command = APDUCommand {
cla: Self::CLA,
ins: INS_CHECKANDSIGN,
p1: ChunkPayloadType::Init as u8,
p2: 0x00,
p2: hex_tx_version,
data: vec![],
};

let response =
<Self as AppExt<E>>::send_chunks(&self.apdu_transport, start_command, &data).await?;
log::info!("checkandsign APDUCommand {:#?}", start_command);
log::info!("hex_tx_version {:#?}", hex_tx_version);

let response = Self::send_chunks_p2_all(&self.apdu_transport, start_command, &data).await?;
log::info!("checkandsign ok");

let response_data = response.data();
Expand Down Expand Up @@ -532,6 +545,7 @@ where
input: DataInput,
parameters: P,
branch: consensus::BranchId,
tx_version: Option<TxVersion>,
target_height: u32,
) -> Result<(Transaction, SaplingMetadata), LedgerAppError<E::Error>> {
log::info!("adding transaction data to builder");
Expand All @@ -547,7 +561,7 @@ where
log::info!("building the transaction");

// Set up a channel to recieve updates on the progress of building the transaction.
let (tx, _) = tokio::sync::mpsc::channel(10);
let (tx, _) = std::sync::mpsc::channel();

let txdata = builder
.build(
Expand All @@ -558,6 +572,7 @@ where
&mut rand_core::OsRng,
target_height,
branch,
tx_version,
Some(tx),
)
.await
Expand Down
4 changes: 3 additions & 1 deletion ledger-zcash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ pub use ledger_zondax_generic::LedgerAppError;
mod app;
pub use app::*;

pub(crate) mod zcash;
pub mod zcash;

/// Ergonomic transaction builder
#[path = "./txbuilder.rs"]
pub mod builder;

mod apdu_extra;
Loading

0 comments on commit febfcf7

Please sign in to comment.