use super::{Comm, StatusWords};
use ledger_secure_sdk_sys::*;
#[cfg(feature = "stack_usage")]
use crate::io_legacy::BOLOS_INS_STACK_CONSUMPTION;
use crate::io_legacy::{
BOLOS_INS_GET_VERSION, BOLOS_INS_QUIT, BOLOS_INS_SET_PKI_CERT, PkiLoadCertificateError,
SyscallError,
};
pub(crate) fn handle_bolos_apdu<const N: usize>(comm: &mut Comm<N>, ins: u8, p1: u8, p2: u8) {
match ins {
BOLOS_INS_GET_VERSION => {
let mut response = comm.begin_response();
let _ = response.append(&[0x01]);
const MAX_TAG_LENGTH: u8 = 32; let mut tag_buf = [0u8; MAX_TAG_LENGTH as usize];
let name_len = unsafe {
os_registry_get_current_app_tag(
BOLOS_TAG_APPNAME,
tag_buf.as_mut_ptr(),
MAX_TAG_LENGTH as u32,
)
};
if name_len > MAX_TAG_LENGTH.into() {
let _ = response.send(StatusWords::Panic); return;
}
let _ = response.append(&[name_len as u8]);
let _ = response.append(&tag_buf[..name_len as usize]);
let ver_len = unsafe {
os_registry_get_current_app_tag(
BOLOS_TAG_APPVERSION,
tag_buf.as_mut_ptr(),
MAX_TAG_LENGTH as u32,
)
};
if ver_len > MAX_TAG_LENGTH.into() {
let _ = response.send(StatusWords::Panic); return;
}
let _ = response.append(&[ver_len as u8]);
let _ = response.append(&tag_buf[..ver_len as usize]);
let flags_byte = unsafe { os_flags() } as u8;
let _ = response.append(&[1]);
let _ = response.append(&[flags_byte]);
let _ = response.send(StatusWords::Ok);
}
BOLOS_INS_QUIT => {
let _ = comm.begin_response().send(StatusWords::Ok);
crate::exit_app(0);
}
BOLOS_INS_SET_PKI_CERT => unsafe {
let public_key = cx_ecfp_384_public_key_t::default();
let err = os_pki_load_certificate(
comm.buf[3], comm.buf[6..].as_mut_ptr(), comm.buf[5] as usize, core::ptr::null_mut(),
core::ptr::null_mut(),
&public_key as *const cx_ecfp_384_public_key_t as *mut cx_ecfp_384_public_key_t,
);
if err != 0 {
let _ = comm
.begin_response()
.send(SyscallError::from(PkiLoadCertificateError::from(err)));
} else {
let _ = comm.begin_response().send(StatusWords::Ok);
}
},
#[cfg(feature = "stack_usage")]
BOLOS_INS_STACK_CONSUMPTION => {
crate::testing::handle_stack_consumption_apdu_new(p1, p2, comm);
}
_ => {
let _ = comm.begin_response().send(StatusWords::BadIns);
}
}
}