hickory_proto/dnssec/
crypto.rs

1use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec};
2
3use rustls_pki_types::{PrivateKeyDer, PrivatePkcs1KeyDer, PrivatePkcs8KeyDer};
4
5use super::ring_like::{
6    ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_FIXED_SIGNING, ED25519_PUBLIC_KEY_LEN,
7    EcdsaKeyPair, Ed25519KeyPair, KeyPair, PublicKeyComponents, RSA_PKCS1_SHA256, RSA_PKCS1_SHA512,
8    RsaKeyPair, SystemRandom, digest, signature,
9};
10use super::{
11    Algorithm, DigestType, DnsSecErrorKind, DnsSecResult, PublicKey, PublicKeyBuf, SigningKey, TBS,
12    ec_public_key::ECPublicKey, rsa_public_key::RSAPublicKey,
13};
14use crate::{ProtoError, ProtoErrorKind, error::ProtoResult};
15
16/// Decode private key
17pub fn signing_key_from_der(
18    key_der: &PrivateKeyDer<'_>,
19    algorithm: Algorithm,
20) -> DnsSecResult<Box<dyn SigningKey>> {
21    #[allow(deprecated)]
22    match algorithm {
23        Algorithm::Unknown(v) => Err(format!("unknown algorithm: {v}").into()),
24        Algorithm::RSASHA256 | Algorithm::RSASHA512 => {
25            Ok(Box::new(RsaSigningKey::from_key_der(key_der, algorithm)?))
26        }
27        Algorithm::ECDSAP256SHA256 | Algorithm::ECDSAP384SHA384 => {
28            Ok(Box::new(EcdsaSigningKey::from_key_der(key_der, algorithm)?))
29        }
30        Algorithm::ED25519 => Ok(Box::new(Ed25519SigningKey::from_key_der(key_der)?)),
31        e => Err(format!("unsupported SigningKey algorithm for ring: {e:?}").into()),
32    }
33}
34
35pub(super) fn decode_public_key<'a>(
36    public_key: &'a [u8],
37    algorithm: Algorithm,
38) -> ProtoResult<Arc<dyn PublicKey + 'a>> {
39    // try to keep this and `Algorithm::is_supported` in sync
40    debug_assert!(algorithm.is_supported());
41
42    #[allow(deprecated)]
43    match algorithm {
44        Algorithm::ECDSAP256SHA256 | Algorithm::ECDSAP384SHA384 => {
45            Ok(Arc::new(Ec::from_public_bytes(public_key, algorithm)?))
46        }
47        Algorithm::ED25519 => Ok(Arc::new(Ed25519::from_public_bytes(public_key.into())?)),
48        Algorithm::RSASHA1
49        | Algorithm::RSASHA1NSEC3SHA1
50        | Algorithm::RSASHA256
51        | Algorithm::RSASHA512 => Ok(Arc::new(Rsa::from_public_bytes(public_key, algorithm)?)),
52        _ => Err("public key algorithm not supported".into()),
53    }
54}
55
56/// An ECDSA signing key pair (backed by ring).
57pub struct EcdsaSigningKey {
58    inner: EcdsaKeyPair,
59    algorithm: Algorithm,
60}
61
62impl EcdsaSigningKey {
63    /// Decode signing key pair from DER.
64    ///
65    /// Errors unless the given algorithm is one of the following:
66    ///
67    /// - [`Algorithm::ECDSAP256SHA256`]
68    /// - [`Algorithm::ECDSAP384SHA384`]
69    pub fn from_key_der(key: &PrivateKeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
70        match key {
71            PrivateKeyDer::Pkcs8(key) => Self::from_pkcs8(key, algorithm),
72            _ => Err("unsupported key format (only PKCS#8 supported)".into()),
73        }
74    }
75
76    /// Decode signing key pair from DER-encoded PKCS#8 bytes.
77    ///
78    /// Errors unless the given algorithm is one of the following:
79    ///
80    /// - [`Algorithm::ECDSAP256SHA256`]
81    /// - [`Algorithm::ECDSAP384SHA384`]
82    pub fn from_pkcs8(key: &PrivatePkcs8KeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
83        let ring_algorithm = if algorithm == Algorithm::ECDSAP256SHA256 {
84            &ECDSA_P256_SHA256_FIXED_SIGNING
85        } else if algorithm == Algorithm::ECDSAP384SHA384 {
86            &ECDSA_P384_SHA384_FIXED_SIGNING
87        } else {
88            return Err(DnsSecErrorKind::Message("unsupported algorithm").into());
89        };
90
91        #[cfg(all(feature = "dnssec-aws-lc-rs", not(feature = "dnssec-ring")))]
92        let inner = EcdsaKeyPair::from_pkcs8(ring_algorithm, key.secret_pkcs8_der())?;
93
94        #[cfg(feature = "dnssec-ring")]
95        let inner =
96            EcdsaKeyPair::from_pkcs8(ring_algorithm, key.secret_pkcs8_der(), &SystemRandom::new())?;
97
98        Ok(Self { inner, algorithm })
99    }
100
101    /// Creates an ECDSA key pair with ring.
102    pub fn from_ecdsa(inner: EcdsaKeyPair, algorithm: Algorithm) -> Self {
103        Self { inner, algorithm }
104    }
105
106    /// Generate signing key pair and return the DER-encoded PKCS#8 bytes.
107    ///
108    /// Errors unless the given algorithm is one of the following:
109    ///
110    /// - [`Algorithm::ECDSAP256SHA256`]
111    /// - [`Algorithm::ECDSAP384SHA384`]
112    pub fn generate_pkcs8(algorithm: Algorithm) -> DnsSecResult<PrivatePkcs8KeyDer<'static>> {
113        let rng = SystemRandom::new();
114        let alg = if algorithm == Algorithm::ECDSAP256SHA256 {
115            &ECDSA_P256_SHA256_FIXED_SIGNING
116        } else if algorithm == Algorithm::ECDSAP384SHA384 {
117            &ECDSA_P384_SHA384_FIXED_SIGNING
118        } else {
119            return Err(DnsSecErrorKind::Message("unsupported algorithm").into());
120        };
121
122        let pkcs8 = EcdsaKeyPair::generate_pkcs8(alg, &rng)?;
123        Ok(PrivatePkcs8KeyDer::from(pkcs8.as_ref().to_vec()))
124    }
125}
126
127impl SigningKey for EcdsaSigningKey {
128    fn sign(&self, tbs: &TBS) -> DnsSecResult<Vec<u8>> {
129        let rng = SystemRandom::new();
130        Ok(self.inner.sign(&rng, tbs.as_ref())?.as_ref().to_vec())
131    }
132
133    fn to_public_key(&self) -> DnsSecResult<PublicKeyBuf> {
134        let mut bytes = self.inner.public_key().as_ref().to_vec();
135        bytes.remove(0);
136        Ok(PublicKeyBuf::new(bytes, self.algorithm))
137    }
138
139    fn algorithm(&self) -> Algorithm {
140        self.algorithm
141    }
142}
143
144/// An Ed25519 signing key pair (backed by ring).
145pub struct Ed25519SigningKey {
146    inner: Ed25519KeyPair,
147}
148
149impl Ed25519SigningKey {
150    /// Decode signing key pair from DER.
151    pub fn from_key_der(key: &PrivateKeyDer<'_>) -> DnsSecResult<Self> {
152        match key {
153            PrivateKeyDer::Pkcs8(key) => Self::from_pkcs8(key),
154            _ => Err("unsupported key format (only PKCS#8 supported)".into()),
155        }
156    }
157
158    /// Decode signing key pair from DER-encoded PKCS#8 bytes.
159    pub fn from_pkcs8(key: &PrivatePkcs8KeyDer<'_>) -> DnsSecResult<Self> {
160        Ok(Self {
161            inner: Ed25519KeyPair::from_pkcs8(key.secret_pkcs8_der())?,
162        })
163    }
164
165    /// Creates an Ed25519 keypair.
166    pub fn from_ed25519(inner: Ed25519KeyPair) -> Self {
167        Self { inner }
168    }
169
170    /// Generate signing key pair and return the DER-encoded PKCS#8 bytes.
171    pub fn generate_pkcs8() -> DnsSecResult<PrivatePkcs8KeyDer<'static>> {
172        let rng = SystemRandom::new();
173        let pkcs8 = Ed25519KeyPair::generate_pkcs8(&rng)?;
174        Ok(PrivatePkcs8KeyDer::from(pkcs8.as_ref().to_vec()))
175    }
176}
177
178impl SigningKey for Ed25519SigningKey {
179    fn sign(&self, tbs: &TBS) -> DnsSecResult<Vec<u8>> {
180        Ok(self.inner.sign(tbs.as_ref()).as_ref().to_vec())
181    }
182
183    fn to_public_key(&self) -> DnsSecResult<PublicKeyBuf> {
184        Ok(PublicKeyBuf::new(
185            self.inner.public_key().as_ref().to_vec(),
186            Algorithm::ED25519,
187        ))
188    }
189
190    fn algorithm(&self) -> Algorithm {
191        Algorithm::ED25519
192    }
193}
194
195/// Elyptic Curve public key type
196pub type Ec = ECPublicKey;
197
198impl Ec {
199    /// ```text
200    /// RFC 6605                    ECDSA for DNSSEC                  April 2012
201    ///
202    ///   4.  DNSKEY and RRSIG Resource Records for ECDSA
203    ///
204    ///   ECDSA public keys consist of a single value, called "Q" in FIPS
205    ///   186-3.  In DNSSEC keys, Q is a simple bit string that represents the
206    ///   uncompressed form of a curve point, "x | y".
207    ///
208    ///   The ECDSA signature is the combination of two non-negative integers,
209    ///   called "r" and "s" in FIPS 186-3.  The two integers, each of which is
210    ///   formatted as a simple octet string, are combined into a single longer
211    ///   octet string for DNSSEC as the concatenation "r | s".  (Conversion of
212    ///   the integers to bit strings is described in Section C.2 of FIPS
213    ///   186-3.)  For P-256, each integer MUST be encoded as 32 octets; for
214    ///   P-384, each integer MUST be encoded as 48 octets.
215    ///
216    ///   The algorithm numbers associated with the DNSKEY and RRSIG resource
217    ///   records are fully defined in the IANA Considerations section.  They
218    ///   are:
219    ///
220    ///   o  DNSKEY and RRSIG RRs signifying ECDSA with the P-256 curve and
221    ///      SHA-256 use the algorithm number 13.
222    ///
223    ///   o  DNSKEY and RRSIG RRs signifying ECDSA with the P-384 curve and
224    ///      SHA-384 use the algorithm number 14.
225    ///
226    ///   Conformant implementations that create records to be put into the DNS
227    ///   MUST implement signing and verification for both of the above
228    ///   algorithms.  Conformant DNSSEC verifiers MUST implement verification
229    ///   for both of the above algorithms.
230    /// ```
231    pub fn from_public_bytes(public_key: &[u8], algorithm: Algorithm) -> ProtoResult<Self> {
232        Self::from_unprefixed(public_key, algorithm)
233    }
234}
235
236impl PublicKey for Ec {
237    fn public_bytes(&self) -> &[u8] {
238        self.unprefixed_bytes()
239    }
240
241    fn verify(&self, message: &[u8], signature: &[u8]) -> ProtoResult<()> {
242        // TODO: assert_eq!(algorithm, self.algorithm); once *ring* allows this.
243        let alg = match self.algorithm {
244            Algorithm::ECDSAP256SHA256 => &signature::ECDSA_P256_SHA256_FIXED,
245            Algorithm::ECDSAP384SHA384 => &signature::ECDSA_P384_SHA384_FIXED,
246            _ => return Err("only ECDSAP256SHA256 and ECDSAP384SHA384 are supported by Ec".into()),
247        };
248        let public_key = signature::UnparsedPublicKey::new(alg, self.prefixed_bytes());
249        public_key.verify(message, signature).map_err(Into::into)
250    }
251
252    fn algorithm(&self) -> Algorithm {
253        self.algorithm
254    }
255}
256
257/// Ed25519 Public key
258pub struct Ed25519<'k> {
259    raw: Cow<'k, [u8]>,
260}
261
262impl<'k> Ed25519<'k> {
263    /// ```text
264    /// RFC 8080                    EdDSA for DNSSEC               February 2017
265    ///
266    ///  An Ed25519 public key consists of a 32-octet value, which is encoded
267    ///  into the Public Key field of a DNSKEY resource record as a simple bit
268    ///  string.  The generation of a public key is defined in Section 5.1.5
269    ///  of [RFC8032].
270    /// ```
271    pub fn from_public_bytes(public_key: Cow<'k, [u8]>) -> ProtoResult<Self> {
272        if public_key.len() != ED25519_PUBLIC_KEY_LEN {
273            return Err(format!(
274                "expected {} byte public_key: {}",
275                ED25519_PUBLIC_KEY_LEN,
276                public_key.len()
277            )
278            .into());
279        }
280
281        Ok(Self { raw: public_key })
282    }
283}
284
285impl PublicKey for Ed25519<'_> {
286    // TODO: just store reference to public key bytes in ctor...
287    fn public_bytes(&self) -> &[u8] {
288        self.raw.as_ref()
289    }
290
291    fn verify(&self, message: &[u8], signature: &[u8]) -> ProtoResult<()> {
292        let public_key = signature::UnparsedPublicKey::new(&signature::ED25519, self.raw.as_ref());
293        public_key.verify(message, signature).map_err(Into::into)
294    }
295
296    fn algorithm(&self) -> Algorithm {
297        Algorithm::ED25519
298    }
299}
300
301/// Rsa public key
302pub struct Rsa<'k> {
303    raw: &'k [u8],
304    pkey: RSAPublicKey<'k>,
305    algorithm: Algorithm,
306}
307
308impl<'k> Rsa<'k> {
309    /// ```text
310    /// RFC 3110              RSA SIGs and KEYs in the DNS              May 2001
311    ///
312    ///       2. RSA Public KEY Resource Records
313    ///
314    ///  RSA public keys are stored in the DNS as KEY RRs using algorithm
315    ///  number 5 [RFC2535].  The structure of the algorithm specific portion
316    ///  of the RDATA part of such RRs is as shown below.
317    ///
318    ///        Field             Size
319    ///        -----             ----
320    ///        exponent length   1 or 3 octets (see text)
321    ///        exponent          as specified by length field
322    ///        modulus           remaining space
323    ///
324    ///  For interoperability, the exponent and modulus are each limited to
325    ///  4096 bits in length.  The public key exponent is a variable length
326    ///  unsigned integer.  Its length in octets is represented as one octet
327    ///  if it is in the range of 1 to 255 and by a zero octet followed by a
328    ///  two octet unsigned length if it is longer than 255 bytes.  The public
329    ///  key modulus field is a multiprecision unsigned integer.  The length
330    ///  of the modulus can be determined from the RDLENGTH and the preceding
331    ///  RDATA fields including the exponent.  Leading zero octets are
332    ///  prohibited in the exponent and modulus.
333    ///
334    ///  Note: KEY RRs for use with RSA/SHA1 DNS signatures MUST use this
335    ///  algorithm number (rather than the algorithm number specified in the
336    ///  obsoleted RFC 2537).
337    ///
338    ///  Note: This changes the algorithm number for RSA KEY RRs to be the
339    ///  same as the new algorithm number for RSA/SHA1 SIGs.
340    /// ```
341    pub fn from_public_bytes(raw: &'k [u8], algorithm: Algorithm) -> ProtoResult<Self> {
342        let pkey = RSAPublicKey::try_from(raw)?;
343        Ok(Self {
344            raw,
345            pkey,
346            algorithm,
347        })
348    }
349}
350
351impl PublicKey for Rsa<'_> {
352    fn public_bytes(&self) -> &[u8] {
353        self.raw
354    }
355
356    fn verify(&self, message: &[u8], signature: &[u8]) -> ProtoResult<()> {
357        #[allow(deprecated)]
358        let alg = match self.algorithm {
359            Algorithm::RSASHA256 => &signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
360            Algorithm::RSASHA512 => &signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
361            Algorithm::RSASHA1 => &signature::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
362            Algorithm::RSASHA1NSEC3SHA1 => {
363                return Err("*ring* doesn't support RSASHA1NSEC3SHA1 yet".into());
364            }
365            _ => unreachable!("non-RSA algorithm passed to RSA verify()"),
366        };
367        let public_key = signature::RsaPublicKeyComponents {
368            n: self.pkey.n(),
369            e: self.pkey.e(),
370        };
371        public_key
372            .verify(alg, message, signature)
373            .map_err(Into::into)
374    }
375
376    fn algorithm(&self) -> Algorithm {
377        self.algorithm
378    }
379}
380
381/// An RSA signing key pair (backed by ring).
382pub struct RsaSigningKey {
383    inner: RsaKeyPair,
384    algorithm: Algorithm,
385}
386
387impl RsaSigningKey {
388    /// Decode signing key pair from DER.
389    pub fn from_key_der(key: &PrivateKeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
390        match key {
391            PrivateKeyDer::Pkcs8(key) => Self::from_pkcs8(key, algorithm),
392            PrivateKeyDer::Pkcs1(key) => Self::from_pkcs1(key, algorithm),
393            _ => Err("unsupported key format (only PKCS#8 supported)".into()),
394        }
395    }
396
397    /// Decode signing key pair from DER-encoded PKCS#8 bytes.
398    pub fn from_pkcs8(key: &PrivatePkcs8KeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
399        match algorithm {
400            #[allow(deprecated)]
401            Algorithm::RSASHA1 | Algorithm::RSASHA1NSEC3SHA1 => {
402                return Err("unsupported Algorithm (insecure): {algorithm:?}".into());
403            }
404            Algorithm::RSASHA256 | Algorithm::RSASHA512 => {}
405            _ => return Err("unsupported Algorithm: {algorithm:?}".into()),
406        }
407
408        Ok(Self {
409            inner: RsaKeyPair::from_pkcs8(key.secret_pkcs8_der())?,
410            algorithm,
411        })
412    }
413
414    /// Decode signing key pair from DER-encoded PKCS#1 bytes.
415    pub fn from_pkcs1(key: &PrivatePkcs1KeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
416        match algorithm {
417            #[allow(deprecated)]
418            Algorithm::RSASHA1 | Algorithm::RSASHA1NSEC3SHA1 => {
419                return Err("unsupported Algorithm (insecure): {algorithm:?}".into());
420            }
421            Algorithm::RSASHA256 | Algorithm::RSASHA512 => {}
422            _ => return Err("unsupported Algorithm: {algorithm:?}".into()),
423        }
424
425        Ok(Self {
426            inner: RsaKeyPair::from_der(key.secret_pkcs1_der())?,
427            algorithm,
428        })
429    }
430}
431
432impl SigningKey for RsaSigningKey {
433    fn sign(&self, tbs: &TBS) -> DnsSecResult<Vec<u8>> {
434        let encoding = match self.algorithm {
435            Algorithm::RSASHA256 => &RSA_PKCS1_SHA256,
436            Algorithm::RSASHA512 => &RSA_PKCS1_SHA512,
437            _ => unreachable!(),
438        };
439
440        let rng = SystemRandom::new();
441        let mut signature = vec![0; self.inner.public_key().modulus_len()];
442        self.inner
443            .sign(encoding, &rng, tbs.as_ref(), &mut signature)?;
444        Ok(signature)
445    }
446
447    fn to_public_key(&self) -> DnsSecResult<PublicKeyBuf> {
448        let components = PublicKeyComponents::<Vec<u8>>::from(self.inner.public_key());
449
450        let mut buf = Vec::with_capacity(components.e.len() + components.n.len());
451        if components.e.len() > 255 {
452            buf.push(0);
453            buf.push((components.e.len() >> 8) as u8);
454        }
455
456        buf.push(components.e.len() as u8);
457        buf.extend(&components.e);
458        buf.extend(&components.n);
459        Ok(PublicKeyBuf::new(buf, self.algorithm))
460    }
461
462    fn algorithm(&self) -> Algorithm {
463        self.algorithm
464    }
465}
466
467/// Hashing wrapper type.
468#[derive(Clone, Copy, Debug)]
469pub struct Digest(digest::Digest);
470
471impl Digest {
472    /// Hashes the given `data` `iterations` times with the given `salt` and `r#type`.
473    pub fn iterated(
474        salt: &[u8],
475        bytes: &[u8],
476        r#type: DigestType,
477        mut iterations: u16,
478    ) -> Result<Self, ProtoError> {
479        let alg = r#type.try_into()?;
480        let mut cur = hash_iter([bytes, salt], alg);
481        while iterations > 0 {
482            cur = hash_iter([cur.as_ref(), salt], alg);
483            iterations -= 1;
484        }
485        Ok(Self(cur))
486    }
487
488    /// Hashes the data from the `bytes` iterator with the given `r#type`.
489    pub fn from_iter<'a>(
490        bytes: impl IntoIterator<Item = &'a [u8]>,
491        r#type: DigestType,
492    ) -> Result<Self, ProtoError> {
493        Ok(Self(hash_iter(bytes, r#type.try_into()?)))
494    }
495
496    /// Hashes
497    pub fn new(bytes: &[u8], r#type: DigestType) -> Result<Self, ProtoError> {
498        Ok(Self(digest::digest(r#type.try_into()?, bytes)))
499    }
500}
501
502fn hash_iter<'a>(
503    iter: impl IntoIterator<Item = &'a [u8]>,
504    alg: &'static digest::Algorithm,
505) -> digest::Digest {
506    let mut ctx = digest::Context::new(alg);
507    for d in iter {
508        ctx.update(d);
509    }
510    ctx.finish()
511}
512
513impl AsRef<[u8]> for Digest {
514    fn as_ref(&self) -> &[u8] {
515        self.0.as_ref()
516    }
517}
518
519impl TryFrom<DigestType> for &'static digest::Algorithm {
520    type Error = ProtoError;
521
522    fn try_from(value: DigestType) -> Result<&'static digest::Algorithm, ProtoError> {
523        match value {
524            DigestType::SHA1 => Ok(&digest::SHA1_FOR_LEGACY_USE_ONLY),
525            DigestType::SHA256 => Ok(&digest::SHA256),
526            DigestType::SHA384 => Ok(&digest::SHA384),
527            DigestType::Unknown(other) => Err(ProtoErrorKind::UnknownDigestTypeValue(other).into()),
528        }
529    }
530}
531
532#[cfg(test)]
533mod tests {
534    use rustls_pki_types::pem::PemObject;
535
536    use super::*;
537    use crate::dnssec::test_utils::{hash_test, public_key_test};
538
539    #[test]
540    fn test_ec_p256_pkcs8() {
541        let algorithm = Algorithm::ECDSAP256SHA256;
542        let pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
543        let key = signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
544        public_key_test(&*key);
545
546        let neg_pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
547        let neg = signing_key_from_der(&PrivateKeyDer::from(neg_pkcs8), algorithm).unwrap();
548        hash_test(&*key, &*neg);
549    }
550
551    #[test]
552    fn test_ec_p384_pkcs8() {
553        let algorithm = Algorithm::ECDSAP384SHA384;
554        let pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
555        let key = signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
556        public_key_test(&*key);
557
558        let neg_pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
559        let neg = signing_key_from_der(&PrivateKeyDer::from(neg_pkcs8), algorithm).unwrap();
560        hash_test(&*key, &*neg);
561    }
562
563    #[test]
564    fn test_ed25519() {
565        let algorithm = Algorithm::ED25519;
566        let pkcs8 = Ed25519SigningKey::generate_pkcs8().unwrap();
567        let key = signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
568        public_key_test(&*key);
569
570        let neg_pkcs8 = Ed25519SigningKey::generate_pkcs8().unwrap();
571        let neg = signing_key_from_der(&PrivateKeyDer::from(neg_pkcs8), algorithm).unwrap();
572        hash_test(&*key, &*neg);
573    }
574
575    #[test]
576    fn test_rsa() {
577        // ring currently does not support RSA key generation support.
578        // Generated per the documentation from https://docs.rs/ring/latest/ring/rsa/struct.KeyPair.html#method.from_pkcs8.
579        const KEY_1: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-private-key-1.pk8");
580        const KEY_2: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-private-key-2.pk8");
581
582        let algorithm = Algorithm::RSASHA256;
583        let key_der = PrivateKeyDer::try_from(KEY_1).unwrap();
584        let key = signing_key_from_der(&key_der, algorithm).unwrap();
585        public_key_test(&*key);
586
587        let key_der = PrivateKeyDer::try_from(KEY_2).unwrap();
588        let neg = signing_key_from_der(&key_der, algorithm).unwrap();
589        hash_test(&*key, &*neg);
590    }
591
592    #[test]
593    fn test_ec_encode_decode_pkcs8() {
594        let algorithm = Algorithm::ECDSAP256SHA256;
595        let pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
596        signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
597    }
598
599    #[test]
600    fn test_ed25519_encode_decode_pkcs8() {
601        let pkcs8 = Ed25519SigningKey::generate_pkcs8().unwrap();
602        signing_key_from_der(&PrivateKeyDer::from(pkcs8), Algorithm::ED25519).unwrap();
603    }
604
605    #[test]
606    fn test_rsasha256_encode_decode_pkcs8() {
607        // ring currently does not support RSA key generation support.
608        // Generated per the documentation from https://docs.rs/ring/latest/ring/rsa/struct.KeyPair.html#method.from_pkcs8.
609        const KEY: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-private-key-1.pk8");
610        let key_der = PrivateKeyDer::try_from(KEY).unwrap();
611        signing_key_from_der(&key_der, Algorithm::RSASHA256).unwrap();
612    }
613
614    #[test]
615    fn test_rsasha256_decode_pkcs1() {
616        const KEY: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-pkcs1.pem");
617        let key_der = PrivateKeyDer::from_pem_slice(KEY).unwrap();
618        assert!(matches!(key_der, PrivateKeyDer::Pkcs1(_)));
619        signing_key_from_der(&key_der, Algorithm::RSASHA256).unwrap();
620    }
621}