Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client_pin: Add permissions #30

Merged
merged 1 commit into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Remove unused `REALISTIC_MAX_MESSAGE_SIZE` constant
- Handle overlong `icon` values in `PublicKeyCredentialUserEntity` ([#27][])
- Update for compatibility with PIN protocol 2
- Add support for permissions in `ctap2::client_pin`

[#8]: https://github.com/trussed-dev/ctap-types/pull/8
[#9]: https://github.com/solokeys/ctap-types/issues/9
Expand Down
43 changes: 41 additions & 2 deletions src/ctap2/client_pin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::Bytes;
use crate::{Bytes, String};
use bitflags::bitflags;
use serde_indexed::{DeserializeIndexed, SerializeIndexed};
use serde_repr::{Deserialize_repr, Serialize_repr};

Expand All @@ -17,6 +18,18 @@ pub enum PinV1Subcommand {
GetPinUvAuthTokenUsingPinWithPermissions = 0x09,
}

bitflags! {
#[derive(Default)]
pub struct Permissions: u8 {
const MAKE_CREDENTIAL = 0x01;
const GET_ASSERTION = 0x02;
const CREDENTIAL_MANAGEMENT = 0x04;
const BIO_ENROLLMENT = 0x08;
const LARGE_BLOB_WRITE = 0x10;
const AUTHENTICATOR_CONFIGURATION = 0x20;
}
}

// minimum PIN length: 4 unicode
// maximum PIN length: UTF-8 represented by <= 63 bytes
// maximum consecutive incorrect PIN attempts: 8
Expand Down Expand Up @@ -55,9 +68,27 @@ pub struct Request {
// Encrypted first 16 bytes of SHA-256 of PIN using `sharedSecret`.
#[serde(skip_serializing_if = "Option::is_none")]
pub pin_hash_enc: Option<Bytes<80>>,

// 0x07
#[serde(skip_serializing_if = "Option::is_none")]
_placeholder07: Option<()>,

// 0x08
#[serde(skip_serializing_if = "Option::is_none")]
_placeholder08: Option<()>,

// 0x09
// Bitfield of permissions
#[serde(skip_serializing_if = "Option::is_none")]
pub permissions: Option<u8>,

// 0x0A
// The RP ID to assign as the permissions RP ID
#[serde(skip_serializing_if = "Option::is_none")]
pub rp_id: Option<String<256>>,
}

#[derive(Clone, Debug, Eq, PartialEq, SerializeIndexed, DeserializeIndexed)]
#[derive(Clone, Debug, Default, Eq, PartialEq, SerializeIndexed, DeserializeIndexed)]
#[serde_indexed(offset = 1)]
pub struct Response {
// 0x01, like ClientPinParameters::key_agreement
Expand All @@ -71,6 +102,14 @@ pub struct Response {
// 0x03, number of PIN attempts remaining before lockout
#[serde(skip_serializing_if = "Option::is_none")]
pub retries: Option<u8>,

// 0x04, whether a power cycle is required before any future PIN operation
#[serde(skip_serializing_if = "Option::is_none")]
pub power_cycle_state: Option<bool>,

// 0x05, number of uv attempts remaining before lockout
#[serde(skip_serializing_if = "Option::is_none")]
pub uv_retries: Option<u8>,
}

#[cfg(test)]
Expand Down
Loading