radicle: ensure unique signatures when parsing trailers

To ensure that signatures are unique for verifying an identity a
HashMap is used in place of a Vec of tuples.

This prevents any double counting for quorum checks.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
Fintan Halpenny 2022-12-15 15:49:22 +00:00 committed by Alexis Sellier
parent adaed6a3ac
commit d7170ff9e7
No known key found for this signature in database
3 changed files with 6 additions and 6 deletions

View File

@ -121,7 +121,7 @@ impl Identity<Untrusted> {
let quorum = untrusted
.sigs
.iter()
.filter(|(key, _)| trusted.delegates.iter().any(|d| &**d == key))
.filter(|(key, _)| trusted.delegates.iter().any(|d| **d == **key))
.count();
if quorum < trusted.threshold {
return Err(IdentityError::ThresholdNotReached(

View File

@ -1,6 +1,6 @@
mod id;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};
use std::fmt;
use std::fmt::Write as _;
use std::marker::PhantomData;
@ -122,7 +122,7 @@ pub struct DocAt {
/// The parsed document.
pub doc: Doc<Verified>,
/// The validated commit signatures.
pub sigs: Vec<(PublicKey, Signature)>,
pub sigs: HashMap<PublicKey, Signature>,
}
/// An identity document.

View File

@ -840,10 +840,10 @@ pub mod trailers {
Signature(#[from] SignatureError),
}
pub fn parse_signatures(msg: &str) -> Result<Vec<(PublicKey, Signature)>, Error> {
pub fn parse_signatures(msg: &str) -> Result<HashMap<PublicKey, Signature>, Error> {
let trailers =
git2::message_trailers_strs(msg).map_err(|_| Error::SignatureTrailerFormat)?;
let mut signatures = Vec::with_capacity(trailers.len());
let mut signatures = HashMap::with_capacity(trailers.len());
for (key, val) in trailers.iter() {
if key == SIGNATURE_TRAILER {
@ -851,7 +851,7 @@ pub mod trailers {
let pk = PublicKey::from_str(pk)?;
let sig = Signature::from_str(sig)?;
signatures.push((pk, sig));
signatures.insert(pk, sig);
} else {
return Err(Error::SignatureTrailerFormat);
}