Skip to content

Commit

Permalink
Use references for ctap1
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-nitrokey committed Jun 18, 2024
1 parent 4cefc05 commit e188ab2
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 26 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Replace `cose` module with `cosey` dependency ([#36][])
- Mark `get_assertion::{ExtensionsInput, ExtensionsOutput}` and `make_credential::Extensions` as non-exhaustive and implement `Default`
- Mark CTAP2 request and response types as non-exhaustive where possible
- Use references for `AuthenticatorData` and `get_assertion::Request` where possible
- Use references where possible

[#8]: https://github.com/trussed-dev/ctap-types/pull/8
[#9]: https://github.com/solokeys/ctap-types/issues/9
Expand Down
2 changes: 1 addition & 1 deletion src/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub use ctap2::Authenticator as Ctap2Authenticator;
// - second is 10456 bytes
#[allow(clippy::large_enum_variant)]
pub enum Request<'a> {
Ctap1(ctap1::Request),
Ctap1(ctap1::Request<'a>),
Ctap2(ctap2::Request<'a>),
}

Expand Down
51 changes: 27 additions & 24 deletions src/ctap1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ pub mod authenticate {
use super::{Bytes, ControlByte};

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Request {
pub struct Request<'a> {
pub control_byte: ControlByte,
pub challenge: Bytes<32>,
pub app_id: Bytes<32>,
pub key_handle: Bytes<255>,
pub challenge: &'a [u8],
pub app_id: &'a [u8],
pub key_handle: &'a [u8],
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand All @@ -32,9 +32,9 @@ pub mod register {
use super::Bytes;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Request {
pub challenge: Bytes<32>,
pub app_id: Bytes<32>,
pub struct Request<'a> {
pub challenge: &'a [u8],
pub app_id: &'a [u8],
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -112,9 +112,9 @@ impl TryFrom<u8> for ControlByte {
pub type Result<T> = core::result::Result<T, Error>;

/// Type alias for convenience.
pub type Register = register::Request;
pub type Register<'a> = register::Request<'a>;
/// Type alias for convenience.
pub type Authenticate = authenticate::Request;
pub type Authenticate<'a> = authenticate::Request<'a>;

/// Type alias for convenience.
pub type RegisterResponse = register::Response;
Expand All @@ -124,9 +124,9 @@ pub type AuthenticateResponse = authenticate::Response;
#[derive(Clone, Debug, Eq, PartialEq)]
#[allow(clippy::large_enum_variant)]
/// Enum of all CTAP1 requests.
pub enum Request {
Register(register::Request),
Authenticate(authenticate::Request),
pub enum Request<'a> {
Register(register::Request<'a>),
Authenticate(authenticate::Request<'a>),
Version,
}

Expand Down Expand Up @@ -165,10 +165,10 @@ impl Response {
}
}

impl<const S: usize> TryFrom<&iso7816::Command<S>> for Request {
impl<'a, const S: usize> TryFrom<&'a iso7816::Command<S>> for Request<'a> {
type Error = Error;
#[inline(never)]
fn try_from(apdu: &iso7816::Command<S>) -> Result<Request> {
fn try_from(apdu: &'a iso7816::Command<S>) -> Result<Request> {
let cla = apdu.class().into_inner();
let ins = match apdu.instruction() {
iso7816::Instruction::Unknown(ins) => ins,
Expand Down Expand Up @@ -196,8 +196,8 @@ impl<const S: usize> TryFrom<&iso7816::Command<S>> for Request {
return Err(Error::IncorrectDataParameter);
}
Ok(Request::Register(Register {
challenge: Bytes::from_slice(&request[..32]).unwrap(),
app_id: Bytes::from_slice(&request[32..]).unwrap(),
challenge: &request[..32],
app_id: &request[32..],
}))
}

Expand All @@ -213,9 +213,9 @@ impl<const S: usize> TryFrom<&iso7816::Command<S>> for Request {
}
Ok(Request::Authenticate(Authenticate {
control_byte,
challenge: Bytes::from_slice(&request[..32]).unwrap(),
app_id: Bytes::from_slice(&request[32..64]).unwrap(),
key_handle: Bytes::from_slice(&request[65..]).unwrap(),
challenge: &request[..32],
app_id: &request[32..64],
key_handle: &request[65..],
}))
}

Expand All @@ -233,16 +233,19 @@ impl<const S: usize> TryFrom<&iso7816::Command<S>> for Request {
/// [`Response`].
pub trait Authenticator {
/// Register a U2F credential.
fn register(&mut self, request: &register::Request) -> Result<register::Response>;
fn register(&mut self, request: &register::Request<'_>) -> Result<register::Response>;
/// Authenticate with a U2F credential.
fn authenticate(&mut self, request: &authenticate::Request) -> Result<authenticate::Response>;
fn authenticate(
&mut self,
request: &authenticate::Request<'_>,
) -> Result<authenticate::Response>;
/// Supported U2F version.
fn version() -> [u8; 6] {
*b"U2F_V2"
}

#[inline(never)]
fn call_ctap1(&mut self, request: &Request) -> Result<Response> {
fn call_ctap1(&mut self, request: &Request<'_>) -> Result<Response> {
match request {
Request::Register(reg) => {
debug_now!("CTAP1.REG");
Expand All @@ -257,9 +260,9 @@ pub trait Authenticator {
}
}

impl<A: Authenticator> crate::Rpc<Error, Request, Response> for A {
impl<A: Authenticator> crate::Rpc<Error, Request<'_>, Response> for A {
/// Dispatches the enum of possible requests into the appropriate trait method.
fn call(&mut self, request: &Request) -> Result<Response> {
fn call(&mut self, request: &Request<'_>) -> Result<Response> {
self.call_ctap1(request)
}
}

0 comments on commit e188ab2

Please sign in to comment.