use git2::Oid;
use serde::ser::Error;
use sequoia_openpgp::{
Cert,
Fingerprint,
Packet,
armor::{
Kind,
Writer,
},
cert::{
prelude::{SubordinateKeyAmalgamation, UserIDAmalgamation},
},
packet::{
key::PublicParts,
Signature,
},
serialize::Serialize,
};
use crate::{
Result,
};
pub fn prune_cert<S, U>(c: Cert,
subkeys: S, userids: U)
-> Result<Cert>
where
S: FnMut(&SubordinateKeyAmalgamation<PublicParts>) -> bool,
U: FnMut(&UserIDAmalgamation) -> bool,
{
let c = c.retain_user_attributes(|_| false)
.retain_subkeys(|s| s.self_signatures().any(
|s| s.key_flags().map(|f| f.for_signing())
.unwrap_or(false)));
let mut acc = Vec::new();
let pk_bundle = c.primary_key().bundle();
acc.push(pk_bundle.key().clone().into());
for s in pk_bundle.self_signatures() {
acc.push(s.clone().into())
}
for s in pk_bundle.self_revocations() {
acc.push(s.clone().into())
}
for skb in c.keys().subkeys().filter(subkeys) {
acc.push(skb.key().clone().into());
for s in skb.self_signatures() {
acc.push(s.clone().into())
}
for s in skb.self_revocations() {
acc.push(s.clone().into())
}
}
for uidb in c.userids().filter(userids) {
acc.push(uidb.userid().clone().into());
for s in uidb.self_signatures() {
acc.push(s.clone().into())
}
for s in uidb.self_revocations() {
acc.push(s.clone().into())
}
}
Ok(Cert::from_packets(acc.into_iter())?)
}
#[allow(dead_code)]
pub fn deserialize_oid<'de, D>(deserializer: D)
-> std::result::Result<Oid, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::{Deserialize, Error};
String::deserialize(deserializer)
.and_then(|s| s.parse().map_err(|e| Error::custom(e)))
}
pub fn serialize_oid<S>(v: &Oid, serializer: S)
-> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&v.to_string())
}
#[allow(dead_code)]
pub fn serialize_optional_oid<S>(v: &Option<&Oid>, serializer: S)
-> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if let Some(v) = v {
serializer.serialize_str(&v.to_string())
} else {
serializer.serialize_none()
}
}
pub fn serialize_fp<S>(v: &Fingerprint, serializer: S)
-> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&format!("{}", v))
}
pub fn serialize_packet<S>(p: &Packet, serializer: S)
-> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut writer = Writer::new(Vec::new(), Kind::File).map_err(Error::custom)?;
p.serialize(&mut writer).map_err(Error::custom)?;
let buffer = writer.finalize().map_err(Error::custom)?;
serializer.serialize_str(&String::from_utf8_lossy(&buffer))
}
pub fn serialize_signature<S>(s: &Signature, serializer: S)
-> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serialize_packet(&Packet::from(s.clone()), serializer)
}