Skip to content

Commit 237f827

Browse files
committed
Transfer changes from other feature branch
1 parent ab9d858 commit 237f827

167 files changed

Lines changed: 204 additions & 83 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
messages = { path = "./messages" }
8-
ledger_device_sdk = "1.34.0"
8+
ledger_device_sdk = "1.35.1"
99
ledger_secure_sdk_sys = "1.16.1"
1010
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
1111
bech32 = { version = "0.11", default-features = false, features = ["alloc"] }

messages/src/lib.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,16 +402,24 @@ pub enum StatusWord {
402402
// Standard Ledger APDU Codes
403403
#[display("Success")]
404404
Ok = 0x9000,
405+
#[display("Nothing received")]
406+
NothingReceived = 0x6982,
405407
#[display("User cancelled")]
406408
Deny = 0x6985,
407409
#[display("CLA not supported")]
408410
ClaNotSupported = 0x6E00,
409-
#[display("Wrong P1/P2 parameters")]
410-
WrongP1P2 = 0x6B00,
411411
#[display("Instruction not supported")]
412-
InsNotSupported = 0x6D00,
412+
InsNotSupported = 0x6E01,
413+
#[display("Wrong P1/P2 parameters")]
414+
WrongP1P2 = 0x6E02,
413415
#[display("Wrong APDU length")]
414-
WrongApduLength = 0x6700,
416+
WrongApduLength = 0x6E03,
417+
#[display("Unknown")]
418+
Unknown = 0x6D00,
419+
#[display("Panic")]
420+
Panic = 0xE000,
421+
#[display("Device locked")]
422+
DeviceLocked = 0x5515,
415423

416424
// App Specific Errors (0xB...)
417425
#[display("Transaction display failed")]
@@ -454,6 +462,8 @@ pub enum StatusWord {
454462
MaxBufferLenExceeded = 0xB012,
455463
#[display("Different input commitment hash")]
456464
DifferentInputCommitmentHash = 0xB013,
465+
#[display("Invalid Timestamp")]
466+
InvalidTimestamp = 0xB014,
457467

458468
// Ecc Errors
459469
#[display("ECC Carry")]

src/errors.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,18 @@ pub fn cx_err_to_status(e: CxError) -> StatusWord {
3939
CxError::GenericError => StatusWord::EccGenericError,
4040
}
4141
}
42+
43+
pub fn sdk_err_to_status(e: ledger_device_sdk::io::StatusWords) -> StatusWord {
44+
match e {
45+
ledger_device_sdk::io::StatusWords::Ok => StatusWord::Ok,
46+
ledger_device_sdk::io::StatusWords::BadCla => StatusWord::ClaNotSupported,
47+
ledger_device_sdk::io::StatusWords::NothingReceived => StatusWord::NothingReceived,
48+
ledger_device_sdk::io::StatusWords::BadIns => StatusWord::InsNotSupported,
49+
ledger_device_sdk::io::StatusWords::BadP1P2 => StatusWord::WrongP1P2,
50+
ledger_device_sdk::io::StatusWords::BadLen => StatusWord::WrongApduLength,
51+
ledger_device_sdk::io::StatusWords::UserCancelled => StatusWord::Deny,
52+
ledger_device_sdk::io::StatusWords::Unknown => StatusWord::Unknown,
53+
ledger_device_sdk::io::StatusWords::Panic => StatusWord::Panic,
54+
ledger_device_sdk::io::StatusWords::DeviceLocked => StatusWord::DeviceLocked,
55+
}
56+
}

src/handlers/sign_tx/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,17 +420,17 @@ fn handle_input_req(
420420
}
421421

422422
fn handle_input_commitment_req(
423-
req: Box<SighashInputCommitment>,
423+
req: &SighashInputCommitment,
424424
mut ctx: Box<TxParsingInputCommitmentsContext>,
425425
review: &NbglStreamingReview,
426426
) -> Result<TxParsingContext, StatusWord> {
427-
update_hash(&req, &mut ctx.input_commitments_hasher)?;
428-
update_hash(&req, &mut ctx.tx_hasher)?;
427+
update_hash(req, &mut ctx.input_commitments_hasher)?;
428+
update_hash(req, &mut ctx.tx_hasher)?;
429429
ctx.advance_next_input_additional_info_step(review)
430430
}
431431

432432
fn handle_output_req(
433-
req: Box<TxOutputReq>,
433+
req: &TxOutputReq,
434434
mut ctx: Box<TxParsingOutputsContext>,
435435
review: &NbglStreamingReview,
436436
) -> Result<TxParsingContext, StatusWord> {
@@ -453,10 +453,10 @@ pub fn handle_sign_tx(
453453
handle_input_req(req, ctx)?
454454
}
455455
(SignTxReq::InputCommitment(req), TxParsingContext::ParsingInputCommitments(ctx)) => {
456-
handle_input_commitment_req(req, ctx, review)?
456+
handle_input_commitment_req(req.as_ref(), ctx, review)?
457457
}
458458
(SignTxReq::Output(req), TxParsingContext::ParsingOutputs(ctx)) => {
459-
handle_output_req(req, ctx, review)?
459+
handle_output_req(req.as_ref(), ctx, review)?
460460
}
461461
(SignTxReq::NextSignature, TxParsingContext::Signing(ctx)) => {
462462
TxParsingContext::Signing(ctx)

src/main.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,14 @@ use app_ui::menu::ui_menu_main;
4747
use handlers::{
4848
get_public_key::handle_get_public_key,
4949
sign_message::{handle_sign_message, setup_sign_message, SignMessageContext},
50-
sign_tx::{setup_sign_tx, TxParsingContext},
50+
sign_tx::{setup_sign_tx, TxParsingContext, handle_sign_tx},
5151
};
52+
use errors::sdk_err_to_status;
5253
use messages::{
5354
decode_all, encode, Ins, PubKeyP1, Response, SignP1, StatusWord, APDU_CLASS, MAX_ADPU_DATA_LEN,
5455
P2_DONE, P2_MORE,
5556
};
5657

57-
use crate::handlers::sign_tx::handle_sign_tx;
58-
5958
ledger_device_sdk::set_panic!(ledger_device_sdk::exiting_panic);
6059

6160
pub const MAX_BUFFER_LEN: usize = 4 * MAX_ADPU_DATA_LEN;
@@ -98,7 +97,7 @@ impl ApduTransport {
9897
/// - If `P2 == P2_DONE`, it finishes accumulation and returns `Ok(Some(RawInstruction))`.
9998
pub fn receive(&mut self, comm: &mut Comm) -> Result<ReceiveInstructionResult, StatusWord> {
10099
let header: ApduHeader = comm.next_command();
101-
let data = comm.get_data().map_err(|_| StatusWord::WrongApduLength)?;
100+
let data = comm.get_data().map_err(sdk_err_to_status)?;
102101

103102
// Validation: If we are in the middle of a stream, INS and P1 must match
104103
if let (Some(curr_ins), Some(curr_p1)) = (self.current_ins, self.current_p1) {
@@ -331,8 +330,7 @@ fn handle_command(cmd: &Command, ctx: &mut AppContext) -> Result<Response, Statu
331330
Some(DataContext::SignMessageContext(ctx)) => ctx,
332331
_ => return Err(StatusWord::WrongContext),
333332
};
334-
let response = handle_sign_message(data, msg_ctx).map(Response::MessageSignature);
335-
response
333+
handle_sign_message(data, msg_ctx).map(Response::MessageSignature)
336334
}
337335
},
338336
Command::Ping => Ok(Response::Pong),

tests/application_client/mintlayer_command_sender.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222

2323
CLA: int = 0xE1
2424

25+
@dataclass
26+
class ReviewTransaction:
27+
transaction: Transaction
28+
has_command_input: bool
29+
review_custom_screen_text: str
2530

2631
@dataclass
2732
class SignTxStep:
@@ -65,8 +70,8 @@ class InsType(IntEnum):
6570
class Errors(IntEnum):
6671
SW_DENY = 0x6985
6772
SW_CLA_NOT_SUPPORTED = 0x6E00
68-
SW_INS_NOT_SUPPORTED = 0x6D00
69-
SW_WRONG_P1P2 = 0x6B00
73+
SW_INS_NOT_SUPPORTED = 0x6E01
74+
SW_WRONG_P1P2 = 0x6E02
7075
SW_WRONG_APDU_LENGTH = 0x6E03
7176

7277
SW_WRONG_RESPONSE_LENGTH = 0xB000
@@ -137,11 +142,19 @@ def sign_message(
137142

138143
for chunk in chunks[:-1]:
139144
self.backend.exchange(
140-
cla=CLA, ins=InsType.SIGN_MESSAGE, p1=SignMessageP1.P1_NEXT, p2=P2.P2_MORE, data=chunk
145+
cla=CLA,
146+
ins=InsType.SIGN_MESSAGE,
147+
p1=SignMessageP1.P1_NEXT,
148+
p2=P2.P2_MORE,
149+
data=chunk
141150
)
142151

143152
with self.backend.exchange_async(
144-
cla=CLA, ins=InsType.SIGN_MESSAGE, p1=SignMessageP1.P1_NEXT, p2=P2.P2_LAST, data=chunks[-1]
153+
cla=CLA,
154+
ins=InsType.SIGN_MESSAGE,
155+
p1=SignMessageP1.P1_NEXT,
156+
p2=P2.P2_LAST,
157+
data=chunks[-1]
145158
) as response:
146159
yield response
147160

@@ -202,7 +215,7 @@ def sign_tx(self, transaction: Transaction) -> Generator[SignTxStep, None, None]
202215
):
203216
kind = "start"
204217
yield SignTxStep(kind=kind, index=0)
205-
218+
206219

207220
# ---- OUTPUTS ----
208221
print("streaming outputs")
@@ -301,7 +314,17 @@ def pack_derivation_path(derivation_path: str) -> bytes:
301314
return path_obj.encode(path).data
302315

303316

304-
def sign_tx_review(client, device, navigator, scenario_navigator, transaction, has_command_input, review_custom_screen_text):
317+
def sign_tx_review(
318+
client,
319+
device,
320+
navigator,
321+
scenario_navigator,
322+
review_transaction: ReviewTransaction,
323+
):
324+
transaction = review_transaction.transaction
325+
has_command_input = review_transaction.has_command_input
326+
review_custom_screen_text = review_transaction.review_custom_screen_text
327+
305328
start_idx = 0
306329
if not device.is_nano:
307330
instruction = NavInsID.SWIPE_CENTER_TO_LEFT
@@ -370,7 +393,11 @@ def sign_tx_review(client, device, navigator, scenario_navigator, transaction, h
370393
start_idx += 10
371394

372395
elif step.kind == "final":
373-
scenario = NavigationScenarioData(scenario_navigator.device, scenario_navigator.backend, UseCase.TX_REVIEW, True)
396+
scenario = NavigationScenarioData(
397+
scenario_navigator.device,
398+
scenario_navigator.backend,
399+
UseCase.TX_REVIEW,
400+
True)
374401
navigator.navigate_until_text_and_compare(
375402
navigate_instruction=scenario.navigation,
376403
validation_instructions=scenario.validation,
@@ -386,4 +413,4 @@ def sign_tx_review(client, device, navigator, scenario_navigator, transaction, h
386413

387414
assert len(responses) == len(transaction.inputs)
388415
for response in responses:
389-
assert len(response) == TX_RESPONSE_SIZE
416+
assert len(response) == TX_RESPONSE_SIZE

tests/application_client/mintlayer_response_unpacker.py

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,7 @@ def unpack_get_app_and_version_response(response: bytes) -> Tuple[str, str]:
5151

5252

5353
# Unpack from response:
54-
# response = pub_key_len (1)
55-
# pub_key (var)
56-
# chain_code_len (1)
57-
# chain_code (var)
5854
def unpack_get_public_key_response(response: bytes) -> Tuple[int, bytes, int, bytes]:
59-
print("response bytes: ", len(response))
6055
response_bytes = scalecodec.base.ScaleBytes(response)
6156
response_obj = scalecodec.base.RuntimeConfiguration().create_scale_object(
6257
"Response", data=response_bytes
@@ -79,24 +74,13 @@ def unpack_get_public_key_response(response: bytes) -> Tuple[int, bytes, int, by
7974

8075

8176
# Unpack from response:
82-
# response = sig_len (1)
83-
# sig (var)
84-
def unpack_sign_message_response(response: bytes) -> Tuple[int, bytes]:
85-
response, sig_len, sig = pop_size_prefixed_buf_from_buf(response)
86-
87-
assert sig_len == 64
88-
assert len(response) == 0
89-
return sig_len, sig
90-
91-
92-
# Unpack from response:
93-
# response = der_sig_len (1)
94-
# der_sig (var)
95-
# v (1)
96-
def unpack_sign_tx_response(response: bytes) -> Tuple[int, bytes, int]:
97-
response, der_sig_len, der_sig = pop_size_prefixed_buf_from_buf(response)
98-
response, v = pop_sized_buf_from_buffer(response, 1)
99-
100-
assert len(response) == 0
101-
102-
return der_sig_len, der_sig, int.from_bytes(v, byteorder="big")
77+
def unpack_sign_message_response(response: bytes) -> bytes:
78+
response_bytes = scalecodec.base.ScaleBytes(response)
79+
response_obj = scalecodec.base.RuntimeConfiguration().create_scale_object(
80+
"Response", data=response_bytes
81+
)
82+
resp = response_obj.decode()
83+
assert resp["MessageSignature"] is not None
84+
signature = bytes.fromhex(resp["MessageSignature"]["signature"][2:])
85+
assert len(signature) == 64
86+
return signature
-45 Bytes
576 Bytes

0 commit comments

Comments
 (0)