mirror of
https://github.com/trussed-dev/usbd-ccid.git
synced 2026-06-20 04:16:20 -07:00
Soo close to setup. Need some CCID fixes
This commit is contained in:
@@ -14,6 +14,7 @@ heapless-bytes = { git = "https://github.com/ycrypto/heapless-bytes", branch = "
|
||||
# heapless-bytes = { path = "../../../heapless-bytes" }
|
||||
interchange = { path = "../interchange" }
|
||||
iso7816 = { path = "../iso7816" }
|
||||
untrusted = "0.7.1"
|
||||
usb-device = { version = "0.2.3", features = ["control-buffer-256"] }
|
||||
|
||||
[features]
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
pub use untrusted::{Input, Reader};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Error {
|
||||
HighTagNumberForm,
|
||||
LongLengthNotSupported,
|
||||
NonCanonical,
|
||||
Read,
|
||||
UnexpectedEnd,
|
||||
WrongTag,
|
||||
WrongValue,
|
||||
}
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
|
||||
impl From<untrusted::EndOfInput> for Error {
|
||||
fn from(_: untrusted::EndOfInput) -> Error {
|
||||
Error::UnexpectedEnd
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the value of the given tag and apply a decoding function to it.
|
||||
pub fn nested<'a, F, R>(input: &mut Reader<'a>, tag: u8, decoder: F) -> Result<R>
|
||||
where
|
||||
F: FnOnce(&mut untrusted::Reader<'a>) -> Result<R>,
|
||||
{
|
||||
let inner = expect_tag_and_get_value(input, tag)?;
|
||||
inner.read_all(Error::Read, decoder)
|
||||
}
|
||||
|
||||
/// Read a tag and return it's value. Errors when the expect and actual tag do not match.
|
||||
pub fn expect_tag_and_get_value<'a>(input: &mut Reader<'a>, tag: u8) -> Result<Input<'a>> {
|
||||
let (actual_tag, inner) = read_tag_and_get_value(input)?;
|
||||
if usize::from(tag) != usize::from(actual_tag) {
|
||||
return Err(Error::WrongTag);
|
||||
}
|
||||
Ok(inner)
|
||||
}
|
||||
|
||||
/// Read a tag and its value. Errors when the expected and actual tag and values do not match.
|
||||
pub fn expect_tag_and_value<'a>(input: &mut Reader<'a>, tag: u8, value: &[u8]) -> Result<()> {
|
||||
let (actual_tag, inner) = read_tag_and_get_value(input)?;
|
||||
if usize::from(tag) != usize::from(actual_tag) {
|
||||
return Err(Error::WrongTag);
|
||||
}
|
||||
if value != inner.as_slice_less_safe() {
|
||||
return Err(Error::WrongValue);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read the next tag, and return it and its value.
|
||||
pub fn read_tag_and_get_value<'a>(input: &mut Reader<'a>) -> Result<(u8, Input<'a>)> {
|
||||
let tag = input.read_byte()?;
|
||||
if (tag & 0x1F) == 0x1F {
|
||||
return Err(Error::HighTagNumberForm);
|
||||
}
|
||||
|
||||
// If the high order bit of the first byte is set to zero then the length
|
||||
// is encoded in the seven remaining bits of that byte. Otherwise, those
|
||||
// seven bits represent the number of bytes used to encode the length.
|
||||
let length = match input.read_byte()? {
|
||||
n if (n & 0x80) == 0 => usize::from(n),
|
||||
0x81 => {
|
||||
let second_byte = input.read_byte()?;
|
||||
if second_byte < 128 {
|
||||
return Err(Error::NonCanonical);
|
||||
}
|
||||
usize::from(second_byte)
|
||||
}
|
||||
0x82 => {
|
||||
let second_byte = usize::from(input.read_byte()?);
|
||||
let third_byte = usize::from(input.read_byte()?);
|
||||
let combined = (second_byte << 8) | third_byte;
|
||||
if combined < 256 {
|
||||
return Err(Error::NonCanonical);
|
||||
}
|
||||
combined
|
||||
}
|
||||
_ => return Err(Error::LongLengthNotSupported),
|
||||
};
|
||||
|
||||
let inner = input.read_bytes(length)?;
|
||||
Ok((tag, inner))
|
||||
}
|
||||
@@ -5,7 +5,10 @@
|
||||
|
||||
pub mod constants;
|
||||
pub mod class;
|
||||
// writer
|
||||
pub mod der;
|
||||
// parser
|
||||
pub mod derp;
|
||||
pub mod pipe;
|
||||
pub mod types;
|
||||
|
||||
|
||||
+3
-3
@@ -190,7 +190,7 @@ where
|
||||
self.interchange.request(command).expect("could not deposit command");
|
||||
// apdu::Command::try_from(&self.message).unwrap()
|
||||
// ).expect("could not deposit command");
|
||||
hprintln!("set ccid state to processing").ok();
|
||||
// hprintln!("set ccid state to processing").ok();
|
||||
self.state = State::Processing;
|
||||
// todo!("have message of length {} to dispatch", self.message.len());
|
||||
}
|
||||
@@ -205,8 +205,8 @@ where
|
||||
// }
|
||||
// }
|
||||
if let State::Processing = self.state {
|
||||
hprintln!("processing, checking for response, interchange state {:?}",
|
||||
self.interchange.state()).ok();
|
||||
// hprintln!("processing, checking for response, interchange state {:?}",
|
||||
// self.interchange.state()).ok();
|
||||
|
||||
if let Some(response) = self.interchange.take_response() {
|
||||
self.message = response.into_message();
|
||||
|
||||
Reference in New Issue
Block a user