Skip to main content

signstar_yubihsm2/
user.rs

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