#![no_std]
#![no_main]
use include_gif::include_gif;
use ledger_device_sdk::ecc::CurvesId;
use ledger_device_sdk::hash::HashInit;
use ledger_device_sdk::io::{ApduHeader, StatusWords};
use ledger_device_sdk::nbgl::{NbglGlyph, NbglHomeAndSettings, init_comm};
use ledger_device_sdk::pki::pki_check_signature;
ledger_device_sdk::set_panic!(ledger_device_sdk::exiting_panic);
ledger_device_sdk::define_comm!(COMM);
pub enum Instruction {
GetVersion = 0x01,
GetAppName = 0x02,
CheckPki = 0x03,
}
impl TryFrom<ApduHeader> for Instruction {
type Error = StatusWords;
fn try_from(value: ApduHeader) -> Result<Self, Self::Error> {
match value.ins {
1 => Ok(Instruction::GetVersion),
2 => Ok(Instruction::GetAppName),
3 => Ok(Instruction::CheckPki),
_ => Err(StatusWords::NothingReceived),
}
}
}
#[unsafe(no_mangle)]
extern "C" fn sample_main() {
let comm = init_comm(&COMM);
#[cfg(target_os = "apex_p")]
const FERRIS: NbglGlyph =
NbglGlyph::from_include(include_gif!("examples/crab_48x48.png", NBGL));
#[cfg(any(target_os = "stax", target_os = "flex"))]
const FERRIS: NbglGlyph =
NbglGlyph::from_include(include_gif!("examples/crab_64x64.gif", NBGL));
#[cfg(any(target_os = "nanosplus", target_os = "nanox"))]
const FERRIS: NbglGlyph =
NbglGlyph::from_include(include_gif!("examples/crab_14x14.png", NBGL));
let mut home = NbglHomeAndSettings::new()
.glyph(&FERRIS)
.infos(
"PKI Example App",
env!("CARGO_PKG_VERSION"),
env!("CARGO_PKG_AUTHORS"),
)
.tagline("Send APDU from apdu folder");
home.show_and_return();
loop {
let cmd = comm.next_command();
let ins = cmd.decode::<Instruction>();
match ins {
Ok(Instruction::GetVersion) => {
ledger_device_sdk::log::info!("GetVersion");
let version = [0, 1, 0]; let _ = cmd.reply(&version, StatusWords::Ok);
}
Ok(Instruction::GetAppName) => {
let app_name = b"PKI Example";
let _ = cmd.reply(app_name, StatusWords::Ok);
}
Ok(Instruction::CheckPki) => {
ledger_device_sdk::log::info!("Starting PKI Check");
let buffer = cmd.get_data();
let mut data = [0u8; 80];
data.copy_from_slice(&buffer[..80]);
let mut signature = [0u8; 72];
signature.copy_from_slice(&buffer[82..]);
let mut hasher = ledger_device_sdk::hash::sha2::Sha2_256::new();
let mut hash_data = [0u8; 32];
let _ = hasher.hash(&data[..], &mut hash_data);
match pki_check_signature(
&mut hash_data[..],
8u8,
CurvesId::Secp256k1,
signature.as_mut_slice(),
) {
Ok(()) => {
ledger_device_sdk::log::info!("PKI Check successful");
let _ = cmd.reply(&[], StatusWords::Ok);
}
Err(err) => {
ledger_device_sdk::log::info!("PKI Check failed");
let _ = cmd.reply(&[], err);
}
}
}
Err(sw) => {
let _ = cmd.reply(&[], sw);
}
}
}
}