Skip to main content

uselesskey_pgp/
native.rs

1//! OpenPGP native adapters for uselesskey fixtures.
2//!
3//! Provides conversions to native [`pgp`] crate key types from
4//! [`PgpKeyPair`](crate::PgpKeyPair) generated fixtures.
5//!
6//! Gated behind the `native` Cargo feature so consumers that only want
7//! the armored/binary byte surface owned by this crate are not pulled
8//! into the native parser surface.
9
10use std::io::Cursor;
11
12use pgp::composed::{Deserializable, SignedPublicKey, SignedSecretKey};
13
14/// Conversion surface for OpenPGP native key types.
15pub trait PgpNativeExt {
16    /// Parse and return a native `SignedSecretKey`.
17    fn secret_key(&self) -> SignedSecretKey;
18
19    /// Parse and return a native `SignedPublicKey`.
20    fn public_key(&self) -> SignedPublicKey;
21
22    /// Parse and return an armored native secret key.
23    fn secret_key_armor(&self) -> SignedSecretKey;
24
25    /// Parse and return an armored native public key.
26    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}