1use core::fmt;
2
3#[cfg(any(feature = "pem", feature = "jwk"))]
4use alloc::string::String;
5use alloc::vec::Vec;
6use pq_oid::Algorithm;
7use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
8
9use crate::error::Result;
10use crate::validation::validate_key_size;
11use crate::{der, pkcs8, spki};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub enum KeyType {
16 Public,
17 Private,
18}
19
20impl fmt::Display for KeyType {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 match self {
23 KeyType::Public => write!(f, "public"),
24 KeyType::Private => write!(f, "private"),
25 }
26 }
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub struct PublicKeyRef<'a> {
36 algorithm: Algorithm,
37 bytes: &'a [u8],
38}
39
40impl<'a> PublicKeyRef<'a> {
41 pub fn new(algorithm: Algorithm, bytes: &'a [u8]) -> Result<Self> {
43 validate_key_size(algorithm, KeyType::Public, bytes)?;
44 Ok(Self { algorithm, bytes })
45 }
46
47 #[inline]
49 pub fn algorithm(&self) -> Algorithm {
50 self.algorithm
51 }
52
53 #[inline]
55 pub fn bytes(&self) -> &'a [u8] {
56 self.bytes
57 }
58
59 #[inline]
61 pub fn key_type(&self) -> KeyType {
62 KeyType::Public
63 }
64
65 pub fn from_spki(der: &'a [u8]) -> Result<Self> {
67 let (alg, key_bytes) = spki::decode_spki(der)?;
68 validate_key_size(alg, KeyType::Public, key_bytes)?;
69 Ok(Self {
70 algorithm: alg,
71 bytes: key_bytes,
72 })
73 }
74
75 pub fn encode_spki_to(&self, out: &mut Vec<u8>) {
77 spki::encode_spki(self.algorithm, self.bytes, out);
78 }
79
80 pub fn encode_der_to(&self, out: &mut Vec<u8>) {
82 self.encode_spki_to(out);
83 }
84
85 pub fn to_spki(&self) -> Vec<u8> {
87 let mut out = Vec::new();
88 self.encode_spki_to(&mut out);
89 out
90 }
91
92 pub fn to_der(&self) -> Vec<u8> {
94 self.to_spki()
95 }
96
97 #[cfg(feature = "pem")]
99 pub fn encode_pem_to(&self, out: &mut String) {
100 let der = self.to_spki();
101 crate::pem::encode_pem_to(&der, crate::pem::label_for_key_type(KeyType::Public), out);
102 }
103
104 #[cfg(feature = "pem")]
106 pub fn to_pem(&self) -> String {
107 let der = self.to_spki();
108 crate::pem::encode_pem(&der, crate::pem::label_for_key_type(KeyType::Public))
109 }
110
111 #[cfg(feature = "jwk")]
113 pub fn to_jwk(&self) -> crate::jwk::PublicJwk {
114 crate::jwk::encode_public_jwk(self.algorithm, self.bytes)
115 }
116
117 pub fn to_owned(&self) -> PublicKey {
119 PublicKey {
120 algorithm: self.algorithm,
121 bytes: self.bytes.to_vec(),
122 }
123 }
124}
125
126#[derive(Clone, Copy, PartialEq, Eq)]
128pub struct PrivateKeyRef<'a> {
129 algorithm: Algorithm,
130 bytes: &'a [u8],
131}
132
133impl fmt::Debug for PrivateKeyRef<'_> {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 f.debug_struct("PrivateKeyRef")
136 .field("algorithm", &self.algorithm)
137 .field("bytes", &"[REDACTED]")
138 .finish()
139 }
140}
141
142impl<'a> PrivateKeyRef<'a> {
143 pub fn new(algorithm: Algorithm, bytes: &'a [u8]) -> Result<Self> {
145 validate_key_size(algorithm, KeyType::Private, bytes)?;
146 Ok(Self { algorithm, bytes })
147 }
148
149 #[inline]
151 pub fn algorithm(&self) -> Algorithm {
152 self.algorithm
153 }
154
155 #[inline]
157 pub fn bytes(&self) -> &'a [u8] {
158 self.bytes
159 }
160
161 #[inline]
163 pub fn key_type(&self) -> KeyType {
164 KeyType::Private
165 }
166
167 pub fn from_pkcs8(der: &'a [u8]) -> Result<Self> {
169 let (alg, key_bytes) = pkcs8::decode_pkcs8(der)?;
170 validate_key_size(alg, KeyType::Private, key_bytes)?;
171 Ok(Self {
172 algorithm: alg,
173 bytes: key_bytes,
174 })
175 }
176
177 pub fn encode_pkcs8_to(&self, out: &mut Vec<u8>) {
179 pkcs8::encode_pkcs8(self.algorithm, self.bytes, out);
180 }
181
182 pub fn encode_der_to(&self, out: &mut Vec<u8>) {
184 self.encode_pkcs8_to(out);
185 }
186
187 pub fn to_pkcs8(&self) -> Zeroizing<Vec<u8>> {
190 let mut out = Vec::new();
191 self.encode_pkcs8_to(&mut out);
192 Zeroizing::new(out)
193 }
194
195 pub fn to_der(&self) -> Zeroizing<Vec<u8>> {
198 self.to_pkcs8()
199 }
200
201 #[cfg(feature = "pem")]
203 pub fn encode_pem_to(&self, out: &mut String) {
204 let mut der = self.to_pkcs8();
205 crate::pem::encode_pem_to(&der, crate::pem::label_for_key_type(KeyType::Private), out);
206 der.zeroize();
207 }
208
209 #[cfg(feature = "pem")]
212 pub fn to_pem(&self) -> Zeroizing<String> {
213 let mut der = self.to_pkcs8();
214 let pem = crate::pem::encode_pem(&der, crate::pem::label_for_key_type(KeyType::Private));
215 der.zeroize();
216 Zeroizing::new(pem)
217 }
218
219 #[cfg(feature = "jwk")]
223 pub fn to_jwk(&self, public_key: &PublicKeyRef<'_>) -> Result<crate::jwk::PrivateJwk> {
224 if public_key.algorithm != self.algorithm {
225 return Err(crate::error::Error::InvalidJwk(
226 "public key algorithm does not match private key",
227 ));
228 }
229 Ok(crate::jwk::encode_private_jwk(
230 self.algorithm,
231 public_key.bytes,
232 self.bytes,
233 ))
234 }
235
236 pub fn to_owned(&self) -> PrivateKey {
238 PrivateKey {
239 algorithm: self.algorithm,
240 bytes: self.bytes.to_vec(),
241 }
242 }
243}
244
245#[derive(Debug, Clone, PartialEq, Eq)]
251pub struct PublicKey {
252 algorithm: Algorithm,
253 bytes: Vec<u8>,
254}
255
256impl PublicKey {
257 pub fn new(algorithm: Algorithm, bytes: Vec<u8>) -> Result<Self> {
259 validate_key_size(algorithm, KeyType::Public, &bytes)?;
260 Ok(Self { algorithm, bytes })
261 }
262
263 pub fn from_bytes(algorithm: Algorithm, bytes: &[u8]) -> Result<Self> {
265 validate_key_size(algorithm, KeyType::Public, bytes)?;
266 Ok(Self {
267 algorithm,
268 bytes: bytes.to_vec(),
269 })
270 }
271
272 #[inline]
274 pub fn algorithm(&self) -> Algorithm {
275 self.algorithm
276 }
277
278 #[inline]
280 pub fn bytes(&self) -> &[u8] {
281 &self.bytes
282 }
283
284 #[inline]
286 pub fn key_type(&self) -> KeyType {
287 KeyType::Public
288 }
289
290 pub fn into_bytes(self) -> Vec<u8> {
292 self.bytes
293 }
294
295 pub fn from_spki(der: &[u8]) -> Result<Self> {
297 let (alg, key_bytes) = spki::decode_spki(der)?;
298 validate_key_size(alg, KeyType::Public, key_bytes)?;
299 Ok(Self {
300 algorithm: alg,
301 bytes: key_bytes.to_vec(),
302 })
303 }
304
305 pub fn encode_spki_to(&self, out: &mut Vec<u8>) {
307 self.as_key_ref().encode_spki_to(out);
308 }
309
310 pub fn encode_der_to(&self, out: &mut Vec<u8>) {
312 self.as_key_ref().encode_der_to(out);
313 }
314
315 pub fn to_spki(&self) -> Vec<u8> {
317 self.as_key_ref().to_spki()
318 }
319
320 pub fn to_der(&self) -> Vec<u8> {
322 self.as_key_ref().to_der()
323 }
324
325 #[cfg(feature = "pem")]
327 pub fn from_pem(pem: &str) -> Result<Self> {
328 let (label, der) = crate::pem::decode_pem(pem)?;
329 if label != crate::pem::label_for_key_type(KeyType::Public) {
330 return Err(crate::error::Error::InvalidPem("expected PUBLIC KEY label"));
331 }
332 Self::from_spki(&der)
333 }
334
335 #[cfg(feature = "pem")]
337 pub fn to_pem(&self) -> String {
338 self.as_key_ref().to_pem()
339 }
340
341 #[cfg(feature = "jwk")]
343 pub fn from_jwk(jwk: &crate::jwk::PublicJwk) -> Result<Self> {
344 let (alg, bytes) = crate::jwk::decode_public_jwk(jwk)?;
345 Ok(Self {
346 algorithm: alg,
347 bytes,
348 })
349 }
350
351 #[cfg(feature = "jwk")]
353 pub fn to_jwk(&self) -> crate::jwk::PublicJwk {
354 self.as_key_ref().to_jwk()
355 }
356
357 pub fn as_key_ref(&self) -> PublicKeyRef<'_> {
359 PublicKeyRef {
360 algorithm: self.algorithm,
361 bytes: &self.bytes,
362 }
363 }
364}
365
366impl AsRef<[u8]> for PublicKey {
367 fn as_ref(&self) -> &[u8] {
368 &self.bytes
369 }
370}
371
372impl<'a> From<PublicKeyRef<'a>> for PublicKey {
373 fn from(key: PublicKeyRef<'a>) -> Self {
374 key.to_owned()
375 }
376}
377
378#[derive(Zeroize, ZeroizeOnDrop)]
384pub struct PrivateKey {
385 #[zeroize(skip)]
386 algorithm: Algorithm,
387 bytes: Vec<u8>,
388}
389
390impl PartialEq for PrivateKey {
391 fn eq(&self, other: &Self) -> bool {
392 self.algorithm == other.algorithm && self.bytes == other.bytes
393 }
394}
395
396impl Eq for PrivateKey {}
397
398impl fmt::Debug for PrivateKey {
399 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400 f.debug_struct("PrivateKey")
401 .field("algorithm", &self.algorithm)
402 .field("bytes", &"[REDACTED]")
403 .finish()
404 }
405}
406
407impl PrivateKey {
408 pub fn new(algorithm: Algorithm, bytes: Vec<u8>) -> Result<Self> {
410 validate_key_size(algorithm, KeyType::Private, &bytes)?;
411 Ok(Self { algorithm, bytes })
412 }
413
414 pub fn from_bytes(algorithm: Algorithm, bytes: &[u8]) -> Result<Self> {
416 validate_key_size(algorithm, KeyType::Private, bytes)?;
417 Ok(Self {
418 algorithm,
419 bytes: bytes.to_vec(),
420 })
421 }
422
423 #[inline]
425 pub fn algorithm(&self) -> Algorithm {
426 self.algorithm
427 }
428
429 #[inline]
431 pub fn bytes(&self) -> &[u8] {
432 &self.bytes
433 }
434
435 #[inline]
437 pub fn key_type(&self) -> KeyType {
438 KeyType::Private
439 }
440
441 pub fn into_bytes(mut self) -> zeroize::Zeroizing<Vec<u8>> {
445 zeroize::Zeroizing::new(core::mem::take(&mut self.bytes))
446 }
447
448 pub fn from_pkcs8(der: &[u8]) -> Result<Self> {
450 let (alg, key_bytes) = pkcs8::decode_pkcs8(der)?;
451 validate_key_size(alg, KeyType::Private, key_bytes)?;
452 Ok(Self {
453 algorithm: alg,
454 bytes: key_bytes.to_vec(),
455 })
456 }
457
458 pub fn encode_pkcs8_to(&self, out: &mut Vec<u8>) {
460 self.as_key_ref().encode_pkcs8_to(out);
461 }
462
463 pub fn encode_der_to(&self, out: &mut Vec<u8>) {
465 self.as_key_ref().encode_der_to(out);
466 }
467
468 pub fn to_pkcs8(&self) -> Zeroizing<Vec<u8>> {
471 self.as_key_ref().to_pkcs8()
472 }
473
474 pub fn to_der(&self) -> Zeroizing<Vec<u8>> {
477 self.as_key_ref().to_der()
478 }
479
480 #[cfg(feature = "pem")]
482 pub fn from_pem(pem: &str) -> Result<Self> {
483 let (label, der) = crate::pem::decode_pem(pem)?;
484 if label != crate::pem::label_for_key_type(KeyType::Private) {
485 return Err(crate::error::Error::InvalidPem(
486 "expected PRIVATE KEY label",
487 ));
488 }
489 Self::from_pkcs8(&der)
490 }
491
492 #[cfg(feature = "pem")]
495 pub fn to_pem(&self) -> Zeroizing<String> {
496 self.as_key_ref().to_pem()
497 }
498
499 #[cfg(feature = "jwk")]
501 pub fn from_jwk(jwk: &crate::jwk::PrivateJwk) -> Result<Self> {
502 let (alg, bytes) = crate::jwk::decode_private_jwk(jwk)?;
503 Ok(Self {
504 algorithm: alg,
505 bytes,
506 })
507 }
508
509 #[cfg(feature = "jwk")]
513 pub fn to_jwk(&self, public_key: &PublicKey) -> Result<crate::jwk::PrivateJwk> {
514 self.as_key_ref().to_jwk(&public_key.as_key_ref())
515 }
516
517 pub fn as_key_ref(&self) -> PrivateKeyRef<'_> {
519 PrivateKeyRef {
520 algorithm: self.algorithm,
521 bytes: &self.bytes,
522 }
523 }
524}
525
526impl AsRef<[u8]> for PrivateKey {
527 fn as_ref(&self) -> &[u8] {
528 &self.bytes
529 }
530}
531
532impl<'a> From<PrivateKeyRef<'a>> for PrivateKey {
533 fn from(key: PrivateKeyRef<'a>) -> Self {
534 key.to_owned()
535 }
536}
537
538impl Clone for PrivateKey {
539 fn clone(&self) -> Self {
541 Self {
542 algorithm: self.algorithm,
543 bytes: self.bytes.clone(),
544 }
545 }
546}
547
548#[derive(Clone, PartialEq, Eq)]
554pub enum Key {
555 Public(PublicKey),
556 Private(PrivateKey),
557}
558
559impl fmt::Debug for Key {
560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
561 match self {
562 Key::Public(k) => f.debug_tuple("Key::Public").field(k).finish(),
563 Key::Private(k) => f.debug_tuple("Key::Private").field(k).finish(),
564 }
565 }
566}
567
568impl Key {
569 #[inline]
571 pub fn algorithm(&self) -> Algorithm {
572 match self {
573 Key::Public(k) => k.algorithm(),
574 Key::Private(k) => k.algorithm(),
575 }
576 }
577
578 #[inline]
580 pub fn key_type(&self) -> KeyType {
581 match self {
582 Key::Public(_) => KeyType::Public,
583 Key::Private(_) => KeyType::Private,
584 }
585 }
586
587 #[inline]
589 pub fn bytes(&self) -> &[u8] {
590 match self {
591 Key::Public(k) => k.bytes(),
592 Key::Private(k) => k.bytes(),
593 }
594 }
595
596 #[inline]
598 pub fn as_public(&self) -> Option<&PublicKey> {
599 match self {
600 Key::Public(k) => Some(k),
601 Key::Private(_) => None,
602 }
603 }
604
605 #[inline]
607 pub fn as_private(&self) -> Option<&PrivateKey> {
608 match self {
609 Key::Public(_) => None,
610 Key::Private(k) => Some(k),
611 }
612 }
613
614 pub fn into_public(self) -> Option<PublicKey> {
616 match self {
617 Key::Public(k) => Some(k),
618 Key::Private(_) => None,
619 }
620 }
621
622 pub fn into_private(self) -> Option<PrivateKey> {
624 match self {
625 Key::Public(_) => None,
626 Key::Private(k) => Some(k),
627 }
628 }
629
630 pub fn from_der(der: &[u8]) -> Result<Self> {
632 let (alg, key_type, key_bytes) = der::decode_der(der)?;
633 match key_type {
634 KeyType::Public => {
635 let key = PublicKey::from_bytes(alg, key_bytes)?;
636 Ok(Key::Public(key))
637 }
638 KeyType::Private => {
639 let key = PrivateKey::from_bytes(alg, key_bytes)?;
640 Ok(Key::Private(key))
641 }
642 }
643 }
644
645 pub fn to_der(&self) -> Vec<u8> {
650 let mut out = Vec::new();
651 self.encode_der_to(&mut out);
652 out
653 }
654
655 pub fn encode_der_to(&self, out: &mut Vec<u8>) {
657 match self {
658 Key::Public(k) => k.encode_der_to(out),
659 Key::Private(k) => k.encode_der_to(out),
660 }
661 }
662
663 #[cfg(feature = "pem")]
665 pub fn from_pem(pem: &str) -> Result<Self> {
666 let (label, der) = crate::pem::decode_pem(pem)?;
667 match label {
668 "PUBLIC KEY" => {
669 let key = PublicKey::from_spki(&der)?;
670 Ok(Key::Public(key))
671 }
672 "PRIVATE KEY" => {
673 let key = PrivateKey::from_pkcs8(&der)?;
674 Ok(Key::Private(key))
675 }
676 _ => Err(crate::error::Error::InvalidPem("unsupported PEM label")),
677 }
678 }
679
680 #[cfg(feature = "pem")]
685 pub fn to_pem(&self) -> String {
686 match self {
687 Key::Public(k) => k.to_pem(),
688 Key::Private(k) => {
689 let mut der = k.to_pkcs8();
690 let pem =
691 crate::pem::encode_pem(&der, crate::pem::label_for_key_type(KeyType::Private));
692 der.zeroize();
693 pem
694 }
695 }
696 }
697
698 #[cfg(feature = "jwk")]
700 pub fn from_jwk(jwk: &crate::jwk::Jwk) -> Result<Self> {
701 match jwk {
702 crate::jwk::Jwk::Public(j) => PublicKey::from_jwk(j).map(Key::Public),
703 crate::jwk::Jwk::Private(j) => PrivateKey::from_jwk(j).map(Key::Private),
704 }
705 }
706
707 #[cfg(feature = "jwk")]
709 pub fn from_jwk_str(json: &str) -> Result<Self> {
710 let jwk = crate::jwk::Jwk::from_json(json)?;
711 Self::from_jwk(&jwk)
712 }
713}
714
715impl AsRef<[u8]> for Key {
716 fn as_ref(&self) -> &[u8] {
717 self.bytes()
718 }
719}
720
721impl From<PublicKey> for Key {
722 fn from(key: PublicKey) -> Self {
723 Key::Public(key)
724 }
725}
726
727impl From<PrivateKey> for Key {
728 fn from(key: PrivateKey) -> Self {
729 Key::Private(key)
730 }
731}
732
733impl<'a> TryFrom<&'a [u8]> for Key {
734 type Error = crate::error::Error;
735
736 fn try_from(der: &'a [u8]) -> Result<Self> {
737 Key::from_der(der)
738 }
739}
740
741#[cfg(test)]
742mod tests {
743 use super::*;
744 use pq_oid::{MlDsa, MlKem, SlhDsa};
745
746 #[test]
747 fn test_public_key_ref_valid() {
748 let alg = Algorithm::MlKem(MlKem::Kem512);
749 let bytes = vec![0u8; 800];
750 let key = PublicKeyRef::new(alg, &bytes).unwrap();
751 assert_eq!(key.algorithm(), alg);
752 assert_eq!(key.bytes().len(), 800);
753 assert_eq!(key.key_type(), KeyType::Public);
754 }
755
756 #[test]
757 fn test_public_key_ref_invalid_size() {
758 let alg = Algorithm::MlKem(MlKem::Kem512);
759 let bytes = vec![0u8; 100];
760 let err = PublicKeyRef::new(alg, &bytes).unwrap_err();
761 assert!(matches!(
762 err,
763 crate::error::Error::KeySizeMismatch {
764 expected: 800,
765 actual: 100,
766 ..
767 }
768 ));
769 }
770
771 #[test]
772 fn test_public_key_ref_empty() {
773 let alg = Algorithm::MlKem(MlKem::Kem512);
774 let err = PublicKeyRef::new(alg, &[]).unwrap_err();
775 assert!(matches!(err, crate::error::Error::EmptyKey));
776 }
777
778 #[test]
779 fn test_private_key_ref_valid() {
780 let alg = Algorithm::MlKem(MlKem::Kem512);
781 let bytes = vec![0u8; 1632];
782 let key = PrivateKeyRef::new(alg, &bytes).unwrap();
783 assert_eq!(key.algorithm(), alg);
784 assert_eq!(key.bytes().len(), 1632);
785 assert_eq!(key.key_type(), KeyType::Private);
786 }
787
788 #[test]
789 fn test_owned_public_key() {
790 let alg = Algorithm::MlKem(MlKem::Kem768);
791 let bytes = vec![0u8; 1184];
792 let key = PublicKey::new(alg, bytes).unwrap();
793 assert_eq!(key.algorithm(), alg);
794 assert_eq!(key.bytes().len(), 1184);
795
796 let key_ref = key.as_key_ref();
797 assert_eq!(key_ref.algorithm(), alg);
798 }
799
800 #[test]
801 fn test_owned_public_key_from_bytes() {
802 let alg = Algorithm::MlKem(MlKem::Kem512);
803 let bytes = [0u8; 800];
804 let key = PublicKey::from_bytes(alg, &bytes).unwrap();
805 assert_eq!(key.bytes().len(), 800);
806 }
807
808 #[test]
809 fn test_owned_public_key_into_bytes() {
810 let alg = Algorithm::MlKem(MlKem::Kem512);
811 let bytes = vec![42u8; 800];
812 let key = PublicKey::new(alg, bytes.clone()).unwrap();
813 let recovered = key.into_bytes();
814 assert_eq!(recovered, bytes);
815 }
816
817 #[test]
818 fn test_ref_to_owned() {
819 let alg = Algorithm::MlKem(MlKem::Kem512);
820 let bytes = vec![0u8; 800];
821 let key_ref = PublicKeyRef::new(alg, &bytes).unwrap();
822 let key: PublicKey = key_ref.into();
823 assert_eq!(key.algorithm(), alg);
824 assert_eq!(key.bytes().len(), 800);
825 }
826
827 #[test]
828 fn test_key_enum() {
829 let alg = Algorithm::MlKem(MlKem::Kem512);
830 let pub_key = PublicKey::new(alg, vec![0u8; 800]).unwrap();
831 let key: Key = pub_key.into();
832 assert_eq!(key.algorithm(), alg);
833 assert_eq!(key.key_type(), KeyType::Public);
834 assert!(key.as_public().is_some());
835 assert!(key.as_private().is_none());
836 }
837
838 #[test]
839 fn test_key_enum_private() {
840 let alg = Algorithm::MlKem(MlKem::Kem512);
841 let priv_key = PrivateKey::new(alg, vec![0u8; 1632]).unwrap();
842 let key: Key = priv_key.into();
843 assert_eq!(key.key_type(), KeyType::Private);
844 assert!(key.as_private().is_some());
845 assert!(key.as_public().is_none());
846 }
847
848 #[test]
849 fn test_key_into_public() {
850 let alg = Algorithm::MlKem(MlKem::Kem512);
851 let pub_key = PublicKey::new(alg, vec![0u8; 800]).unwrap();
852 let key: Key = pub_key.into();
853 assert!(key.into_public().is_some());
854 }
855
856 #[test]
857 fn test_key_into_private() {
858 let alg = Algorithm::MlKem(MlKem::Kem512);
859 let priv_key = PrivateKey::new(alg, vec![0u8; 1632]).unwrap();
860 let key: Key = priv_key.into();
861 assert!(key.into_private().is_some());
862 }
863
864 #[test]
865 fn test_as_ref_u8() {
866 let alg = Algorithm::MlKem(MlKem::Kem512);
867 let pub_key = PublicKey::new(alg, vec![1u8; 800]).unwrap();
868 let bytes: &[u8] = pub_key.as_ref();
869 assert_eq!(bytes.len(), 800);
870 assert_eq!(bytes[0], 1);
871 }
872
873 #[test]
874 fn test_key_type_display() {
875 assert_eq!(KeyType::Public.to_string(), "public");
876 assert_eq!(KeyType::Private.to_string(), "private");
877 }
878
879 #[test]
884 fn test_public_key_ref_spki_roundtrip() {
885 let alg = Algorithm::MlKem(MlKem::Kem512);
886 let bytes = vec![0xABu8; 800];
887 let key = PublicKeyRef::new(alg, &bytes).unwrap();
888 let der = key.to_spki();
889 let decoded = PublicKeyRef::from_spki(&der).unwrap();
890 assert_eq!(decoded.algorithm(), alg);
891 assert_eq!(decoded.bytes(), &bytes[..]);
892 }
893
894 #[test]
895 fn test_public_key_ref_der_roundtrip() {
896 let alg = Algorithm::MlDsa(MlDsa::Dsa44);
897 let bytes = vec![0xCDu8; 1312];
898 let key = PublicKeyRef::new(alg, &bytes).unwrap();
899 let der = key.to_der();
900 let decoded = PublicKeyRef::from_spki(&der).unwrap();
901 assert_eq!(decoded.algorithm(), alg);
902 assert_eq!(decoded.bytes(), &bytes[..]);
903 }
904
905 #[test]
906 fn test_private_key_ref_pkcs8_roundtrip() {
907 let alg = Algorithm::MlKem(MlKem::Kem512);
908 let bytes = vec![0xABu8; 1632];
909 let key = PrivateKeyRef::new(alg, &bytes).unwrap();
910 let der = key.to_pkcs8();
911 let decoded = PrivateKeyRef::from_pkcs8(&der).unwrap();
912 assert_eq!(decoded.algorithm(), alg);
913 assert_eq!(decoded.bytes(), &bytes[..]);
914 }
915
916 #[test]
917 fn test_private_key_ref_der_roundtrip() {
918 let alg = Algorithm::SlhDsa(SlhDsa::Sha2_128s);
919 let bytes = vec![0xEFu8; 64];
920 let key = PrivateKeyRef::new(alg, &bytes).unwrap();
921 let der = key.to_der();
922 let decoded = PrivateKeyRef::from_pkcs8(&der).unwrap();
923 assert_eq!(decoded.algorithm(), alg);
924 assert_eq!(decoded.bytes(), &bytes[..]);
925 }
926
927 #[test]
928 fn test_public_key_spki_roundtrip() {
929 let alg = Algorithm::MlKem(MlKem::Kem768);
930 let bytes = vec![0x42u8; 1184];
931 let key = PublicKey::new(alg, bytes.clone()).unwrap();
932 let der = key.to_spki();
933 let decoded = PublicKey::from_spki(&der).unwrap();
934 assert_eq!(decoded.algorithm(), alg);
935 assert_eq!(decoded.bytes(), &bytes[..]);
936 }
937
938 #[test]
939 fn test_private_key_pkcs8_roundtrip() {
940 let alg = Algorithm::MlDsa(MlDsa::Dsa44);
941 let bytes = vec![0x42u8; 2560];
942 let key = PrivateKey::new(alg, bytes.clone()).unwrap();
943 let der = key.to_pkcs8();
944 let decoded = PrivateKey::from_pkcs8(&der).unwrap();
945 assert_eq!(decoded.algorithm(), alg);
946 assert_eq!(decoded.bytes(), &bytes[..]);
947 }
948
949 #[test]
950 fn test_key_from_der_public() {
951 let alg = Algorithm::MlKem(MlKem::Kem512);
952 let bytes = vec![0xAAu8; 800];
953 let key = PublicKey::new(alg, bytes.clone()).unwrap();
954 let der = key.to_der();
955 let decoded = Key::from_der(&der).unwrap();
956 assert_eq!(decoded.algorithm(), alg);
957 assert_eq!(decoded.key_type(), KeyType::Public);
958 assert_eq!(decoded.bytes(), &bytes[..]);
959 }
960
961 #[test]
962 fn test_key_from_der_private() {
963 let alg = Algorithm::MlKem(MlKem::Kem512);
964 let bytes = vec![0xBBu8; 1632];
965 let key = PrivateKey::new(alg, bytes.clone()).unwrap();
966 let der = key.to_der();
967 let decoded = Key::from_der(&der).unwrap();
968 assert_eq!(decoded.algorithm(), alg);
969 assert_eq!(decoded.key_type(), KeyType::Private);
970 assert_eq!(decoded.bytes(), &bytes[..]);
971 }
972
973 #[test]
974 fn test_key_try_from_bytes() {
975 let alg = Algorithm::MlKem(MlKem::Kem512);
976 let bytes = vec![0xCCu8; 800];
977 let key = PublicKey::new(alg, bytes).unwrap();
978 let der = key.to_der();
979 let decoded: Key = der.as_slice().try_into().unwrap();
980 assert_eq!(decoded.algorithm(), alg);
981 assert_eq!(decoded.key_type(), KeyType::Public);
982 }
983
984 #[test]
985 fn test_key_encode_der_to() {
986 let alg = Algorithm::MlKem(MlKem::Kem512);
987 let bytes = vec![0xDDu8; 800];
988 let key = PublicKey::new(alg, bytes).unwrap();
989 let key = Key::Public(key);
990 let mut buf = Vec::new();
991 key.encode_der_to(&mut buf);
992 let decoded = Key::from_der(&buf).unwrap();
993 assert_eq!(decoded.algorithm(), alg);
994 }
995
996 #[test]
997 fn test_all_algorithms_public_der_roundtrip() {
998 for alg in Algorithm::all() {
999 let bytes = vec![0x42u8; alg.public_key_size()];
1000 let key = PublicKey::new(alg, bytes.clone()).unwrap();
1001 let der = key.to_der();
1002 let decoded = PublicKey::from_spki(&der).unwrap();
1003 assert_eq!(decoded.algorithm(), alg, "failed for {}", alg);
1004 assert_eq!(decoded.bytes(), &bytes[..]);
1005 }
1006 }
1007
1008 #[test]
1009 fn test_all_algorithms_private_der_roundtrip() {
1010 for alg in Algorithm::all() {
1011 let bytes = vec![0x42u8; alg.private_key_size()];
1012 let key = PrivateKey::new(alg, bytes.clone()).unwrap();
1013 let der = key.to_der();
1014 let decoded = PrivateKey::from_pkcs8(&der).unwrap();
1015 assert_eq!(decoded.algorithm(), alg, "failed for {}", alg);
1016 assert_eq!(decoded.bytes(), &bytes[..]);
1017 }
1018 }
1019
1020 #[test]
1021 fn test_all_algorithms_key_from_der_roundtrip() {
1022 for alg in Algorithm::all() {
1023 let pub_bytes = vec![0x42u8; alg.public_key_size()];
1025 let pub_key = PublicKey::new(alg, pub_bytes).unwrap();
1026 let pub_der = pub_key.to_der();
1027 let decoded = Key::from_der(&pub_der).unwrap();
1028 assert_eq!(decoded.algorithm(), alg);
1029 assert_eq!(decoded.key_type(), KeyType::Public);
1030
1031 let priv_bytes = vec![0x42u8; alg.private_key_size()];
1033 let priv_key = PrivateKey::new(alg, priv_bytes).unwrap();
1034 let priv_der = priv_key.to_der();
1035 let decoded = Key::from_der(&priv_der).unwrap();
1036 assert_eq!(decoded.algorithm(), alg);
1037 assert_eq!(decoded.key_type(), KeyType::Private);
1038 }
1039 }
1040
1041 #[cfg(feature = "pem")]
1046 #[test]
1047 fn test_public_key_pem_roundtrip() {
1048 let alg = Algorithm::MlKem(MlKem::Kem512);
1049 let bytes = vec![0xABu8; 800];
1050 let key = PublicKey::new(alg, bytes).unwrap();
1051 let pem = key.to_pem();
1052 let decoded = PublicKey::from_pem(&pem).unwrap();
1053 assert_eq!(decoded.algorithm(), alg);
1054 assert_eq!(decoded.bytes(), key.bytes());
1055 }
1056
1057 #[cfg(feature = "pem")]
1058 #[test]
1059 fn test_private_key_pem_roundtrip() {
1060 let alg = Algorithm::MlKem(MlKem::Kem512);
1061 let bytes = vec![0xCDu8; 1632];
1062 let key = PrivateKey::new(alg, bytes).unwrap();
1063 let pem = key.to_pem();
1064 let decoded = PrivateKey::from_pem(&pem).unwrap();
1065 assert_eq!(decoded.algorithm(), alg);
1066 assert_eq!(decoded.bytes(), key.bytes());
1067 }
1068
1069 #[cfg(feature = "pem")]
1070 #[test]
1071 fn test_public_key_from_pem_wrong_label() {
1072 let alg = Algorithm::MlKem(MlKem::Kem512);
1073 let bytes = vec![0xABu8; 1632];
1074 let key = PrivateKey::new(alg, bytes).unwrap();
1075 let pem = key.to_pem();
1076 let err = PublicKey::from_pem(&pem).unwrap_err();
1077 assert!(matches!(err, crate::error::Error::InvalidPem(_)));
1078 }
1079
1080 #[cfg(feature = "pem")]
1081 #[test]
1082 fn test_private_key_from_pem_wrong_label() {
1083 let alg = Algorithm::MlKem(MlKem::Kem512);
1084 let bytes = vec![0xABu8; 800];
1085 let key = PublicKey::new(alg, bytes).unwrap();
1086 let pem = key.to_pem();
1087 let err = PrivateKey::from_pem(&pem).unwrap_err();
1088 assert!(matches!(err, crate::error::Error::InvalidPem(_)));
1089 }
1090
1091 #[cfg(feature = "pem")]
1092 #[test]
1093 fn test_key_from_pem_public() {
1094 let alg = Algorithm::MlKem(MlKem::Kem768);
1095 let bytes = vec![0x42u8; 1184];
1096 let key = PublicKey::new(alg, bytes).unwrap();
1097 let pem = key.to_pem();
1098 let decoded = Key::from_pem(&pem).unwrap();
1099 assert_eq!(decoded.algorithm(), alg);
1100 assert_eq!(decoded.key_type(), KeyType::Public);
1101 assert_eq!(decoded.bytes(), key.bytes());
1102 }
1103
1104 #[cfg(feature = "pem")]
1105 #[test]
1106 fn test_key_from_pem_private() {
1107 let alg = Algorithm::MlDsa(MlDsa::Dsa44);
1108 let bytes = vec![0x42u8; 2560];
1109 let key = PrivateKey::new(alg, bytes).unwrap();
1110 let pem = key.to_pem();
1111 let decoded = Key::from_pem(&pem).unwrap();
1112 assert_eq!(decoded.algorithm(), alg);
1113 assert_eq!(decoded.key_type(), KeyType::Private);
1114 assert_eq!(decoded.bytes(), key.bytes());
1115 }
1116
1117 #[cfg(feature = "pem")]
1118 #[test]
1119 fn test_key_from_pem_unsupported_label() {
1120 let pem = "-----BEGIN CERTIFICATE-----\nAAA=\n-----END CERTIFICATE-----";
1121 let err = Key::from_pem(pem).unwrap_err();
1122 assert!(matches!(err, crate::error::Error::InvalidPem(_)));
1123 }
1124
1125 #[cfg(feature = "pem")]
1126 #[test]
1127 fn test_public_key_ref_to_pem() {
1128 let alg = Algorithm::MlKem(MlKem::Kem512);
1129 let bytes = vec![0xABu8; 800];
1130 let key_ref = PublicKeyRef::new(alg, &bytes).unwrap();
1131 let pem = key_ref.to_pem();
1132 let decoded = PublicKey::from_pem(&pem).unwrap();
1133 assert_eq!(decoded.algorithm(), alg);
1134 assert_eq!(decoded.bytes(), &bytes[..]);
1135 }
1136
1137 #[cfg(feature = "pem")]
1138 #[test]
1139 fn test_private_key_ref_to_pem() {
1140 let alg = Algorithm::MlKem(MlKem::Kem512);
1141 let bytes = vec![0xCDu8; 1632];
1142 let key_ref = PrivateKeyRef::new(alg, &bytes).unwrap();
1143 let pem = key_ref.to_pem();
1144 let decoded = PrivateKey::from_pem(&pem).unwrap();
1145 assert_eq!(decoded.algorithm(), alg);
1146 assert_eq!(decoded.bytes(), &bytes[..]);
1147 }
1148
1149 #[cfg(feature = "pem")]
1150 #[test]
1151 fn test_all_algorithms_pem_roundtrip() {
1152 for alg in Algorithm::all() {
1153 let pub_bytes = vec![0x42u8; alg.public_key_size()];
1155 let pub_key = PublicKey::new(alg, pub_bytes).unwrap();
1156 let pub_pem = pub_key.to_pem();
1157 let decoded = PublicKey::from_pem(&pub_pem).unwrap();
1158 assert_eq!(
1159 decoded.algorithm(),
1160 alg,
1161 "public PEM roundtrip failed for {}",
1162 alg
1163 );
1164 assert_eq!(decoded.bytes(), pub_key.bytes());
1165
1166 let priv_bytes = vec![0x42u8; alg.private_key_size()];
1168 let priv_key = PrivateKey::new(alg, priv_bytes).unwrap();
1169 let priv_pem = priv_key.to_pem();
1170 let decoded = PrivateKey::from_pem(&priv_pem).unwrap();
1171 assert_eq!(
1172 decoded.algorithm(),
1173 alg,
1174 "private PEM roundtrip failed for {}",
1175 alg
1176 );
1177 assert_eq!(decoded.bytes(), priv_key.bytes());
1178 }
1179 }
1180
1181 #[cfg(feature = "jwk")]
1186 #[test]
1187 fn test_public_key_to_jwk() {
1188 let alg = Algorithm::MlKem(MlKem::Kem512);
1189 let bytes = vec![0x42u8; 800];
1190 let key = PublicKey::new(alg, bytes).unwrap();
1191 let jwk = key.to_jwk();
1192 assert_eq!(jwk.kty, "PQC");
1193 assert_eq!(jwk.alg, "ML-KEM-512");
1194 assert!(!jwk.x.is_empty());
1195 }
1196
1197 #[cfg(feature = "jwk")]
1198 #[test]
1199 fn test_public_key_jwk_roundtrip() {
1200 let alg = Algorithm::MlKem(MlKem::Kem512);
1201 let bytes = vec![0x42u8; 800];
1202 let key = PublicKey::new(alg, bytes).unwrap();
1203 let jwk = key.to_jwk();
1204 let decoded = PublicKey::from_jwk(&jwk).unwrap();
1205 assert_eq!(decoded, key);
1206 }
1207
1208 #[cfg(feature = "jwk")]
1209 #[test]
1210 fn test_private_key_jwk_roundtrip() {
1211 let alg = Algorithm::MlKem(MlKem::Kem512);
1212 let pub_bytes = vec![0x42u8; 800];
1213 let priv_bytes = vec![0xABu8; 1632];
1214 let pub_key = PublicKey::new(alg, pub_bytes).unwrap();
1215 let priv_key = PrivateKey::new(alg, priv_bytes).unwrap();
1216 let jwk = priv_key.to_jwk(&pub_key).unwrap();
1217 let decoded = PrivateKey::from_jwk(&jwk).unwrap();
1218 assert_eq!(decoded, priv_key);
1219 }
1220
1221 #[cfg(feature = "jwk")]
1222 #[test]
1223 fn test_public_key_ref_to_jwk() {
1224 let alg = Algorithm::MlKem(MlKem::Kem768);
1225 let bytes = vec![0x42u8; 1184];
1226 let key_ref = PublicKeyRef::new(alg, &bytes).unwrap();
1227 let jwk = key_ref.to_jwk();
1228 let decoded = PublicKey::from_jwk(&jwk).unwrap();
1229 assert_eq!(decoded.algorithm(), alg);
1230 assert_eq!(decoded.bytes(), &bytes[..]);
1231 }
1232
1233 #[cfg(feature = "jwk")]
1234 #[test]
1235 fn test_private_key_ref_to_jwk() {
1236 let alg = Algorithm::SlhDsa(SlhDsa::Sha2_128s);
1237 let pub_bytes = vec![0x42u8; 32];
1238 let priv_bytes = vec![0xABu8; 64];
1239 let pub_ref = PublicKeyRef::new(alg, &pub_bytes).unwrap();
1240 let priv_ref = PrivateKeyRef::new(alg, &priv_bytes).unwrap();
1241 let jwk = priv_ref.to_jwk(&pub_ref).unwrap();
1242 let decoded = PrivateKey::from_jwk(&jwk).unwrap();
1243 assert_eq!(decoded.algorithm(), alg);
1244 assert_eq!(decoded.bytes(), &priv_bytes[..]);
1245 }
1246
1247 #[cfg(feature = "jwk")]
1248 #[test]
1249 fn test_private_key_to_jwk_algorithm_mismatch() {
1250 let priv_alg = Algorithm::SlhDsa(SlhDsa::Sha2_128s);
1252 let pub_alg = Algorithm::SlhDsa(SlhDsa::Shake128s);
1253 let priv_bytes = vec![0xABu8; 64];
1254 let pub_bytes = vec![0x42u8; 32];
1255 let priv_ref = PrivateKeyRef::new(priv_alg, &priv_bytes).unwrap();
1256 let pub_ref = PublicKeyRef::new(pub_alg, &pub_bytes).unwrap();
1257 let err = priv_ref.to_jwk(&pub_ref).unwrap_err();
1258 assert!(matches!(err, crate::error::Error::InvalidJwk(_)));
1259 }
1260
1261 #[cfg(feature = "jwk")]
1262 #[test]
1263 fn test_key_from_jwk_public() {
1264 let alg = Algorithm::MlDsa(MlDsa::Dsa44);
1265 let bytes = vec![0x42u8; 1312];
1266 let pub_key = PublicKey::new(alg, bytes).unwrap();
1267 let jwk = crate::jwk::Jwk::Public(pub_key.to_jwk());
1268 let decoded = Key::from_jwk(&jwk).unwrap();
1269 assert_eq!(decoded.algorithm(), alg);
1270 assert_eq!(decoded.key_type(), KeyType::Public);
1271 assert_eq!(decoded.bytes(), pub_key.bytes());
1272 }
1273
1274 #[cfg(feature = "jwk")]
1275 #[test]
1276 fn test_key_from_jwk_private() {
1277 let alg = Algorithm::MlDsa(MlDsa::Dsa44);
1278 let pub_bytes = vec![0x42u8; 1312];
1279 let priv_bytes = vec![0xABu8; 2560];
1280 let pub_key = PublicKey::new(alg, pub_bytes).unwrap();
1281 let priv_key = PrivateKey::new(alg, priv_bytes).unwrap();
1282 let jwk = crate::jwk::Jwk::Private(priv_key.to_jwk(&pub_key).unwrap());
1283 let decoded = Key::from_jwk(&jwk).unwrap();
1284 assert_eq!(decoded.algorithm(), alg);
1285 assert_eq!(decoded.key_type(), KeyType::Private);
1286 assert_eq!(decoded.bytes(), priv_key.bytes());
1287 }
1288
1289 #[cfg(feature = "jwk")]
1290 #[test]
1291 fn test_key_from_jwk_str_public() {
1292 let alg = Algorithm::MlKem(MlKem::Kem512);
1293 let bytes = vec![0x42u8; 800];
1294 let key = PublicKey::new(alg, bytes).unwrap();
1295 let json = key.to_jwk().to_json();
1296 let decoded = Key::from_jwk_str(&json).unwrap();
1297 assert_eq!(decoded.algorithm(), alg);
1298 assert_eq!(decoded.key_type(), KeyType::Public);
1299 assert_eq!(decoded.bytes(), key.bytes());
1300 }
1301
1302 #[cfg(feature = "jwk")]
1303 #[test]
1304 fn test_key_from_jwk_str_private() {
1305 let alg = Algorithm::MlKem(MlKem::Kem512);
1306 let pub_bytes = vec![0x42u8; 800];
1307 let priv_bytes = vec![0xABu8; 1632];
1308 let pub_key = PublicKey::new(alg, pub_bytes).unwrap();
1309 let priv_key = PrivateKey::new(alg, priv_bytes).unwrap();
1310 let json = priv_key.to_jwk(&pub_key).unwrap().to_json();
1311 let decoded = Key::from_jwk_str(&json).unwrap();
1312 assert_eq!(decoded.algorithm(), alg);
1313 assert_eq!(decoded.key_type(), KeyType::Private);
1314 assert_eq!(decoded.bytes(), priv_key.bytes());
1315 }
1316
1317 #[cfg(feature = "jwk")]
1318 #[test]
1319 fn test_all_algorithms_jwk_roundtrip() {
1320 for alg in Algorithm::all() {
1321 let pub_bytes = vec![0x42u8; alg.public_key_size()];
1322 let priv_bytes = vec![0xABu8; alg.private_key_size()];
1323 let pub_key = PublicKey::new(alg, pub_bytes).unwrap();
1324 let priv_key = PrivateKey::new(alg, priv_bytes).unwrap();
1325
1326 let pub_jwk = pub_key.to_jwk();
1328 let decoded_pub = PublicKey::from_jwk(&pub_jwk).unwrap();
1329 assert_eq!(
1330 decoded_pub, pub_key,
1331 "public JWK roundtrip failed for {}",
1332 alg
1333 );
1334
1335 let priv_jwk = priv_key.to_jwk(&pub_key).unwrap();
1337 let decoded_priv = PrivateKey::from_jwk(&priv_jwk).unwrap();
1338 assert_eq!(
1339 decoded_priv, priv_key,
1340 "private JWK roundtrip failed for {}",
1341 alg
1342 );
1343 }
1344 }
1345
1346 #[cfg(feature = "pem")]
1347 #[test]
1348 fn test_real_fixture_pem_types_roundtrip() {
1349 use pq_oid::SlhDsa;
1350
1351 let fixtures: &[(&str, Algorithm, KeyType)] = &[
1352 (
1353 include_str!("../../test-data/test-keys/ml_kem_512_pub.pem"),
1354 Algorithm::MlKem(MlKem::Kem512),
1355 KeyType::Public,
1356 ),
1357 (
1358 include_str!("../../test-data/test-keys/ml_kem_512_priv.pem"),
1359 Algorithm::MlKem(MlKem::Kem512),
1360 KeyType::Private,
1361 ),
1362 (
1363 include_str!("../../test-data/test-keys/ml_kem_768_pub.pem"),
1364 Algorithm::MlKem(MlKem::Kem768),
1365 KeyType::Public,
1366 ),
1367 (
1368 include_str!("../../test-data/test-keys/ml_kem_768_priv.pem"),
1369 Algorithm::MlKem(MlKem::Kem768),
1370 KeyType::Private,
1371 ),
1372 (
1373 include_str!("../../test-data/test-keys/ml_kem_1024_pub.pem"),
1374 Algorithm::MlKem(MlKem::Kem1024),
1375 KeyType::Public,
1376 ),
1377 (
1378 include_str!("../../test-data/test-keys/ml_kem_1024_priv.pem"),
1379 Algorithm::MlKem(MlKem::Kem1024),
1380 KeyType::Private,
1381 ),
1382 (
1383 include_str!("../../test-data/test-keys/ml_dsa_44_pub.pem"),
1384 Algorithm::MlDsa(MlDsa::Dsa44),
1385 KeyType::Public,
1386 ),
1387 (
1388 include_str!("../../test-data/test-keys/ml_dsa_44_priv.pem"),
1389 Algorithm::MlDsa(MlDsa::Dsa44),
1390 KeyType::Private,
1391 ),
1392 (
1393 include_str!("../../test-data/test-keys/ml_dsa_65_pub.pem"),
1394 Algorithm::MlDsa(MlDsa::Dsa65),
1395 KeyType::Public,
1396 ),
1397 (
1398 include_str!("../../test-data/test-keys/ml_dsa_65_priv.pem"),
1399 Algorithm::MlDsa(MlDsa::Dsa65),
1400 KeyType::Private,
1401 ),
1402 (
1403 include_str!("../../test-data/test-keys/slh_dsa_sha2_128s_pub.pem"),
1404 Algorithm::SlhDsa(SlhDsa::Sha2_128s),
1405 KeyType::Public,
1406 ),
1407 (
1408 include_str!("../../test-data/test-keys/slh_dsa_sha2_128s_priv.pem"),
1409 Algorithm::SlhDsa(SlhDsa::Sha2_128s),
1410 KeyType::Private,
1411 ),
1412 ];
1413
1414 for (pem_str, expected_alg, expected_type) in fixtures {
1415 match expected_type {
1416 KeyType::Public => {
1417 let key = PublicKey::from_pem(pem_str).unwrap();
1418 assert_eq!(
1419 key.algorithm(),
1420 *expected_alg,
1421 "alg mismatch for {}",
1422 expected_alg
1423 );
1424 let re_pem = key.to_pem();
1425 let re_key = PublicKey::from_pem(&re_pem).unwrap();
1426 assert_eq!(re_key, key, "PEM roundtrip failed for {}", expected_alg);
1427 }
1428 KeyType::Private => {
1429 let key = PrivateKey::from_pem(pem_str).unwrap();
1430 assert_eq!(
1431 key.algorithm(),
1432 *expected_alg,
1433 "alg mismatch for {}",
1434 expected_alg
1435 );
1436 let re_pem = key.to_pem();
1437 let re_key = PrivateKey::from_pem(&re_pem).unwrap();
1438 assert_eq!(re_key, key, "PEM roundtrip failed for {}", expected_alg);
1439 }
1440 }
1441
1442 let key = Key::from_pem(pem_str).unwrap();
1444 assert_eq!(key.algorithm(), *expected_alg);
1445 assert_eq!(key.key_type(), *expected_type);
1446 }
1447 }
1448}