signstar_yubihsm2/user/
mod.rs

1//! User handling for YubiHSM2 devices.
2
3use signstar_crypto::{passphrase::Passphrase, traits::UserWithPassphrase};
4
5/// Credentials for a YubiHSM2 device.
6///
7/// Credentials are mapped to the authentication key ID and the passphrase used as key derivation
8/// function (KDF) for an authentication key.
9#[derive(Clone, Debug)]
10#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
11pub struct Credentials {
12    pub(crate) id: u16,
13    passphrase: Passphrase,
14}
15
16impl Credentials {
17    /// Creates a new [`Credentials`].
18    ///
19    /// # Examples
20    ///
21    /// ```
22    /// use signstar_crypto::passphrase::Passphrase;
23    /// use signstar_yubihsm2::Credentials;
24    ///
25    /// # fn main() -> testresult::TestResult {
26    /// let creds = Credentials::new(1, "this-is-a-passphrase".parse()?);
27    /// # Ok(())
28    /// # }
29    /// ```
30    pub fn new(id: u16, passphrase: Passphrase) -> Self {
31        Self { id, passphrase }
32    }
33}
34
35impl UserWithPassphrase for Credentials {
36    fn user(&self) -> String {
37        self.id.to_string()
38    }
39
40    fn passphrase(&self) -> &Passphrase {
41        &self.passphrase
42    }
43}
44
45impl From<&Credentials> for yubihsm::Credentials {
46    fn from(value: &Credentials) -> Self {
47        Self::from_password(value.id, value.passphrase.expose_borrowed().as_bytes())
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn credentials_user_with_passphrase() {
57        let credentials = Credentials::new(1, Passphrase::generate(None));
58        assert_eq!(credentials.user(), "1");
59        assert_eq!(
60            credentials.passphrase().expose_borrowed().len(),
61            Passphrase::DEFAULT_LENGTH
62        );
63    }
64}