1use std::io::Cursor;
11
12use pgp::composed::{Deserializable, SignedPublicKey, SignedSecretKey};
13
14pub trait PgpNativeExt {
16 fn secret_key(&self) -> SignedSecretKey;
18
19 fn public_key(&self) -> SignedPublicKey;
21
22 fn secret_key_armor(&self) -> SignedSecretKey;
24
25 fn public_key_armor(&self) -> SignedPublicKey;
27}
28
29impl PgpNativeExt for crate::PgpKeyPair {
30 fn secret_key(&self) -> SignedSecretKey {
31 SignedSecretKey::from_bytes(Cursor::new(self.private_key_binary()))
32 .expect("failed to parse uselesskey PGP private key bytes")
33 }
34
35 fn public_key(&self) -> SignedPublicKey {
36 SignedPublicKey::from_bytes(Cursor::new(self.public_key_binary()))
37 .expect("failed to parse uselesskey PGP public key bytes")
38 }
39
40 fn secret_key_armor(&self) -> SignedSecretKey {
41 let (key, _) = SignedSecretKey::from_armor_single(Cursor::new(self.private_key_armored()))
42 .expect("failed to parse armored uselesskey PGP private key");
43 key
44 }
45
46 fn public_key_armor(&self) -> SignedPublicKey {
47 let (key, _) = SignedPublicKey::from_armor_single(Cursor::new(self.public_key_armored()))
48 .expect("failed to parse armored uselesskey PGP public key");
49 key
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use pgp::types::KeyDetails;
56 use uselesskey_core::Factory;
57
58 use super::PgpNativeExt;
59 use crate::{PgpFactoryExt, PgpSpec};
60
61 #[test]
62 fn parse_round_trip_binary_and_armor() {
63 let fx = Factory::random();
64 let keypair = fx.pgp("fixture", PgpSpec::ed25519());
65
66 assert_eq!(
67 keypair.fingerprint(),
68 keypair.secret_key().fingerprint().to_string()
69 );
70 assert_eq!(
71 keypair.fingerprint(),
72 keypair.secret_key_armor().fingerprint().to_string()
73 );
74 assert_eq!(
75 keypair.fingerprint(),
76 keypair.public_key().fingerprint().to_string()
77 );
78 assert_eq!(
79 keypair.fingerprint(),
80 keypair.public_key_armor().fingerprint().to_string()
81 );
82 }
83}