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