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