Merge certs before importing them.

This commit is contained in:
Justus Winter 2023-11-28 12:52:50 +01:00
parent 712add9679
commit 041574d320
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
2 changed files with 23 additions and 13 deletions

View File

@ -45,6 +45,7 @@ use crate::{
},
Config,
Model,
merge_keyring,
serialize_keyring,
output::WkdUrlVariant,
print_error_chain,
@ -60,7 +61,7 @@ const NP: NullPolicy = NullPolicy::new();
pub fn import_certs(config: &mut Config, certs: Vec<Cert>) -> Result<()> {
// Once we get a mutable reference to the cert_store, we're locked
// out of config. Gather the information we need first.
let certs = certs.into_iter()
let certs = merge_keyring(certs)?.into_values()
.map(|cert| {
let fpr = cert.fingerprint();
let userid = cert.with_policy(&config.policy, config.time)

View File

@ -132,6 +132,26 @@ fn load_certs<'a, I>(files: I) -> openpgp::Result<Vec<Cert>>
Ok(certs)
}
/// Merges duplicate certs in a keyring.
fn merge_keyring<C>(certs: C) -> Result<BTreeMap<Fingerprint, Cert>>
where
C: IntoIterator<Item = Cert>,
{
let mut merged = BTreeMap::new();
for cert in certs {
match merged.entry(cert.fingerprint()) {
Entry::Vacant(e) => {
e.insert(cert);
},
Entry::Occupied(mut e) => {
let old = e.get().clone();
e.insert(old.merge_public(cert)?);
},
}
}
Ok(merged)
}
/// Serializes a keyring, adding descriptive headers if armored.
#[allow(dead_code)]
fn serialize_keyring(mut output: &mut dyn io::Write, certs: Vec<Cert>,
@ -151,18 +171,7 @@ fn serialize_keyring(mut output: &mut dyn io::Write, certs: Vec<Cert>,
}
// Otherwise, merge the certs.
let mut merged = BTreeMap::new();
for cert in certs {
match merged.entry(cert.fingerprint()) {
Entry::Vacant(e) => {
e.insert(cert);
},
Entry::Occupied(mut e) => {
let old = e.get().clone();
e.insert(old.merge_public(cert)?);
},
}
}
let merged = merge_keyring(certs)?;
// Then, collect the headers.
let mut headers = Vec::new();