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    ///  Internet-Draft              EdDSA for DNSSEC               December 2016
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    ///  in [RFC 8032]. Breaking tradition, the keys are encoded in little-
270    ///  endian byte order.
271    /// ```
272    pub fn from_public_bytes(public_key: Cow<'k, [u8]>) -> ProtoResult<Self> {
273        if public_key.len() != ED25519_PUBLIC_KEY_LEN {
274            return Err(format!(
275                "expected {} byte public_key: {}",
276                ED25519_PUBLIC_KEY_LEN,
277                public_key.len()
278            )
279            .into());
280        }
281
282        Ok(Self { raw: public_key })
283    }
284}
285
286impl PublicKey for Ed25519<'_> {
287    // TODO: just store reference to public key bytes in ctor...
288    fn public_bytes(&self) -> &[u8] {
289        self.raw.as_ref()
290    }
291
292    fn verify(&self, message: &[u8], signature: &[u8]) -> ProtoResult<()> {
293        let public_key = signature::UnparsedPublicKey::new(&signature::ED25519, self.raw.as_ref());
294        public_key.verify(message, signature).map_err(Into::into)
295    }
296
297    fn algorithm(&self) -> Algorithm {
298        Algorithm::ED25519
299    }
300}
301
302/// Rsa public key
303pub struct Rsa<'k> {
304    raw: &'k [u8],
305    pkey: RSAPublicKey<'k>,
306    algorithm: Algorithm,
307}
308
309impl<'k> Rsa<'k> {
310    /// ```text
311    /// RFC 3110              RSA SIGs and KEYs in the DNS              May 2001
312    ///
313    ///       2. RSA Public KEY Resource Records
314    ///
315    ///  RSA public keys are stored in the DNS as KEY RRs using algorithm
316    ///  number 5 [RFC2535].  The structure of the algorithm specific portion
317    ///  of the RDATA part of such RRs is as shown below.
318    ///
319    ///        Field             Size
320    ///        -----             ----
321    ///        exponent length   1 or 3 octets (see text)
322    ///        exponent          as specified by length field
323    ///        modulus           remaining space
324    ///
325    ///  For interoperability, the exponent and modulus are each limited to
326    ///  4096 bits in length.  The public key exponent is a variable length
327    ///  unsigned integer.  Its length in octets is represented as one octet
328    ///  if it is in the range of 1 to 255 and by a zero octet followed by a
329    ///  two octet unsigned length if it is longer than 255 bytes.  The public
330    ///  key modulus field is a multiprecision unsigned integer.  The length
331    ///  of the modulus can be determined from the RDLENGTH and the preceding
332    ///  RDATA fields including the exponent.  Leading zero octets are
333    ///  prohibited in the exponent and modulus.
334    ///
335    ///  Note: KEY RRs for use with RSA/SHA1 DNS signatures MUST use this
336    ///  algorithm number (rather than the algorithm number specified in the
337    ///  obsoleted RFC 2537).
338    ///
339    ///  Note: This changes the algorithm number for RSA KEY RRs to be the
340    ///  same as the new algorithm number for RSA/SHA1 SIGs.
341    /// ```
342    pub fn from_public_bytes(raw: &'k [u8], algorithm: Algorithm) -> ProtoResult<Self> {
343        let pkey = RSAPublicKey::try_from(raw)?;
344        Ok(Self {
345            raw,
346            pkey,
347            algorithm,
348        })
349    }
350}
351
352impl PublicKey for Rsa<'_> {
353    fn public_bytes(&self) -> &[u8] {
354        self.raw
355    }
356
357    fn verify(&self, message: &[u8], signature: &[u8]) -> ProtoResult<()> {
358        #[allow(deprecated)]
359        let alg = match self.algorithm {
360            Algorithm::RSASHA256 => &signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY,
361            Algorithm::RSASHA512 => &signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY,
362            Algorithm::RSASHA1 => &signature::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
363            Algorithm::RSASHA1NSEC3SHA1 => {
364                return Err("*ring* doesn't support RSASHA1NSEC3SHA1 yet".into());
365            }
366            _ => unreachable!("non-RSA algorithm passed to RSA verify()"),
367        };
368        let public_key = signature::RsaPublicKeyComponents {
369            n: self.pkey.n(),
370            e: self.pkey.e(),
371        };
372        public_key
373            .verify(alg, message, signature)
374            .map_err(Into::into)
375    }
376
377    fn algorithm(&self) -> Algorithm {
378        self.algorithm
379    }
380}
381
382/// An RSA signing key pair (backed by ring).
383pub struct RsaSigningKey {
384    inner: RsaKeyPair,
385    algorithm: Algorithm,
386}
387
388impl RsaSigningKey {
389    /// Decode signing key pair from DER.
390    pub fn from_key_der(key: &PrivateKeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
391        match key {
392            PrivateKeyDer::Pkcs8(key) => Self::from_pkcs8(key, algorithm),
393            PrivateKeyDer::Pkcs1(key) => Self::from_pkcs1(key, algorithm),
394            _ => Err("unsupported key format (only PKCS#8 supported)".into()),
395        }
396    }
397
398    /// Decode signing key pair from DER-encoded PKCS#8 bytes.
399    pub fn from_pkcs8(key: &PrivatePkcs8KeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
400        match algorithm {
401            #[allow(deprecated)]
402            Algorithm::RSASHA1 | Algorithm::RSASHA1NSEC3SHA1 => {
403                return Err("unsupported Algorithm (insecure): {algorithm:?}".into());
404            }
405            Algorithm::RSASHA256 | Algorithm::RSASHA512 => {}
406            _ => return Err("unsupported Algorithm: {algorithm:?}".into()),
407        }
408
409        Ok(Self {
410            inner: RsaKeyPair::from_pkcs8(key.secret_pkcs8_der())?,
411            algorithm,
412        })
413    }
414
415    /// Decode signing key pair from DER-encoded PKCS#1 bytes.
416    pub fn from_pkcs1(key: &PrivatePkcs1KeyDer<'_>, algorithm: Algorithm) -> DnsSecResult<Self> {
417        match algorithm {
418            #[allow(deprecated)]
419            Algorithm::RSASHA1 | Algorithm::RSASHA1NSEC3SHA1 => {
420                return Err("unsupported Algorithm (insecure): {algorithm:?}".into());
421            }
422            Algorithm::RSASHA256 | Algorithm::RSASHA512 => {}
423            _ => return Err("unsupported Algorithm: {algorithm:?}".into()),
424        }
425
426        Ok(Self {
427            inner: RsaKeyPair::from_der(key.secret_pkcs1_der())?,
428            algorithm,
429        })
430    }
431}
432
433impl SigningKey for RsaSigningKey {
434    fn sign(&self, tbs: &TBS) -> DnsSecResult<Vec<u8>> {
435        let encoding = match self.algorithm {
436            Algorithm::RSASHA256 => &RSA_PKCS1_SHA256,
437            Algorithm::RSASHA512 => &RSA_PKCS1_SHA512,
438            _ => unreachable!(),
439        };
440
441        let rng = SystemRandom::new();
442        let mut signature = vec![0; self.inner.public_key().modulus_len()];
443        self.inner
444            .sign(encoding, &rng, tbs.as_ref(), &mut signature)?;
445        Ok(signature)
446    }
447
448    fn to_public_key(&self) -> DnsSecResult<PublicKeyBuf> {
449        let components = PublicKeyComponents::<Vec<u8>>::from(self.inner.public_key());
450
451        let mut buf = Vec::with_capacity(components.e.len() + components.n.len());
452        if components.e.len() > 255 {
453            buf.push(0);
454            buf.push((components.e.len() >> 8) as u8);
455        }
456
457        buf.push(components.e.len() as u8);
458        buf.extend(&components.e);
459        buf.extend(&components.n);
460        Ok(PublicKeyBuf::new(buf, self.algorithm))
461    }
462
463    fn algorithm(&self) -> Algorithm {
464        self.algorithm
465    }
466}
467
468/// Hashing wrapper type.
469#[derive(Clone, Copy, Debug)]
470pub struct Digest(digest::Digest);
471
472impl Digest {
473    /// Hashes the given `data` `iterations` times with the given `salt` and `r#type`.
474    pub fn iterated(
475        salt: &[u8],
476        bytes: &[u8],
477        r#type: DigestType,
478        mut iterations: u16,
479    ) -> Result<Self, ProtoError> {
480        let alg = r#type.try_into()?;
481        let mut cur = hash_iter([bytes, salt], alg);
482        while iterations > 0 {
483            cur = hash_iter([cur.as_ref(), salt], alg);
484            iterations -= 1;
485        }
486        Ok(Self(cur))
487    }
488
489    /// Hashes the data from the `bytes` iterator with the given `r#type`.
490    pub fn from_iter<'a>(
491        bytes: impl IntoIterator<Item = &'a [u8]>,
492        r#type: DigestType,
493    ) -> Result<Self, ProtoError> {
494        Ok(Self(hash_iter(bytes, r#type.try_into()?)))
495    }
496
497    /// Hashes
498    pub fn new(bytes: &[u8], r#type: DigestType) -> Result<Self, ProtoError> {
499        Ok(Self(digest::digest(r#type.try_into()?, bytes)))
500    }
501}
502
503fn hash_iter<'a>(
504    iter: impl IntoIterator<Item = &'a [u8]>,
505    alg: &'static digest::Algorithm,
506) -> digest::Digest {
507    let mut ctx = digest::Context::new(alg);
508    for d in iter {
509        ctx.update(d);
510    }
511    ctx.finish()
512}
513
514impl AsRef<[u8]> for Digest {
515    fn as_ref(&self) -> &[u8] {
516        self.0.as_ref()
517    }
518}
519
520impl TryFrom<DigestType> for &'static digest::Algorithm {
521    type Error = ProtoError;
522
523    fn try_from(value: DigestType) -> Result<&'static digest::Algorithm, ProtoError> {
524        match value {
525            DigestType::SHA1 => Ok(&digest::SHA1_FOR_LEGACY_USE_ONLY),
526            DigestType::SHA256 => Ok(&digest::SHA256),
527            DigestType::SHA384 => Ok(&digest::SHA384),
528            DigestType::Unknown(other) => Err(ProtoErrorKind::UnknownDigestTypeValue(other).into()),
529        }
530    }
531}
532
533#[cfg(test)]
534mod tests {
535    use rustls_pki_types::pem::PemObject;
536
537    use super::*;
538    use crate::dnssec::test_utils::{hash_test, public_key_test};
539
540    #[test]
541    fn test_ec_p256_pkcs8() {
542        let algorithm = Algorithm::ECDSAP256SHA256;
543        let pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
544        let key = signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
545        public_key_test(&*key);
546
547        let neg_pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
548        let neg = signing_key_from_der(&PrivateKeyDer::from(neg_pkcs8), algorithm).unwrap();
549        hash_test(&*key, &*neg);
550    }
551
552    #[test]
553    fn test_ec_p384_pkcs8() {
554        let algorithm = Algorithm::ECDSAP384SHA384;
555        let pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
556        let key = signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
557        public_key_test(&*key);
558
559        let neg_pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
560        let neg = signing_key_from_der(&PrivateKeyDer::from(neg_pkcs8), algorithm).unwrap();
561        hash_test(&*key, &*neg);
562    }
563
564    #[test]
565    fn test_ed25519() {
566        let algorithm = Algorithm::ED25519;
567        let pkcs8 = Ed25519SigningKey::generate_pkcs8().unwrap();
568        let key = signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
569        public_key_test(&*key);
570
571        let neg_pkcs8 = Ed25519SigningKey::generate_pkcs8().unwrap();
572        let neg = signing_key_from_der(&PrivateKeyDer::from(neg_pkcs8), algorithm).unwrap();
573        hash_test(&*key, &*neg);
574    }
575
576    #[test]
577    fn test_rsa() {
578        // ring currently does not support RSA key generation support.
579        // Generated per the documentation from https://docs.rs/ring/latest/ring/rsa/struct.KeyPair.html#method.from_pkcs8.
580        const KEY_1: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-private-key-1.pk8");
581        const KEY_2: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-private-key-2.pk8");
582
583        let algorithm = Algorithm::RSASHA256;
584        let key_der = PrivateKeyDer::try_from(KEY_1).unwrap();
585        let key = signing_key_from_der(&key_der, algorithm).unwrap();
586        public_key_test(&*key);
587
588        let key_der = PrivateKeyDer::try_from(KEY_2).unwrap();
589        let neg = signing_key_from_der(&key_der, algorithm).unwrap();
590        hash_test(&*key, &*neg);
591    }
592
593    #[test]
594    fn test_ec_encode_decode_pkcs8() {
595        let algorithm = Algorithm::ECDSAP256SHA256;
596        let pkcs8 = EcdsaSigningKey::generate_pkcs8(algorithm).unwrap();
597        signing_key_from_der(&PrivateKeyDer::from(pkcs8), algorithm).unwrap();
598    }
599
600    #[test]
601    fn test_ed25519_encode_decode_pkcs8() {
602        let pkcs8 = Ed25519SigningKey::generate_pkcs8().unwrap();
603        signing_key_from_der(&PrivateKeyDer::from(pkcs8), Algorithm::ED25519).unwrap();
604    }
605
606    #[test]
607    fn test_rsasha256_encode_decode_pkcs8() {
608        // ring currently does not support RSA key generation support.
609        // Generated per the documentation from https://docs.rs/ring/latest/ring/rsa/struct.KeyPair.html#method.from_pkcs8.
610        const KEY: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-private-key-1.pk8");
611        let key_der = PrivateKeyDer::try_from(KEY).unwrap();
612        signing_key_from_der(&key_der, Algorithm::RSASHA256).unwrap();
613    }
614
615    #[test]
616    fn test_rsasha256_decode_pkcs1() {
617        const KEY: &[u8] = include_bytes!("../../tests/test-data/rsa-2048-pkcs1.pem");
618        let key_der = PrivateKeyDer::from_pem_slice(KEY).unwrap();
619        assert!(matches!(key_der, PrivateKeyDer::Pkcs1(_)));
620        signing_key_from_der(&key_der, Algorithm::RSASHA256).unwrap();
621    }
622}