//! Public key, public subkey, private key and private subkey packets.
use std::fmt;
use std::mem;
use std::cmp::Ordering;
use time;
use Error;
use crypto::{mpis, KeyPair, SessionKey};
use packet::Tag;
use packet;
use Packet;
use PublicKeyAlgorithm;
use SymmetricAlgorithm;
use HashAlgorithm;
use constants::Curve;
use crypto::s2k::S2K;
use Result;
use conversions::Time;
use crypto::Password;
/// Holds a public key, public subkey, private key or private subkey packet.
///
/// See [Section 5.5 of RFC 4880] for details.
///
/// [Section 5.5 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.5
#[derive(PartialEq, Eq, Hash, Clone)]
pub struct Key {
/// CTB packet header fields.
pub(crate) common: packet::Common,
/// Version of the key packet. Must be 4.
version: u8,
/// When the key was created.
creation_time: time::Tm,
/// Public key algorithm of this signature.
pk_algo: PublicKeyAlgorithm,
/// Public key MPIs.
mpis: mpis::PublicKey,
/// Optional secret part of the key.
secret: Option<SecretKey>,
}
impl fmt::Debug for Key {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Key")
.field("fingerprint", &self.fingerprint())
.field("version", &self.version)
.field("creation_time", &format!("{}", self.creation_time.rfc3339()))
.field("pk_algo", &self.pk_algo)
.field("mpis", &self.mpis)
.field("secret", &self.secret)
.finish()
}
}
impl fmt::Display for Key {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.fingerprint())
}
}
impl Key {
/// Compares the public bits of two keys.
///
/// This returns Ordering::Equal if the public MPIs, version,
/// creation time and algorithm of the two `Key`s match. This
/// does not consider the packet's encoding, packet's tag or the
/// secret key material.
pub fn public_cmp(a: &Self, b: &Self) -> Ordering {
match a.mpis.cmp(&b.mpis) {
Ordering::Equal => (),
o => return o,
}
match a.version.cmp(&b.version) {
Ordering::Equal => (),
o => return o,
}
match a.creation_time.cmp(&b.creation_time) {
Ordering::Equal => (),
o => return o,
}
a.pk_algo.cmp(&b.pk_algo)
}
}
impl Key {
/// Creates a new OpenPGP key packet.
pub fn new(creation_time: time::Tm, pk_algo: PublicKeyAlgorithm,
mpis: mpis::PublicKey, secret: Option<SecretKey>)
-> Result<Key>
{
Ok(Key {
common: Default::default(),
version: 4,
creation_time: creation_time,