use crate::Result;
use crate::Cert;
use crate::packet::{key, Signature, Tag};
use crate::serialize::{
PacketRef, Serialize, SerializeInto,
generic_serialize_into, generic_export_into,
};
impl Serialize for Cert {
fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> {
self.serialize_common(o, false)
}
fn export(&self, o: &mut dyn std::io::Write) -> Result<()> {
self.serialize_common(o, true)
}
}
impl Cert {
/// Serializes or exports the Cert.
///
/// If `export` is true, then non-exportable signatures are not
/// written, and components without any exportable binding
/// signature or revocation are not exported.
///
/// The signatures are ordered from authenticated and most
/// important to not authenticated and most likely to be abused.
/// The order is:
///
/// - Self revocations first. They are authenticated and the
/// most important information.
/// - Self signatures. They are authenticated.
/// - Other signatures. They are not authenticated at this point.
/// - Other revocations. They are not authenticated, and likely
/// not well supported in other implementations, hence the
/// least reliable way of revoking keys and therefore least
/// useful and most likely to be abused.
fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool)
-> Result<()>
{
let primary = self.primary_key().bundle();
PacketRef::PublicKey(primary.key().mark_role_primary_ref())
.serialize(o)?;
// Writes a signature if it is exportable or `! export`.
let serialize_sig =
|o: &mut dyn std::io::Write, sig: &Signature| -> Result<()>
{
if export {
if sig.exportable().is_ok() {
PacketRef::Signature(sig).export(o)?;
}
} else {
PacketRef::Signature(sig).serialize(o)?;
}
Ok(())
};
for s in primary.self_revocations() {
serialize_sig(o, s)?;
}
for s in primary.self_signatures() {
serialize_sig(o, s)?;
}
for s in primary.certifications() {
serialize_sig(o, s)?;
}
for s in primary.other_revocations() {
serialize_sig(o, s)?;
}
for u in self.userids().bundles() {
if export && ! u.self_signatures().iter().chain(u.self_revocations()).any(
|s| s.exportable().is_ok())
{
// No exportable selfsig on this component, skip it.
continue;
}
PacketRef::UserID(u.userid()).serialize(o)?;
for s in u.self_revocations() {
serialize_sig(o, s)?;
}
for