mirror of
https://github.com/trussed-dev/trussed-auth.git
synced 2026-06-20 04:16:21 -07:00
Change PIN data path
This patch changes the path used to store PIN data inside the client namespace from backend-auth/pin/<id> to backend-auth/pin.<id> to make better use of the available space. It also adds documentation for the filesystem layout. Fixes https://github.com/trussed-dev/trussed-auth/issues/9
This commit is contained in:
@@ -22,6 +22,7 @@ subtle = { version = "2.4.1", default-features = false }
|
||||
trussed = { version = "0.1.0", features = ["serde-extensions"] }
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = { version = "1.0.3", default-features = false }
|
||||
rand_core = { version = "0.6.4", default-features = false, features = ["getrandom"] }
|
||||
trussed = { version = "0.1.0", features = ["serde-extensions", "virt"] }
|
||||
|
||||
|
||||
+17
-3
@@ -22,7 +22,7 @@ use trussed::{
|
||||
|
||||
use crate::{
|
||||
extension::{reply, AuthExtension, AuthReply, AuthRequest},
|
||||
PIN_PATH, SALT_PATH,
|
||||
BACKEND_DIR,
|
||||
};
|
||||
use data::{Key, PinData, Salt, KEY_LEN, SALT_LEN};
|
||||
|
||||
@@ -50,6 +50,20 @@ impl fmt::Debug for HardwareKey {
|
||||
///
|
||||
/// This implementation stores PINs together with their retry counters on the filesystem. PINs are
|
||||
/// hashed with SHA-256 using a salt that is generated per PIN.
|
||||
///
|
||||
/// # Filesystem Layout
|
||||
///
|
||||
/// ```text
|
||||
/// trussed/
|
||||
/// backend-auth/
|
||||
/// salt global salt for key derivation
|
||||
/// <client>/
|
||||
/// backend-auth/
|
||||
/// pin.<id> PIN data, can be deleted with DeletePin or DeleteAllPins
|
||||
/// ```
|
||||
///
|
||||
/// The storage location can be set when creating the backend, see [`AuthBackend::new`][] and
|
||||
/// [`AuthBackend::with_hw_key`][].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuthBackend {
|
||||
location: Location,
|
||||
@@ -80,7 +94,7 @@ impl AuthBackend {
|
||||
trussed_filestore: &mut impl Filestore,
|
||||
rng: &mut R,
|
||||
) -> Result<Salt, Error> {
|
||||
let path = PathBuf::from(SALT_PATH);
|
||||
let path = PathBuf::from(BACKEND_DIR).join(&PathBuf::from("salt"));
|
||||
trussed_filestore
|
||||
.read(&path, self.location)
|
||||
.or_else(|_| {
|
||||
@@ -263,7 +277,7 @@ impl ExtensionImpl<AuthExtension> for AuthBackend {
|
||||
Ok(reply::DeletePin.into())
|
||||
}
|
||||
AuthRequest::DeleteAllPins(_) => {
|
||||
fs.remove_dir_all(&PathBuf::from(PIN_PATH), self.location)
|
||||
fs.remove_dir_all(&PathBuf::from(BACKEND_DIR), self.location)
|
||||
.map_err(|_| Error::WriteFailed)?;
|
||||
Ok(reply::DeleteAllPins.into())
|
||||
}
|
||||
|
||||
+29
-6
@@ -1,7 +1,7 @@
|
||||
// Copyright (C) Nitrokey GmbH
|
||||
// SPDX-License-Identifier: Apache-2.0 or MIT
|
||||
|
||||
#![no_std]
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
@@ -80,8 +80,7 @@ pub const MAX_PIN_LENGTH: usize = MAX_SHORT_DATA_LENGTH;
|
||||
/// A PIN.
|
||||
pub type Pin = Bytes<MAX_PIN_LENGTH>;
|
||||
|
||||
const PIN_PATH: &str = "backend-auth/pin";
|
||||
const SALT_PATH: &str = "backend-auth/salt";
|
||||
const BACKEND_DIR: &str = "backend-auth";
|
||||
|
||||
/// The ID of a PIN within the namespace of a client.
|
||||
///
|
||||
@@ -112,9 +111,18 @@ pub struct PinId(u8);
|
||||
|
||||
impl PinId {
|
||||
fn path(&self) -> PathBuf {
|
||||
let mut path = PathBuf::from(PIN_PATH);
|
||||
path.push(&PathBuf::from(&self.hex()));
|
||||
path
|
||||
const PIN_PREFIX: &[u8] = b"/pin.";
|
||||
const N: usize = BACKEND_DIR.len();
|
||||
const M: usize = PIN_PREFIX.len();
|
||||
|
||||
let mut path = [0; N + M + 2];
|
||||
let (backend_dir, rest) = path.split_at_mut(N);
|
||||
let (pin, id) = rest.split_at_mut(M);
|
||||
backend_dir.copy_from_slice(BACKEND_DIR.as_bytes());
|
||||
pin.copy_from_slice(PIN_PREFIX);
|
||||
id.copy_from_slice(&self.hex());
|
||||
|
||||
PathBuf::from(&path)
|
||||
}
|
||||
|
||||
fn hex(&self) -> [u8; 2] {
|
||||
@@ -137,3 +145,18 @@ impl From<PinId> for u8 {
|
||||
id.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PinId;
|
||||
use trussed::types::PathBuf;
|
||||
|
||||
quickcheck::quickcheck! {
|
||||
fn test_pin_path(id: u8) -> bool {
|
||||
let actual = PinId(id).path();
|
||||
let expected = PathBuf::from(format!("backend-auth/pin.{id:02x}").as_str());
|
||||
println!("id: {id}, actual: {actual}, expected: {expected}");
|
||||
actual == expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user