nethsm/
key.rs

1use std::{fmt::Display, str::FromStr};
2
3use base64ct::{Base64, Encoding};
4use nethsm_sdk_rs::models::KeyPrivateData;
5use rsa::{
6    RsaPrivateKey,
7    pkcs8::DecodePrivateKey,
8    traits::PrivateKeyParts,
9    traits::PublicKeyParts,
10};
11use serde::{Deserialize, Serialize};
12
13use crate::{KeyMechanism, KeyType, OpenPgpUserIdList, OpenPgpVersion, SignatureType, TlsKeyType};
14
15/// The minimum bit length for an RSA key
16///
17/// This follows recommendations from [NIST Special Publication 800-57 Part 3 Revision 1](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf) (January 2015).
18pub const MIN_RSA_BIT_LENGTH: u32 = 2048;
19
20/// A unique key identifier for a private key on a NetHSM.
21///
22/// A [`KeyId`]s must be in the character set `[a-z0-9]`.
23/// It is used in [key management] on a NetHSM and is unique in its scope.
24/// The same [`KeyId`] may exist system-wide and in one or several [namespaces], but no duplicate
25/// [`KeyId`] can exist system-wide or in the same namespace.
26///
27/// [key management]: https://docs.nitrokey.com/nethsm/operation#key-management
28/// [namespaces]: https://docs.nitrokey.com/nethsm/administration#namespaces
29#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
30#[serde(into = "String", try_from = "String")]
31pub struct KeyId(String);
32
33impl KeyId {
34    /// Constructs a new Key ID from a `String`.
35    ///
36    /// Validates the input string and returns [`crate::Error::Key`]
37    /// if it is invalid.
38    ///
39    /// # Errors
40    ///
41    /// Returns an [`Error`][`crate::Error`] if
42    /// * string contains characters outside of the allowed range (`[a-z0-9]`)
43    /// * string is empty
44    ///
45    /// # Examples
46    ///
47    /// ```
48    /// use nethsm::KeyId;
49    ///
50    /// assert!(KeyId::new("key1".into()).is_ok());
51    /// assert!(KeyId::new("key".into()).is_ok());
52    ///
53    /// // the input can not contain invalid chars
54    /// assert!(KeyId::new("key1#".into()).is_err());
55    /// assert!(KeyId::new("key~1".into()).is_err());
56    ///
57    /// // the key must be non-empty
58    /// assert!(KeyId::new("".into()).is_err());
59    /// ```
60    pub fn new(key_id: String) -> Result<Self, Error> {
61        if key_id.is_empty()
62            || !key_id.chars().all(|char| {
63                char.is_numeric() || (char.is_ascii_lowercase() && char.is_ascii_alphabetic())
64            })
65        {
66            return Err(Error::InvalidKeyId(key_id));
67        }
68
69        Ok(Self(key_id))
70    }
71}
72
73impl AsRef<str> for KeyId {
74    fn as_ref(&self) -> &str {
75        &self.0
76    }
77}
78
79impl From<KeyId> for String {
80    fn from(value: KeyId) -> Self {
81        value.0
82    }
83}
84
85impl FromStr for KeyId {
86    type Err = Error;
87    fn from_str(s: &str) -> Result<Self, Self::Err> {
88        Self::new(s.into())
89    }
90}
91
92impl Display for KeyId {
93    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94        self.0.fmt(f)
95    }
96}
97
98impl TryFrom<&str> for KeyId {
99    type Error = Error;
100
101    fn try_from(value: &str) -> Result<Self, Self::Error> {
102        Self::from_str(value)
103    }
104}
105
106impl TryFrom<&String> for KeyId {
107    type Error = Error;
108
109    fn try_from(value: &String) -> Result<Self, Self::Error> {
110        Self::from_str(value)
111    }
112}
113
114impl TryFrom<String> for KeyId {
115    type Error = Error;
116
117    fn try_from(value: String) -> Result<Self, Self::Error> {
118        Self::new(value)
119    }
120}
121
122#[derive(Debug, thiserror::Error)]
123pub enum Error {
124    /// Importing from PKCS#8 DER or PEM failed
125    #[error("PKCS#8 error: {0}")]
126    Pkcs8(#[from] rsa::pkcs8::Error),
127
128    /// No primes found when importing an RSA key
129    #[error("No primes found")]
130    NoPrimes,
131
132    /// The [`KeyType`] is not supported
133    #[error("The {0} key type is not supported")]
134    UnsupportedKeyType(KeyType),
135
136    /// The key mechanisms provided for a key type are not valid
137    #[error(
138        "The key type {key_type} does not support the following key mechanisms: {invalid_mechanisms:?}"
139    )]
140    InvalidKeyMechanism {
141        key_type: KeyType,
142        invalid_mechanisms: Vec<KeyMechanism>,
143    },
144
145    /// Elliptic curve keys do not support providing a length
146    #[error("Elliptic curve key ({key_type}) does not support setting length")]
147    KeyLengthUnsupported { key_type: KeyType },
148
149    /// Key type requires setting a length
150    #[error("Generating a key of type {key_type} requires setting a length")]
151    KeyLengthRequired { key_type: KeyType },
152
153    /// AES key is generated with unsupported key length (not 128, 192 or 256)
154    #[error(
155        "AES only defines key lengths of 128, 192 and 256. A key length of {key_length} is unsupported!"
156    )]
157    InvalidKeyLengthAes { key_length: u32 },
158
159    /// RSA key is generated with unsafe key length (smaller than 2048)
160    #[error(
161        "RSA keys shorter than {MIN_RSA_BIT_LENGTH} are not supported. A key length of {key_length} is unsafe!"
162    )]
163    InvalidKeyLengthRsa { key_length: u32 },
164
165    /// Elliptic curve TLS keys do not support providing a length
166    #[error("Elliptic curve key ({tls_key_type}) does not support setting length")]
167    TlsKeyLengthUnsupported { tls_key_type: TlsKeyType },
168
169    /// RSA TLS key type requires setting a length
170    #[error("Generating a key of type {tls_key_type} requires setting a length")]
171    TlsKeyLengthRequired { tls_key_type: TlsKeyType },
172
173    /// RSA TLS key is generated with unsafe key length (smaller than 2048)
174    #[error(
175        "RSA keys shorter than {MIN_RSA_BIT_LENGTH} are not supported. A key length of {key_length} is unsafe!"
176    )]
177    InvalidTlsKeyLengthRsa { key_length: u32 },
178
179    /// Invalid Key ID
180    #[error("Invalid Key ID: {0}")]
181    InvalidKeyId(String),
182
183    /// The signature type provided for a key type is not valid
184    #[error("The key type {key_type} is not compatible with signature type: {signature_type}")]
185    InvalidKeyTypeForSignatureType {
186        key_type: KeyType,
187        signature_type: SignatureType,
188    },
189
190    /// The key mechanisms provided for a signature type are not valid
191    #[error(
192        "The key mechanism {required_key_mechanism} must be used with signature type {signature_type}"
193    )]
194    InvalidKeyMechanismsForSignatureType {
195        required_key_mechanism: KeyMechanism,
196        signature_type: SignatureType,
197    },
198
199    /// A valid cryptographic key use can not be derived from a String
200    #[error("Unable to derive a valid cryptography key use from string: {0}")]
201    InvalidCryptograhicKeyUse(String),
202
203    /// A signing key setup is not compatible with raw cryptographic signing
204    #[error(
205        "The key type {key_type}, key mechanisms {key_mechanisms:?} and signature type {signature_type} are incompatible with raw cryptographic signing"
206    )]
207    InvalidRawSigningKeySetup {
208        key_type: KeyType,
209        key_mechanisms: Vec<KeyMechanism>,
210        signature_type: SignatureType,
211    },
212
213    /// A signing key setup is not compatible with OpenPGP signing
214    #[error(
215        "The key type {key_type}, key mechanisms {key_mechanisms:?} and signature type {signature_type} are incompatible with OpenPGP signing"
216    )]
217    InvalidOpenPgpSigningKeySetup {
218        key_type: KeyType,
219        key_mechanisms: Vec<KeyMechanism>,
220        signature_type: SignatureType,
221    },
222}
223
224/// The cryptographic context in which a key is used
225///
226/// Each key can only be used in one cryptographic context.
227/// This is because the NetHSM offers only a single certificate slot per key, which can be used to
228/// attach certificates for a specific cryptographic use.
229#[derive(Clone, Debug, Deserialize, Hash, Eq, PartialEq, Serialize)]
230pub enum CryptographicKeyContext {
231    /// A key is used in an OpenPGP context
232    #[serde(rename = "openpgp")]
233    OpenPgp {
234        /// List of OpenPGP User IDs for the certificate.
235        user_ids: OpenPgpUserIdList,
236
237        /// OpenPGP version for the certificate.
238        version: OpenPgpVersion,
239    },
240
241    /// A key is used in a raw cryptographic context
242    #[serde(rename = "raw")]
243    Raw,
244}
245
246impl CryptographicKeyContext {
247    /// Validates the cryptographic context against a signing key setup
248    ///
249    /// # Errors
250    ///
251    /// Returns an [`Error::Key`][`crate::Error::Key`] if the key setup can not be used for signing
252    /// operations in the respective cryptographic context.
253    ///
254    /// # Examples
255    ///
256    /// ```
257    /// use nethsm::{
258    ///     CryptographicKeyContext,
259    ///     KeyMechanism,
260    ///     KeyType,
261    ///     OpenPgpUserIdList,
262    ///     OpenPgpVersion,
263    ///     SignatureType,
264    /// };
265    ///
266    /// # fn main() -> testresult::TestResult {
267    /// CryptographicKeyContext::Raw.validate_signing_key_setup(
268    ///     KeyType::Curve25519,
269    ///     &[KeyMechanism::EdDsaSignature],
270    ///     SignatureType::EdDsa,
271    /// )?;
272    ///
273    /// CryptographicKeyContext::OpenPgp {
274    ///     user_ids: OpenPgpUserIdList::new(vec!["Foobar McFooface <foobar@mcfooface.org>".parse()?])?,
275    ///     version: OpenPgpVersion::V4,
276    /// }
277    /// .validate_signing_key_setup(
278    ///     KeyType::Curve25519,
279    ///     &[KeyMechanism::EdDsaSignature],
280    ///     SignatureType::EdDsa,
281    /// )?;
282    ///
283    /// // OpenPGP does not support ECDSA P224
284    /// assert!(
285    ///     CryptographicKeyContext::OpenPgp {
286    ///         user_ids: OpenPgpUserIdList::new(vec![
287    ///             "Foobar McFooface <foobar@mcfooface.org>".parse()?
288    ///         ])?,
289    ///         version: OpenPgpVersion::V4,
290    ///     }
291    ///     .validate_signing_key_setup(
292    ///         KeyType::EcP224,
293    ///         &[KeyMechanism::EcdsaSignature],
294    ///         SignatureType::EcdsaP224,
295    ///     )
296    ///     .is_err()
297    /// );
298    /// # Ok(())
299    /// # }
300    /// ```
301    pub fn validate_signing_key_setup(
302        &self,
303        key_type: KeyType,
304        key_mechanisms: &[KeyMechanism],
305        signature_type: SignatureType,
306    ) -> Result<(), Error> {
307        match self {
308            Self::Raw => match (key_type, signature_type) {
309                (KeyType::Curve25519, SignatureType::EdDsa)
310                    if key_mechanisms.contains(&KeyMechanism::EdDsaSignature) => {}
311                (KeyType::EcP224, SignatureType::EcdsaP224)
312                    if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
313                (KeyType::EcP256, SignatureType::EcdsaP256)
314                    if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
315                (KeyType::EcP384, SignatureType::EcdsaP384)
316                    if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
317                (KeyType::EcP521, SignatureType::EcdsaP521)
318                    if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
319                (KeyType::Rsa, SignatureType::Pkcs1)
320                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePkcs1) => {}
321                (KeyType::Rsa, SignatureType::PssMd5)
322                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssMd5) => {}
323                (KeyType::Rsa, SignatureType::PssSha1)
324                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha1) => {}
325                (KeyType::Rsa, SignatureType::PssSha224)
326                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha224) => {}
327                (KeyType::Rsa, SignatureType::PssSha256)
328                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha256) => {}
329                (KeyType::Rsa, SignatureType::PssSha384)
330                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha384) => {}
331                (KeyType::Rsa, SignatureType::PssSha512)
332                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePssSha512) => {}
333                _ => {
334                    return Err(Error::InvalidRawSigningKeySetup {
335                        key_type,
336                        key_mechanisms: key_mechanisms.to_vec(),
337                        signature_type,
338                    });
339                }
340            },
341            Self::OpenPgp {
342                user_ids: _,
343                version: _,
344            } => match (key_type, signature_type) {
345                (KeyType::Curve25519, SignatureType::EdDsa)
346                    if key_mechanisms.contains(&KeyMechanism::EdDsaSignature) => {}
347                (KeyType::EcP256, SignatureType::EcdsaP256)
348                    if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
349                (KeyType::EcP384, SignatureType::EcdsaP384)
350                    if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
351                (KeyType::EcP521, SignatureType::EcdsaP521)
352                    if key_mechanisms.contains(&KeyMechanism::EcdsaSignature) => {}
353                (KeyType::Rsa, SignatureType::Pkcs1)
354                    if key_mechanisms.contains(&KeyMechanism::RsaSignaturePkcs1) => {}
355                _ => {
356                    return Err(Error::InvalidOpenPgpSigningKeySetup {
357                        key_type,
358                        key_mechanisms: key_mechanisms.to_vec(),
359                        signature_type,
360                    });
361                }
362            },
363        }
364        Ok(())
365    }
366}
367
368/// The validated setup for a cryptographic signing key
369#[derive(Clone, Debug, Deserialize, Hash, Eq, PartialEq, Serialize)]
370pub struct SigningKeySetup {
371    key_id: KeyId,
372    key_type: KeyType,
373    key_mechanisms: Vec<KeyMechanism>,
374    key_length: Option<u32>,
375    signature_type: SignatureType,
376    key_context: CryptographicKeyContext,
377}
378
379impl SigningKeySetup {
380    /// Creates a new [`SigningKeySetup`]
381    ///
382    /// # Errors
383    ///
384    /// Returns an [`Error::Key`][`crate::Error::Key`] if the key setup is not valid in itself or
385    /// can not be used for signing operations in the respective cryptographic context.
386    ///
387    /// # Examples
388    ///
389    /// ```
390    /// use nethsm::{
391    ///     CryptographicKeyContext,
392    ///     KeyMechanism,
393    ///     KeyType,
394    ///     OpenPgpUserIdList,
395    ///     SignatureType,
396    ///     SigningKeySetup,
397    /// };
398    ///
399    /// # fn main() -> testresult::TestResult {
400    /// SigningKeySetup::new(
401    ///     "key1".parse()?,
402    ///     KeyType::Curve25519,
403    ///     vec![KeyMechanism::EdDsaSignature],
404    ///     None,
405    ///     SignatureType::EdDsa,
406    ///     CryptographicKeyContext::Raw,
407    /// )?;
408    ///
409    /// SigningKeySetup::new(
410    ///     "key1".parse()?,
411    ///     KeyType::Curve25519,
412    ///     vec![KeyMechanism::EdDsaSignature],
413    ///     None,
414    ///     SignatureType::EdDsa,
415    ///     CryptographicKeyContext::OpenPgp {
416    ///         user_ids: OpenPgpUserIdList::new(vec![
417    ///             "Foobar McFooface <foobar@mcfooface.org>".parse()?,
418    ///         ])?,
419    ///         version: "v4".parse()?,
420    ///     },
421    /// )?;
422    ///
423    /// // this fails because Curve25519 does not support the ECDSA key mechanism
424    /// assert!(
425    ///     SigningKeySetup::new(
426    ///         "key1".parse()?,
427    ///         KeyType::Curve25519,
428    ///         vec![KeyMechanism::EcdsaSignature],
429    ///         None,
430    ///         SignatureType::EdDsa,
431    ///         CryptographicKeyContext::OpenPgp {
432    ///             user_ids: OpenPgpUserIdList::new(vec![
433    ///                 "Foobar McFooface <foobar@mcfooface.org>".parse()?
434    ///             ])?,
435    ///             version: "v4".parse()?,
436    ///         },
437    ///     )
438    ///     .is_err()
439    /// );
440    ///
441    /// // this fails because OpenPGP does not support the ECDSA P224 key type
442    /// assert!(
443    ///     SigningKeySetup::new(
444    ///         "key1".parse()?,
445    ///         KeyType::EcP224,
446    ///         vec![KeyMechanism::EcdsaSignature],
447    ///         None,
448    ///         SignatureType::EcdsaP224,
449    ///         CryptographicKeyContext::OpenPgp {
450    ///             user_ids: OpenPgpUserIdList::new(vec![
451    ///                 "Foobar McFooface <foobar@mcfooface.org>".parse()?
452    ///             ])?,
453    ///             version: "v4".parse()?,
454    ///         },
455    ///     )
456    ///     .is_err()
457    /// );
458    /// # Ok(())
459    /// # }
460    /// ```
461    pub fn new(
462        key_id: KeyId,
463        key_type: KeyType,
464        key_mechanisms: Vec<KeyMechanism>,
465        key_length: Option<u32>,
466        signature_type: SignatureType,
467        cryptographic_key_context: CryptographicKeyContext,
468    ) -> Result<Self, Error> {
469        key_type_matches_mechanisms(key_type, &key_mechanisms)?;
470        key_type_matches_length(key_type, key_length)?;
471        key_type_and_mechanisms_match_signature_type(key_type, &key_mechanisms, signature_type)?;
472        cryptographic_key_context.validate_signing_key_setup(
473            key_type,
474            &key_mechanisms,
475            signature_type,
476        )?;
477
478        Ok(Self {
479            key_id,
480            key_type,
481            key_mechanisms,
482            key_length,
483            signature_type,
484            key_context: cryptographic_key_context,
485        })
486    }
487
488    /// Returns the [`KeyId`]
489    pub fn get_key_id(&self) -> KeyId {
490        self.key_id.clone()
491    }
492
493    /// Returns the [`KeyType`]
494    pub fn get_key_type(&self) -> KeyType {
495        self.key_type
496    }
497
498    /// Returns the list of [`KeyMechanism`]s
499    pub fn get_key_mechanisms(&self) -> Vec<KeyMechanism> {
500        self.key_mechanisms.clone()
501    }
502
503    /// Returns the optional key length
504    pub fn get_key_length(&self) -> Option<u32> {
505        self.key_length
506    }
507
508    /// Returns the [`SignatureType`]
509    pub fn get_signature_type(&self) -> SignatureType {
510        self.signature_type
511    }
512
513    /// Returns the [`CryptographicKeyContext`]
514    pub fn get_key_context(&self) -> CryptographicKeyContext {
515        self.key_context.clone()
516    }
517}
518
519/// The data for private key import
520enum PrivateKeyData {
521    /// Data for [`KeyType::Curve25519`]
522    Curve25519(Vec<u8>),
523    /// Data for [`KeyType::EcP224`]
524    EcP224(Vec<u8>),
525    /// Data for [`KeyType::EcP256`]
526    EcP256(Vec<u8>),
527    /// Data for [`KeyType::EcP384`]
528    EcP384(Vec<u8>),
529    /// Data for [`KeyType::EcP521`]
530    EcP521(Vec<u8>),
531    /// Data for [`KeyType::Rsa`]
532    Rsa {
533        prime_p: Vec<u8>,
534        prime_q: Vec<u8>,
535        public_exponent: Vec<u8>,
536    },
537}
538
539impl std::fmt::Debug for PrivateKeyData {
540    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
541        const REDACTED: &&str = &"[REDACTED]";
542        match self {
543            Self::Curve25519(_) => f.debug_tuple("Curve25519").field(REDACTED).finish(),
544            Self::EcP224(_) => f.debug_tuple("EcP224").field(REDACTED).finish(),
545            Self::EcP256(_) => f.debug_tuple("EcP256").field(REDACTED).finish(),
546            Self::EcP384(_) => f.debug_tuple("EcP384").field(REDACTED).finish(),
547            Self::EcP521(_) => f.debug_tuple("EcP521").field(REDACTED).finish(),
548            Self::Rsa {
549                public_exponent, ..
550            } => f
551                .debug_struct("Rsa")
552                .field("prime_p", REDACTED)
553                .field("prime_q", REDACTED)
554                .field("public_exponent", public_exponent)
555                .finish(),
556        }
557    }
558}
559
560/// The key data required when importing a secret key
561#[derive(Debug)]
562pub struct PrivateKeyImport {
563    key_data: PrivateKeyData,
564}
565
566/// Creates a new vector with bytes in `buf`, left-padded with zeros so
567/// that the result is exactly `len` big.
568///
569/// # Errors
570///
571/// Returns an [`crate::Error::Default`], if the input buffer `buf` is
572/// longer than the targeted `len`.
573///
574/// # Examples
575///
576/// ```no_compile
577/// let input = vec![1, 2, 3];
578/// let output = pad(&input, 4)?;
579/// assert_eq!(output, vec![0, 1, 2, 3]);
580/// ```
581fn pad(buf: &[u8], len: usize) -> Result<Vec<u8>, crate::Error> {
582    if len < buf.len() {
583        return Err(crate::Error::Default(format!(
584            "Input buffer should be upmost {len} bytes long but has {} bytes.",
585            buf.len()
586        )));
587    }
588    let mut v = vec![0; len];
589    v[len - buf.len()..].copy_from_slice(buf);
590    Ok(v)
591}
592
593impl PrivateKeyImport {
594    /// Creates a new [`PrivateKeyImport`]
595    ///
596    /// Accepts a [`KeyType`] (all except [`KeyType::Generic`]) and a bytes array representing a
597    /// matching PKCS#8 private key in ASN.1 DER-encoded format.
598    ///
599    /// # Errors
600    ///
601    /// Returns an [`crate::Error::Key`] if
602    /// * `key_data` can not be deserialized to a respective private key format.
603    /// * an RSA private key does not have prime P or prime Q.
604    /// * an RSA private key is shorter than [`MIN_RSA_BIT_LENGTH`].
605    /// * `key_type` is the unsupported [`KeyType::Generic`].
606    ///
607    /// # Examples
608    ///
609    /// ```
610    /// # use testresult::TestResult;
611    /// use ed25519_dalek::{SigningKey, pkcs8::EncodePrivateKey};
612    /// use nethsm::{KeyType, PrivateKeyImport};
613    /// use rand::rngs::OsRng;
614    /// # fn main() -> TestResult {
615    ///
616    /// let key_data = {
617    ///     let mut csprng = OsRng;
618    ///     let signing_key: SigningKey = SigningKey::generate(&mut csprng);
619    ///     signing_key.to_pkcs8_der()?.as_bytes().to_vec()
620    /// };
621    ///
622    /// assert!(PrivateKeyImport::new(KeyType::Curve25519, &key_data).is_ok());
623    /// # Ok(())
624    /// # }
625    /// ```
626    pub fn new(key_type: KeyType, key_data: &[u8]) -> Result<Self, Error> {
627        Ok(match key_type {
628            KeyType::Curve25519 => {
629                let key_pair = ed25519_dalek::pkcs8::KeypairBytes::from_pkcs8_der(key_data)?;
630                Self {
631                    key_data: PrivateKeyData::Curve25519(key_pair.secret_key.to_vec()),
632                }
633            }
634            KeyType::EcP224 => {
635                let private_key = p224::SecretKey::from_pkcs8_der(key_data)?;
636                Self {
637                    key_data: PrivateKeyData::EcP224(private_key.to_bytes().as_slice().to_owned()),
638                }
639            }
640            KeyType::EcP256 => {
641                let private_key = p256::SecretKey::from_pkcs8_der(key_data)?;
642                Self {
643                    key_data: PrivateKeyData::EcP256(private_key.to_bytes().as_slice().to_owned()),
644                }
645            }
646            KeyType::EcP384 => {
647                let private_key = p384::SecretKey::from_pkcs8_der(key_data)?;
648                Self {
649                    key_data: PrivateKeyData::EcP384(private_key.to_bytes().as_slice().to_owned()),
650                }
651            }
652            KeyType::EcP521 => {
653                let private_key = p521::SecretKey::from_pkcs8_der(key_data)?;
654                Self {
655                    key_data: PrivateKeyData::EcP521(private_key.to_bytes().as_slice().to_owned()),
656                }
657            }
658            KeyType::Generic => return Err(Error::UnsupportedKeyType(KeyType::Generic)),
659            KeyType::Rsa => {
660                let private_key = RsaPrivateKey::from_pkcs8_der(key_data)?;
661                // ensure, that we have sufficient bit length
662                key_type_matches_length(key_type, Some(private_key.size() as u32 * 8))?;
663                Self {
664                    key_data: PrivateKeyData::Rsa {
665                        prime_p: private_key
666                            .primes()
667                            .first()
668                            .ok_or(Error::NoPrimes)?
669                            .to_bytes_be(),
670                        prime_q: private_key
671                            .primes()
672                            .get(1)
673                            .ok_or(Error::NoPrimes)?
674                            .to_bytes_be(),
675                        public_exponent: private_key.e().to_bytes_be(),
676                    },
677                }
678            }
679        })
680    }
681
682    /// Creates a new [`PrivateKeyImport`]
683    ///
684    /// Accepts a [`KeyType`] (all except [`KeyType::Generic`]) and a string slice representing a
685    /// matching PKCS#8 private key in PEM-encoded format.
686    ///
687    /// # Errors
688    ///
689    /// Returns an [`crate::Error::Key`] if
690    /// * `key_data` can not be deserialized to a respective private key format.
691    /// * an RSA private key does not have prime P or prime Q.
692    /// * an RSA private key is shorter than [`MIN_RSA_BIT_LENGTH`].
693    /// * `key_type` is the unsupported [`KeyType::Generic`].
694    ///
695    /// # Examples
696    ///
697    /// ```
698    /// # use testresult::TestResult;
699    /// use std::ops::Deref;
700    ///
701    /// use ed25519_dalek::{SigningKey, pkcs8::EncodePrivateKey, pkcs8::spki::der::pem::LineEnding};
702    /// use nethsm::{KeyType, PrivateKeyImport};
703    /// use rand::rngs::OsRng;
704    /// # fn main() -> TestResult {
705    ///
706    /// let key_data = {
707    ///     let mut csprng = OsRng;
708    ///     let signing_key: SigningKey = SigningKey::generate(&mut csprng);
709    ///     signing_key.to_pkcs8_pem(LineEnding::default())?
710    /// };
711    ///
712    /// assert!(PrivateKeyImport::from_pkcs8_pem(KeyType::Curve25519, key_data.deref()).is_ok());
713    /// # Ok(())
714    /// # }
715    /// ```
716    pub fn from_pkcs8_pem(key_type: KeyType, key_data: &str) -> Result<Self, Error> {
717        Ok(match key_type {
718            KeyType::Curve25519 => {
719                let key_pair = ed25519_dalek::pkcs8::KeypairBytes::from_pkcs8_pem(key_data)?;
720                Self {
721                    key_data: PrivateKeyData::Curve25519(key_pair.secret_key.to_vec()),
722                }
723            }
724            KeyType::EcP224 => {
725                let private_key = p224::SecretKey::from_pkcs8_pem(key_data)?;
726                Self {
727                    key_data: PrivateKeyData::EcP224(private_key.to_bytes().as_slice().to_owned()),
728                }
729            }
730            KeyType::EcP256 => {
731                let private_key = p256::SecretKey::from_pkcs8_pem(key_data)?;
732                Self {
733                    key_data: PrivateKeyData::EcP256(private_key.to_bytes().as_slice().to_owned()),
734                }
735            }
736            KeyType::EcP384 => {
737                let private_key = p384::SecretKey::from_pkcs8_pem(key_data)?;
738                Self {
739                    key_data: PrivateKeyData::EcP384(private_key.to_bytes().as_slice().to_owned()),
740                }
741            }
742            KeyType::EcP521 => {
743                let private_key = p521::SecretKey::from_pkcs8_pem(key_data)?;
744                Self {
745                    key_data: PrivateKeyData::EcP521(private_key.to_bytes().as_slice().to_owned()),
746                }
747            }
748            KeyType::Generic => return Err(Error::UnsupportedKeyType(KeyType::Generic)),
749            KeyType::Rsa => {
750                let private_key = RsaPrivateKey::from_pkcs8_pem(key_data)?;
751                // ensure, that we have sufficient bit length
752                key_type_matches_length(key_type, Some(private_key.size() as u32 * 8))?;
753                Self {
754                    key_data: PrivateKeyData::Rsa {
755                        prime_p: private_key
756                            .primes()
757                            .first()
758                            .ok_or(Error::NoPrimes)?
759                            .to_bytes_be(),
760                        prime_q: private_key
761                            .primes()
762                            .get(1)
763                            .ok_or(Error::NoPrimes)?
764                            .to_bytes_be(),
765                        public_exponent: private_key.e().to_bytes_be(),
766                    },
767                }
768            }
769        })
770    }
771
772    /// Create [`PrivateKeyImport`] object from raw, private RSA key parts.
773    ///
774    /// The function takes two primes (*p* and *q*) and the public exponent,
775    /// which usually is 65537 (`[0x01, 0x00, 0x01]`).
776    ///
777    /// # Examples
778    ///
779    /// ```rust
780    /// use nethsm::PrivateKeyImport;
781    ///
782    /// # fn main() -> testresult::TestResult {
783    /// let prime_p = vec![7];
784    /// let prime_q = vec![11];
785    /// let public_exponent = vec![1, 0, 1];
786    ///
787    /// let _import = PrivateKeyImport::from_rsa(prime_p, prime_q, public_exponent);
788    /// # Ok(()) }
789    /// ```
790    pub fn from_rsa(prime_p: Vec<u8>, prime_q: Vec<u8>, public_exponent: Vec<u8>) -> Self {
791        Self {
792            key_data: PrivateKeyData::Rsa {
793                prime_p,
794                prime_q,
795                public_exponent,
796            },
797        }
798    }
799
800    /// Create [`PrivateKeyImport`] object from raw, private Elliptic Curve bytes.
801    ///
802    /// The function takes two parameters:
803    /// - the type of elliptic curve,
804    /// - raw bytes in a curve-specific encoding
805    ///
806    /// Elliptic curve keys require the `bytes` to be zero-padded to be of correct size.
807    /// This function automatically applies padding accordingly.
808    ///
809    /// # Examples
810    ///
811    /// ```rust
812    /// use nethsm::{KeyType, PrivateKeyImport};
813    ///
814    /// # fn main() -> testresult::TestResult {
815    /// let bytes = vec![0x00; 32];
816    ///
817    /// let _import = PrivateKeyImport::from_raw_bytes(KeyType::Curve25519, bytes)?;
818    /// # Ok(()) }
819    /// ```
820    pub fn from_raw_bytes(ec: KeyType, bytes: impl AsRef<[u8]>) -> Result<Self, crate::Error> {
821        let bytes = bytes.as_ref();
822        Ok(Self {
823            key_data: match ec {
824                KeyType::EcP224 => PrivateKeyData::EcP224(pad(bytes, 28)?),
825                KeyType::EcP256 => PrivateKeyData::EcP256(pad(bytes, 32)?),
826                KeyType::EcP384 => PrivateKeyData::EcP384(pad(bytes, 48)?),
827                KeyType::EcP521 => PrivateKeyData::EcP521(pad(bytes, 66)?),
828                KeyType::Curve25519 => PrivateKeyData::Curve25519(pad(bytes, 32)?),
829                ec => return Err(crate::Error::Default(format!("Unsupported key type: {ec}"))),
830            },
831        })
832    }
833
834    /// Get the matching [`KeyType`] for the data contained in the [`PrivateKeyImport`]
835    pub fn key_type(&self) -> KeyType {
836        match &self.key_data {
837            PrivateKeyData::Curve25519(_) => KeyType::Curve25519,
838            PrivateKeyData::EcP224(_) => KeyType::EcP224,
839            PrivateKeyData::EcP256(_) => KeyType::EcP256,
840            PrivateKeyData::EcP384(_) => KeyType::EcP384,
841            PrivateKeyData::EcP521(_) => KeyType::EcP521,
842            PrivateKeyData::Rsa {
843                prime_p: _,
844                prime_q: _,
845                public_exponent: _,
846            } => KeyType::Rsa,
847        }
848    }
849}
850
851impl From<PrivateKeyImport> for KeyPrivateData {
852    fn from(value: PrivateKeyImport) -> Self {
853        match value.key_data {
854            PrivateKeyData::Rsa {
855                prime_p,
856                prime_q,
857                public_exponent,
858            } => KeyPrivateData {
859                prime_p: Some(Base64::encode_string(&prime_p)),
860                prime_q: Some(Base64::encode_string(&prime_q)),
861                public_exponent: Some(Base64::encode_string(&public_exponent)),
862                data: None,
863            },
864            PrivateKeyData::EcP224(data)
865            | PrivateKeyData::EcP256(data)
866            | PrivateKeyData::EcP384(data)
867            | PrivateKeyData::EcP521(data)
868            | PrivateKeyData::Curve25519(data) => KeyPrivateData {
869                prime_p: None,
870                prime_q: None,
871                public_exponent: None,
872                data: Some(Base64::encode_string(&data)),
873            },
874        }
875    }
876}
877
878/// Ensures that a [`KeyType`] is compatible with a list of [`KeyMechanism`]s
879///
880/// # Errors
881///
882/// Returns an [`Error::Key`][`crate::Error::Key`] if any of the [`KeyMechanism`]s is incompatible
883/// with the [`KeyType`]
884///
885/// # Examples
886///
887/// ```
888/// use nethsm::{KeyMechanism, KeyType, key_type_matches_mechanisms};
889///
890/// # fn main() -> testresult::TestResult {
891/// key_type_matches_mechanisms(KeyType::Curve25519, &[KeyMechanism::EdDsaSignature])?;
892/// key_type_matches_mechanisms(KeyType::EcP224, &[KeyMechanism::EcdsaSignature])?;
893/// key_type_matches_mechanisms(
894///     KeyType::Rsa,
895///     &[
896///         KeyMechanism::RsaDecryptionPkcs1,
897///         KeyMechanism::RsaSignaturePkcs1,
898///     ],
899/// )?;
900/// key_type_matches_mechanisms(
901///     KeyType::Generic,
902///     &[
903///         KeyMechanism::AesDecryptionCbc,
904///         KeyMechanism::AesEncryptionCbc,
905///     ],
906/// )?;
907///
908/// // this fails because Curve25519 is not compatible with the Elliptic Curve Digital Signature Algorithm (ECDSA),
909/// // but instead requires the use of the Edwards-curve Digital Signature Algorithm (EdDSA)
910/// assert!(
911///     key_type_matches_mechanisms(KeyType::Curve25519, &[KeyMechanism::EcdsaSignature]).is_err()
912/// );
913///
914/// // this fails because RSA key mechanisms are not compatible with block ciphers
915/// assert!(key_type_matches_mechanisms(
916///     KeyType::Generic,
917///     &[
918///         KeyMechanism::RsaDecryptionPkcs1,
919///         KeyMechanism::RsaSignaturePkcs1,
920///     ]
921/// )
922/// .is_err());
923///
924/// // this fails because RSA keys do not support Curve25519's Edwards-curve Digital Signature Algorithm (EdDSA)
925/// assert!(key_type_matches_mechanisms(
926///     KeyType::Rsa,
927///     &[
928///         KeyMechanism::AesDecryptionCbc,
929///         KeyMechanism::AesEncryptionCbc,
930///         KeyMechanism::EcdsaSignature
931///     ]
932/// )
933/// .is_err());
934/// # Ok(())
935/// # }
936/// ```
937pub fn key_type_matches_mechanisms(
938    key_type: KeyType,
939    mechanisms: &[KeyMechanism],
940) -> Result<(), Error> {
941    let valid_mechanisms: &[KeyMechanism] = match key_type {
942        KeyType::Curve25519 => &KeyMechanism::curve25519_mechanisms(),
943        KeyType::EcP224 | KeyType::EcP256 | KeyType::EcP384 | KeyType::EcP521 => {
944            &KeyMechanism::elliptic_curve_mechanisms()
945        }
946        KeyType::Generic => &KeyMechanism::generic_mechanisms(),
947        KeyType::Rsa => &KeyMechanism::rsa_mechanisms(),
948    };
949
950    let invalid_mechanisms = mechanisms
951        .iter()
952        .filter(|mechanism| !valid_mechanisms.contains(mechanism))
953        .cloned()
954        .collect::<Vec<KeyMechanism>>();
955
956    if invalid_mechanisms.is_empty() {
957        Ok(())
958    } else {
959        Err(Error::InvalidKeyMechanism {
960            key_type,
961            invalid_mechanisms,
962        })
963    }
964}
965
966/// Ensures that a [`KeyType`] and a list of [`KeyMechanism`]s is compatible with a
967/// [`SignatureType`]
968///
969/// # Errors
970///
971/// Returns an [`Error::Key`][`crate::Error::Key`] if the provided [`SignatureType`] is incompatible
972/// with the [`KeyType`] or [`KeyMechanism`]s.
973///
974/// # Examples
975///
976/// ```
977/// use nethsm::{KeyMechanism, KeyType, SignatureType, key_type_and_mechanisms_match_signature_type};
978///
979/// # fn main() -> testresult::TestResult {
980/// key_type_and_mechanisms_match_signature_type(KeyType::Curve25519, &[KeyMechanism::EdDsaSignature], SignatureType::EdDsa)?;
981/// key_type_and_mechanisms_match_signature_type(KeyType::EcP224, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP224)?;
982/// key_type_and_mechanisms_match_signature_type(KeyType::Rsa, &[KeyMechanism::RsaSignaturePkcs1],SignatureType::Pkcs1)?;
983///
984/// // this fails because Curve25519 is not compatible with the Elliptic Curve Digital Signature Algorithm (ECDSA),
985/// // but instead requires the use of the Edwards-curve Digital Signature Algorithm (EdDSA)
986/// assert!(
987///     key_type_and_mechanisms_match_signature_type(KeyType::Curve25519, &[KeyMechanism::EdDsaSignature], SignatureType::EcdsaP256).is_err()
988/// );
989/// # Ok(())
990/// # }
991/// ```
992pub fn key_type_and_mechanisms_match_signature_type(
993    key_type: KeyType,
994    mechanisms: &[KeyMechanism],
995    signature_type: SignatureType,
996) -> Result<(), Error> {
997    match signature_type {
998        SignatureType::EcdsaP224 => {
999            if key_type != KeyType::EcP224 {
1000                return Err(Error::InvalidKeyTypeForSignatureType {
1001                    key_type,
1002                    signature_type,
1003                });
1004            } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
1005                return Err(Error::InvalidKeyMechanismsForSignatureType {
1006                    required_key_mechanism: KeyMechanism::EcdsaSignature,
1007                    signature_type,
1008                });
1009            }
1010        }
1011        SignatureType::EcdsaP256 => {
1012            if key_type != KeyType::EcP256 {
1013                return Err(Error::InvalidKeyTypeForSignatureType {
1014                    key_type,
1015                    signature_type,
1016                });
1017            } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
1018                return Err(Error::InvalidKeyMechanismsForSignatureType {
1019                    required_key_mechanism: KeyMechanism::EcdsaSignature,
1020                    signature_type,
1021                });
1022            }
1023        }
1024        SignatureType::EcdsaP384 => {
1025            if key_type != KeyType::EcP384 {
1026                return Err(Error::InvalidKeyTypeForSignatureType {
1027                    key_type,
1028                    signature_type,
1029                });
1030            } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
1031                return Err(Error::InvalidKeyMechanismsForSignatureType {
1032                    required_key_mechanism: KeyMechanism::EcdsaSignature,
1033                    signature_type,
1034                });
1035            }
1036        }
1037        SignatureType::EcdsaP521 => {
1038            if key_type != KeyType::EcP521 {
1039                return Err(Error::InvalidKeyTypeForSignatureType {
1040                    key_type,
1041                    signature_type,
1042                });
1043            } else if !mechanisms.contains(&KeyMechanism::EcdsaSignature) {
1044                return Err(Error::InvalidKeyMechanismsForSignatureType {
1045                    required_key_mechanism: KeyMechanism::EcdsaSignature,
1046                    signature_type,
1047                });
1048            }
1049        }
1050        SignatureType::EdDsa => {
1051            if key_type != KeyType::Curve25519 {
1052                return Err(Error::InvalidKeyTypeForSignatureType {
1053                    key_type,
1054                    signature_type,
1055                });
1056            } else if !mechanisms.contains(&KeyMechanism::EdDsaSignature) {
1057                return Err(Error::InvalidKeyMechanismsForSignatureType {
1058                    required_key_mechanism: KeyMechanism::EdDsaSignature,
1059                    signature_type,
1060                });
1061            }
1062        }
1063        SignatureType::Pkcs1 => {
1064            if key_type != KeyType::Rsa {
1065                return Err(Error::InvalidKeyTypeForSignatureType {
1066                    key_type,
1067                    signature_type,
1068                });
1069            } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePkcs1) {
1070                return Err(Error::InvalidKeyMechanismsForSignatureType {
1071                    required_key_mechanism: KeyMechanism::RsaSignaturePkcs1,
1072                    signature_type,
1073                });
1074            }
1075        }
1076        SignatureType::PssMd5 => {
1077            if key_type != KeyType::Rsa {
1078                return Err(Error::InvalidKeyTypeForSignatureType {
1079                    key_type,
1080                    signature_type,
1081                });
1082            } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssMd5) {
1083                return Err(Error::InvalidKeyMechanismsForSignatureType {
1084                    required_key_mechanism: KeyMechanism::RsaSignaturePssMd5,
1085                    signature_type,
1086                });
1087            }
1088        }
1089        SignatureType::PssSha1 => {
1090            if key_type != KeyType::Rsa {
1091                return Err(Error::InvalidKeyTypeForSignatureType {
1092                    key_type,
1093                    signature_type,
1094                });
1095            } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha1) {
1096                return Err(Error::InvalidKeyMechanismsForSignatureType {
1097                    required_key_mechanism: KeyMechanism::RsaSignaturePssSha1,
1098                    signature_type,
1099                });
1100            }
1101        }
1102        SignatureType::PssSha224 => {
1103            if key_type != KeyType::Rsa {
1104                return Err(Error::InvalidKeyTypeForSignatureType {
1105                    key_type,
1106                    signature_type,
1107                });
1108            } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha224) {
1109                return Err(Error::InvalidKeyMechanismsForSignatureType {
1110                    required_key_mechanism: KeyMechanism::RsaSignaturePssSha224,
1111                    signature_type,
1112                });
1113            }
1114        }
1115        SignatureType::PssSha256 => {
1116            if key_type != KeyType::Rsa {
1117                return Err(Error::InvalidKeyTypeForSignatureType {
1118                    key_type,
1119                    signature_type,
1120                });
1121            } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha256) {
1122                return Err(Error::InvalidKeyMechanismsForSignatureType {
1123                    required_key_mechanism: KeyMechanism::RsaSignaturePssSha256,
1124                    signature_type,
1125                });
1126            }
1127        }
1128        SignatureType::PssSha384 => {
1129            if key_type != KeyType::Rsa {
1130                return Err(Error::InvalidKeyTypeForSignatureType {
1131                    key_type,
1132                    signature_type,
1133                });
1134            } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha384) {
1135                return Err(Error::InvalidKeyMechanismsForSignatureType {
1136                    required_key_mechanism: KeyMechanism::RsaSignaturePssSha384,
1137                    signature_type,
1138                });
1139            }
1140        }
1141        SignatureType::PssSha512 => {
1142            if key_type != KeyType::Rsa {
1143                return Err(Error::InvalidKeyTypeForSignatureType {
1144                    key_type,
1145                    signature_type,
1146                });
1147            } else if !mechanisms.contains(&KeyMechanism::RsaSignaturePssSha512) {
1148                return Err(Error::InvalidKeyMechanismsForSignatureType {
1149                    required_key_mechanism: KeyMechanism::RsaSignaturePssSha512,
1150                    signature_type,
1151                });
1152            }
1153        }
1154    }
1155    Ok(())
1156}
1157
1158/// Ensures that a [`KeyType`] is compatible with an optional key length
1159///
1160/// # Errors
1161///
1162/// Returns an [`Error::Key`][`crate::Error::Key`] if
1163/// * `key_type` is one of [`KeyType::Curve25519`], [`KeyType::EcP224`], [`KeyType::EcP256`],
1164///   [`KeyType::EcP384`] or [`KeyType::EcP521`] and `length` is [`Some`].
1165/// * `key_type` is [`KeyType::Generic`] or [`KeyType::Rsa`] and `length` is [`None`].
1166/// * `key_type` is [`KeyType::Generic`] and `length` is not [`Some`] value of `128`, `192` or
1167///   `256`.
1168/// * `key_type` is [`KeyType::Rsa`] and `length` is not [`Some`] value equal to or greater than
1169///   [`MIN_RSA_BIT_LENGTH`].
1170///
1171/// # Examples
1172///
1173/// ```
1174/// use nethsm::{KeyType, key_type_matches_length};
1175///
1176/// # fn main() -> testresult::TestResult {
1177/// key_type_matches_length(KeyType::Curve25519, None)?;
1178/// key_type_matches_length(KeyType::EcP224, None)?;
1179/// key_type_matches_length(KeyType::Rsa, Some(2048))?;
1180/// key_type_matches_length(KeyType::Generic, Some(256))?;
1181///
1182/// // this fails because elliptic curve keys have their length set intrinsically
1183/// assert!(key_type_matches_length(KeyType::Curve25519, Some(2048)).is_err());
1184/// // this fails because a bit length of 2048 is not defined for AES block ciphers
1185/// assert!(key_type_matches_length(KeyType::Generic, Some(2048)).is_err());
1186/// // this fails because a bit length of 1024 is unsafe to use for RSA keys
1187/// assert!(key_type_matches_length(KeyType::Rsa, Some(1024)).is_err());
1188/// # Ok(())
1189/// # }
1190/// ```
1191pub fn key_type_matches_length(key_type: KeyType, length: Option<u32>) -> Result<(), Error> {
1192    match key_type {
1193        KeyType::Curve25519
1194        | KeyType::EcP224
1195        | KeyType::EcP256
1196        | KeyType::EcP384
1197        | KeyType::EcP521 => {
1198            if length.is_some() {
1199                Err(Error::KeyLengthUnsupported { key_type })
1200            } else {
1201                Ok(())
1202            }
1203        }
1204        KeyType::Generic => match length {
1205            None => Err(Error::KeyLengthRequired { key_type }),
1206            Some(length) => {
1207                if ![128, 192, 256].contains(&length) {
1208                    Err(Error::InvalidKeyLengthAes { key_length: length })
1209                } else {
1210                    Ok(())
1211                }
1212            }
1213        },
1214        KeyType::Rsa => match length {
1215            None => Err(Error::KeyLengthRequired { key_type }),
1216            Some(length) => {
1217                if length < MIN_RSA_BIT_LENGTH {
1218                    Err(Error::InvalidKeyLengthRsa { key_length: length })
1219                } else {
1220                    Ok(())
1221                }
1222            }
1223        },
1224    }
1225}
1226
1227/// Ensures that a [`TlsKeyType`] is compatible with an optional key length
1228///
1229/// # Errors
1230///
1231/// Returns an [`Error::Key`][`crate::Error::Key`] if
1232/// * `tls_key_type` is one of [`TlsKeyType::Curve25519`], [`TlsKeyType::EcP224`],
1233///   [`TlsKeyType::EcP256`], [`TlsKeyType::EcP384`] or [`TlsKeyType::EcP521`] and `length` is
1234///   [`Some`].
1235/// * `tls_key_type` is [`TlsKeyType::Rsa`] and `length` is [`None`].
1236/// * `tls_key_type` is [`TlsKeyType::Rsa`] and `length` is not [`Some`] value equal to or greater
1237///   than [`MIN_RSA_BIT_LENGTH`].
1238///
1239/// # Examples
1240///
1241/// ```
1242/// use nethsm::{TlsKeyType, tls_key_type_matches_length};
1243///
1244/// # fn main() -> testresult::TestResult {
1245/// tls_key_type_matches_length(TlsKeyType::Curve25519, None)?;
1246/// tls_key_type_matches_length(TlsKeyType::EcP224, None)?;
1247/// tls_key_type_matches_length(TlsKeyType::Rsa, Some(2048))?;
1248///
1249/// // this fails because elliptic curve keys have their length set intrinsically
1250/// assert!(tls_key_type_matches_length(TlsKeyType::Curve25519, Some(2048)).is_err());
1251/// // this fails because a bit length of 1024 is unsafe to use for RSA keys
1252/// assert!(tls_key_type_matches_length(TlsKeyType::Rsa, Some(1024)).is_err());
1253/// # Ok(())
1254/// # }
1255/// ```
1256pub fn tls_key_type_matches_length(
1257    tls_key_type: TlsKeyType,
1258    length: Option<u32>,
1259) -> Result<(), Error> {
1260    match tls_key_type {
1261        TlsKeyType::Curve25519
1262        | TlsKeyType::EcP224
1263        | TlsKeyType::EcP256
1264        | TlsKeyType::EcP384
1265        | TlsKeyType::EcP521 => {
1266            if length.is_some() {
1267                Err(Error::TlsKeyLengthUnsupported { tls_key_type })
1268            } else {
1269                Ok(())
1270            }
1271        }
1272        TlsKeyType::Rsa => match length {
1273            None => Err(Error::TlsKeyLengthRequired { tls_key_type }),
1274            Some(length) => {
1275                if length < MIN_RSA_BIT_LENGTH {
1276                    Err(Error::InvalidTlsKeyLengthRsa { key_length: length })
1277                } else {
1278                    Ok(())
1279                }
1280            }
1281        },
1282    }
1283}
1284
1285#[cfg(test)]
1286mod tests {
1287    use rsa::RsaPrivateKey;
1288    use rsa::pkcs8::EncodePrivateKey;
1289    use rstest::{fixture, rstest};
1290    use testresult::TestResult;
1291
1292    use super::*;
1293
1294    #[fixture]
1295    fn ed25519_private_key() -> TestResult<Vec<u8>> {
1296        use ed25519_dalek::SigningKey;
1297        use rand::rngs::OsRng;
1298        let mut csprng = OsRng;
1299        let signing_key: SigningKey = SigningKey::generate(&mut csprng);
1300        Ok(signing_key.to_pkcs8_der()?.as_bytes().to_vec())
1301    }
1302
1303    #[fixture]
1304    fn p224_private_key() -> TestResult<Vec<u8>> {
1305        use p224::elliptic_curve::rand_core::OsRng;
1306        let private_key = p224::SecretKey::random(&mut OsRng);
1307        Ok(private_key.to_pkcs8_der()?.as_bytes().to_vec())
1308    }
1309
1310    #[fixture]
1311    fn p256_private_key() -> TestResult<Vec<u8>> {
1312        use p256::elliptic_curve::rand_core::OsRng;
1313        let private_key = p256::SecretKey::random(&mut OsRng);
1314        Ok(private_key.to_pkcs8_der()?.as_bytes().to_vec())
1315    }
1316
1317    #[fixture]
1318    fn p384_private_key() -> TestResult<Vec<u8>> {
1319        use p384::elliptic_curve::rand_core::OsRng;
1320        let private_key = p384::SecretKey::random(&mut OsRng);
1321        Ok(private_key.to_pkcs8_der()?.as_bytes().to_vec())
1322    }
1323
1324    #[fixture]
1325    fn p521_private_key() -> TestResult<Vec<u8>> {
1326        use p521::elliptic_curve::rand_core::OsRng;
1327        let private_key = p521::SecretKey::random(&mut OsRng);
1328        Ok(private_key.to_pkcs8_der()?.as_bytes().to_vec())
1329    }
1330
1331    #[fixture]
1332    fn rsa_private_key() -> TestResult<Vec<u8>> {
1333        let mut rng = rand::thread_rng();
1334        let private_key = RsaPrivateKey::new(&mut rng, 2048.try_into()?)?;
1335        Ok(private_key.to_pkcs8_der()?.as_bytes().to_vec())
1336    }
1337
1338    #[rstest]
1339    fn key_data(
1340        ed25519_private_key: TestResult<Vec<u8>>,
1341        p224_private_key: TestResult<Vec<u8>>,
1342        p256_private_key: TestResult<Vec<u8>>,
1343        p384_private_key: TestResult<Vec<u8>>,
1344        p521_private_key: TestResult<Vec<u8>>,
1345        rsa_private_key: TestResult<Vec<u8>>,
1346    ) -> TestResult {
1347        let ed25519_private_key = ed25519_private_key?;
1348        let p224_private_key = p224_private_key?;
1349        let p256_private_key = p256_private_key?;
1350        let p384_private_key = p384_private_key?;
1351        let p521_private_key = p521_private_key?;
1352        let rsa_private_key = rsa_private_key?;
1353
1354        assert!(PrivateKeyImport::new(KeyType::Curve25519, &ed25519_private_key).is_ok());
1355        assert!(PrivateKeyImport::new(KeyType::Curve25519, &p224_private_key).is_err());
1356        assert!(PrivateKeyImport::new(KeyType::Curve25519, &p256_private_key).is_err());
1357        assert!(PrivateKeyImport::new(KeyType::Curve25519, &p384_private_key).is_err());
1358        assert!(PrivateKeyImport::new(KeyType::Curve25519, &p521_private_key).is_err());
1359        assert!(PrivateKeyImport::new(KeyType::Curve25519, &rsa_private_key).is_err());
1360
1361        assert!(PrivateKeyImport::new(KeyType::EcP224, &ed25519_private_key).is_err());
1362        assert!(PrivateKeyImport::new(KeyType::EcP224, &p224_private_key).is_ok());
1363        assert!(PrivateKeyImport::new(KeyType::EcP224, &p256_private_key).is_err());
1364        assert!(PrivateKeyImport::new(KeyType::EcP224, &p384_private_key).is_err());
1365        assert!(PrivateKeyImport::new(KeyType::EcP224, &p521_private_key).is_err());
1366        assert!(PrivateKeyImport::new(KeyType::EcP224, &rsa_private_key).is_err());
1367
1368        assert!(PrivateKeyImport::new(KeyType::EcP256, &ed25519_private_key).is_err());
1369        assert!(PrivateKeyImport::new(KeyType::EcP256, &p224_private_key).is_err());
1370        assert!(PrivateKeyImport::new(KeyType::EcP256, &p256_private_key).is_ok());
1371        assert!(PrivateKeyImport::new(KeyType::EcP256, &p384_private_key).is_err());
1372        assert!(PrivateKeyImport::new(KeyType::EcP256, &p521_private_key).is_err());
1373        assert!(PrivateKeyImport::new(KeyType::EcP256, &rsa_private_key).is_err());
1374
1375        assert!(PrivateKeyImport::new(KeyType::EcP384, &ed25519_private_key).is_err());
1376        assert!(PrivateKeyImport::new(KeyType::EcP384, &p224_private_key).is_err());
1377        assert!(PrivateKeyImport::new(KeyType::EcP384, &p256_private_key).is_err());
1378        assert!(PrivateKeyImport::new(KeyType::EcP384, &p384_private_key).is_ok());
1379        assert!(PrivateKeyImport::new(KeyType::EcP384, &p521_private_key).is_err());
1380        assert!(PrivateKeyImport::new(KeyType::EcP384, &rsa_private_key).is_err());
1381
1382        assert!(PrivateKeyImport::new(KeyType::EcP521, &ed25519_private_key).is_err());
1383        assert!(PrivateKeyImport::new(KeyType::EcP521, &p224_private_key).is_err());
1384        assert!(PrivateKeyImport::new(KeyType::EcP521, &p256_private_key).is_err());
1385        assert!(PrivateKeyImport::new(KeyType::EcP521, &p384_private_key).is_err());
1386        assert!(PrivateKeyImport::new(KeyType::EcP521, &p521_private_key).is_ok());
1387        assert!(PrivateKeyImport::new(KeyType::EcP521, &rsa_private_key).is_err());
1388
1389        assert!(PrivateKeyImport::new(KeyType::Rsa, &ed25519_private_key).is_err());
1390        assert!(PrivateKeyImport::new(KeyType::Rsa, &p224_private_key).is_err());
1391        assert!(PrivateKeyImport::new(KeyType::Rsa, &p256_private_key).is_err());
1392        assert!(PrivateKeyImport::new(KeyType::Rsa, &p384_private_key).is_err());
1393        assert!(PrivateKeyImport::new(KeyType::Rsa, &p521_private_key).is_err());
1394        assert!(PrivateKeyImport::new(KeyType::Rsa, &rsa_private_key).is_ok());
1395
1396        assert!(PrivateKeyImport::new(KeyType::Generic, &ed25519_private_key).is_err());
1397        assert!(PrivateKeyImport::new(KeyType::Generic, &p224_private_key).is_err());
1398        assert!(PrivateKeyImport::new(KeyType::Generic, &p256_private_key).is_err());
1399        assert!(PrivateKeyImport::new(KeyType::Generic, &p384_private_key).is_err());
1400        assert!(PrivateKeyImport::new(KeyType::Generic, &p521_private_key).is_err());
1401        assert!(PrivateKeyImport::new(KeyType::Generic, &rsa_private_key).is_err());
1402        Ok(())
1403    }
1404
1405    #[rstest]
1406    #[case(KeyType::Curve25519, &[KeyMechanism::EdDsaSignature], SignatureType::EdDsa, None)]
1407    #[case(KeyType::EcP224, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP224, None)]
1408    #[case(KeyType::EcP256, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP256, None)]
1409    #[case(KeyType::EcP384, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP384, None)]
1410    #[case(KeyType::EcP521, &[KeyMechanism::EcdsaSignature], SignatureType::EcdsaP521, None)]
1411    #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePkcs1], SignatureType::Pkcs1, None)]
1412    #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssMd5], SignatureType::PssMd5, None)]
1413    #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha1], SignatureType::PssSha1, None)]
1414    #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha224], SignatureType::PssSha224, None)]
1415    #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha256], SignatureType::PssSha256, None)]
1416    #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha384], SignatureType::PssSha384, None)]
1417    #[case(KeyType::Rsa, &[KeyMechanism::RsaSignaturePssSha512], SignatureType::PssSha512, None)]
1418    #[case(
1419        KeyType::Curve25519,
1420        &[KeyMechanism::EdDsaSignature],
1421        SignatureType::EcdsaP256,
1422        Some(Box::new(Error::InvalidKeyTypeForSignatureType {
1423            key_type: KeyType::Curve25519,
1424            signature_type: SignatureType::EcdsaP256
1425        })
1426    ))]
1427    #[case(
1428        KeyType::Curve25519,
1429        &[KeyMechanism::EcdsaSignature],
1430        SignatureType::EdDsa,
1431        Some(Box::new(Error::InvalidKeyMechanismsForSignatureType {
1432            signature_type: SignatureType::EdDsa,
1433            required_key_mechanism: KeyMechanism::EdDsaSignature,
1434        })
1435    ))]
1436    #[case(
1437        KeyType::EcP224,
1438        &[KeyMechanism::EcdsaSignature],
1439        SignatureType::EdDsa,
1440        Some(Box::new(Error::InvalidKeyTypeForSignatureType {
1441            key_type: KeyType::EcP224,
1442            signature_type: SignatureType::EdDsa,
1443        })
1444    ))]
1445    #[case(
1446        KeyType::EcP224,
1447        &[KeyMechanism::EdDsaSignature],
1448        SignatureType::EcdsaP224,
1449        Some(Box::new(Error::InvalidKeyMechanismsForSignatureType {
1450            signature_type: SignatureType::EcdsaP224,
1451            required_key_mechanism: KeyMechanism::EcdsaSignature,
1452        })
1453    ))]
1454    #[case(
1455        KeyType::EcP256,
1456        &[KeyMechanism::EcdsaSignature],
1457        SignatureType::EdDsa,
1458        Some(Box::new(Error::InvalidKeyTypeForSignatureType {
1459            key_type: KeyType::EcP256,
1460            signature_type: SignatureType::EdDsa,
1461        })
1462    ))]
1463    #[case(
1464        KeyType::EcP256,
1465        &[KeyMechanism::EdDsaSignature],
1466        SignatureType::EcdsaP256,
1467        Some(Box::new(Error::InvalidKeyMechanismsForSignatureType {
1468            signature_type: SignatureType::EcdsaP256,
1469            required_key_mechanism: KeyMechanism::EcdsaSignature,
1470        })
1471    ))]
1472    #[case(
1473        KeyType::EcP384,
1474        &[KeyMechanism::EcdsaSignature],
1475        SignatureType::EdDsa,
1476        Some(Box::new(Error::InvalidKeyTypeForSignatureType {
1477            key_type: KeyType::EcP384,
1478            signature_type: SignatureType::EdDsa,
1479        })
1480    ))]
1481    #[case(
1482        KeyType::EcP384,
1483        &[KeyMechanism::EdDsaSignature],
1484        SignatureType::EcdsaP384,
1485        Some(Box::new(Error::InvalidKeyMechanismsForSignatureType {
1486            signature_type: SignatureType::EcdsaP384,
1487            required_key_mechanism: KeyMechanism::EcdsaSignature,
1488        })
1489    ))]
1490    #[case(
1491        KeyType::EcP521,
1492        &[KeyMechanism::EcdsaSignature],
1493        SignatureType::EdDsa,
1494        Some(Box::new(Error::InvalidKeyTypeForSignatureType {
1495            key_type: KeyType::EcP521,
1496            signature_type: SignatureType::EdDsa,
1497        })
1498    ))]
1499    #[case(
1500        KeyType::EcP521,
1501        &[KeyMechanism::EdDsaSignature],
1502        SignatureType::EcdsaP521,
1503        Some(Box::new(Error::InvalidKeyMechanismsForSignatureType {
1504            signature_type: SignatureType::EcdsaP521,
1505            required_key_mechanism: KeyMechanism::EcdsaSignature,
1506        })
1507    ))]
1508    #[case(
1509        KeyType::Rsa,
1510        &[KeyMechanism::RsaSignaturePkcs1],
1511        SignatureType::EdDsa,
1512        Some(Box::new(Error::InvalidKeyTypeForSignatureType {
1513            key_type: KeyType::Rsa,
1514            signature_type: SignatureType::EdDsa,
1515        })
1516    ))]
1517    #[case(
1518        KeyType::Rsa,
1519        &[KeyMechanism::RsaDecryptionOaepMd5],
1520        SignatureType::PssMd5,
1521        Some(Box::new(Error::InvalidKeyMechanismsForSignatureType {
1522            signature_type: SignatureType::PssMd5,
1523            required_key_mechanism: KeyMechanism::RsaSignaturePssMd5,
1524        })
1525    ))]
1526    fn test_key_type_and_mechanisms_match_signature_type(
1527        #[case] key_type: KeyType,
1528        #[case] key_mechanisms: &[KeyMechanism],
1529        #[case] signature_type: SignatureType,
1530        #[case] result: Option<Box<Error>>,
1531    ) -> TestResult {
1532        if let Some(error) = result {
1533            if let Err(fn_error) = key_type_and_mechanisms_match_signature_type(
1534                key_type,
1535                key_mechanisms,
1536                signature_type,
1537            ) {
1538                assert_eq!(fn_error.to_string(), error.to_string());
1539            } else {
1540                panic!("Did not return an Error!");
1541            }
1542        } else {
1543            key_type_and_mechanisms_match_signature_type(key_type, key_mechanisms, signature_type)?;
1544        }
1545
1546        Ok(())
1547    }
1548}