Skip to main content

signstar_crypto/key/base/
yubihsm2.rs

1//! YubiHSM2 specific integration for cryptographic keys.
2
3use yubihsm::{
4    Algorithm,
5    asymmetric::Algorithm as AsymmetricAlgorithm,
6    authentication::Algorithm as AuthenticationAlgorithm,
7    ecdh::Algorithm as EcdhAlgorithm,
8    ecdsa::Algorithm as EcdsaAlgorithm,
9    hmac::Algorithm as HmacAlgorithm,
10    opaque::Algorithm as OpaqueAlgorithm,
11    otp::Algorithm as OtpAlgorithm,
12    rsa::Algorithm as RsaAlgorithm,
13    rsa::mgf::Algorithm as RsaMgfAlgorithm,
14    template::Algorithm as TemplateAlgorithm,
15    wrap::Algorithm as WrapAlgorithm,
16};
17
18use crate::key::{Error, KeyType};
19
20impl TryFrom<Algorithm> for KeyType {
21    type Error = crate::Error;
22
23    /// Creates a new [`KeyType`] from an [`Algorithm`].
24    ///
25    /// # Note
26    ///
27    /// The semantic abstraction for types of keys and their inherent capabilities differs in
28    /// [`yubihsm`] and [`signstar_crypto`][`crate`]. Hence, this conversion is only an
29    /// approximation and other abstractions (e.g. [`KeyMechanism`][`crate::key::KeyMechanism`]
30    /// and [`SignatureType`][`crate::key::SignatureType`]) may need to be considered in
31    /// addition.
32    ///
33    /// # Errors
34    ///
35    /// Returns an error, if an [`Algorithm`] is encountered, that either does not map directly to a
36    /// [`KeyType`] or describes other functionality (e.g. a hash function).
37    fn try_from(value: Algorithm) -> Result<Self, Self::Error> {
38        Ok(match value {
39            Algorithm::Asymmetric(algorithm) => match algorithm {
40                AsymmetricAlgorithm::Rsa2048
41                | AsymmetricAlgorithm::Rsa3072
42                | AsymmetricAlgorithm::Rsa4096 => KeyType::Rsa,
43                AsymmetricAlgorithm::Ed25519 => KeyType::Curve25519,
44                AsymmetricAlgorithm::EcP224 => KeyType::EcP224,
45                AsymmetricAlgorithm::EcP256 => KeyType::EcP256,
46                AsymmetricAlgorithm::EcP384 => KeyType::EcP384,
47                AsymmetricAlgorithm::EcP521 => KeyType::EcP521,
48                AsymmetricAlgorithm::EcK256 => KeyType::EcK256,
49                AsymmetricAlgorithm::EcBp256 => KeyType::EcBp256,
50                AsymmetricAlgorithm::EcBp384 => KeyType::EcBp384,
51                AsymmetricAlgorithm::EcBp512 => KeyType::EcBp512,
52            },
53            Algorithm::Authentication(AuthenticationAlgorithm::YubicoAes) => KeyType::Generic,
54            Algorithm::Ecdh(EcdhAlgorithm::Ecdh) => {
55                return Err(Error::YubiHsm2AlgorithmNotAKeyType {
56                    algorithm: value,
57                    context: "it is an Elliptic-curve Diffie-Hellman (ECDH) protocol",
58                }
59                .into());
60            }
61            Algorithm::Ecdsa(algorithm) => match algorithm {
62                EcdsaAlgorithm::Sha1
63                | EcdsaAlgorithm::Sha256
64                | EcdsaAlgorithm::Sha384
65                | EcdsaAlgorithm::Sha512 => {
66                    return Err(Error::YubiHsm2AlgorithmNotAKeyType {
67                        algorithm: value,
68                        context: "it is a hash function",
69                    }
70                    .into());
71                }
72            },
73
74            Algorithm::Hmac(algorithm) => match algorithm {
75                HmacAlgorithm::Sha1
76                | HmacAlgorithm::Sha256
77                | HmacAlgorithm::Sha384
78                | HmacAlgorithm::Sha512 => {
79                    return Err(Error::YubiHsm2AlgorithmNotAKeyType {
80                        algorithm: value,
81                        context: "it is a hash-based message authentication code (HMAC)",
82                    }
83                    .into());
84                }
85            },
86            Algorithm::Mgf(algorithm) => match algorithm {
87                RsaMgfAlgorithm::Sha1
88                | RsaMgfAlgorithm::Sha256
89                | RsaMgfAlgorithm::Sha384
90                | RsaMgfAlgorithm::Sha512 => KeyType::Rsa,
91            },
92            Algorithm::Opaque(algorithm) => match algorithm {
93                OpaqueAlgorithm::Data | OpaqueAlgorithm::X509Certificate => {
94                    return Err(Error::YubiHsm2AlgorithmNotAKeyType {
95                        algorithm: value,
96                        context: "it is data",
97                    }
98                    .into());
99                }
100            },
101            Algorithm::Rsa(algorithm) => match algorithm {
102                RsaAlgorithm::Oaep(_) => KeyType::Rsa,
103                RsaAlgorithm::Pkcs1(_) => KeyType::Rsa,
104                RsaAlgorithm::Pss(_) => KeyType::Rsa,
105            },
106            Algorithm::Template(TemplateAlgorithm::Ssh) => {
107                return Err(Error::YubiHsm2AlgorithmNotAKeyType {
108                    algorithm: value,
109                    context: "it is an SSH template",
110                }
111                .into());
112            }
113            Algorithm::Wrap(algorithm) => match algorithm {
114                WrapAlgorithm::Aes128Ccm | WrapAlgorithm::Aes192Ccm | WrapAlgorithm::Aes256Ccm => {
115                    KeyType::Generic
116                }
117            },
118            Algorithm::YubicoOtp(algorithm) => match algorithm {
119                OtpAlgorithm::Aes128 | OtpAlgorithm::Aes192 | OtpAlgorithm::Aes256 => {
120                    KeyType::Generic
121                }
122            },
123        })
124    }
125}