signatures: Use BTreeMap instead of HashMap

This commit is contained in:
Jonas Platte 2020-09-29 23:20:53 +02:00
parent 406b8501ac
commit 5ab9c4dc19
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
3 changed files with 21 additions and 22 deletions

View File

@ -1,6 +1,6 @@
//! Functions for signing and verifying JSON and events. //! Functions for signing and verifying JSON and events.
use std::{cmp, collections::HashMap, mem}; use std::{cmp, collections::BTreeMap, mem};
use base64::{decode_config, encode_config, STANDARD_NO_PAD, URL_SAFE_NO_PAD}; use base64::{decode_config, encode_config, STANDARD_NO_PAD, URL_SAFE_NO_PAD};
use ring::digest::{digest, SHA256}; use ring::digest::{digest, SHA256};
@ -147,7 +147,7 @@ where
Some(signatures) => from_value(Value::Object(signatures.clone()))?, Some(signatures) => from_value(Value::Object(signatures.clone()))?,
None => return Err(Error::new("field `signatures` must be a JSON object")), None => return Err(Error::new("field `signatures` must be a JSON object")),
}, },
None => HashMap::with_capacity(1), None => BTreeMap::new(),
}; };
maybe_unsigned = map.remove("unsigned"); maybe_unsigned = map.remove("unsigned");
@ -160,8 +160,7 @@ where
let signature = key_pair.sign(json.as_bytes()); let signature = key_pair.sign(json.as_bytes());
// Insert the new signature in the map we pulled out (or created) previously. // Insert the new signature in the map we pulled out (or created) previously.
let signature_set = let signature_set = signature_map.entry(entity_id.to_string()).or_insert_with(BTreeMap::new);
signature_map.entry(entity_id.to_string()).or_insert_with(|| HashMap::with_capacity(1));
signature_set.insert(signature.id(), signature.base64()); signature_set.insert(signature.id(), signature.base64());
@ -225,7 +224,7 @@ pub fn canonical_json(value: &Value) -> Result<String, Error> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use std::collections::HashMap; /// use std::collections::BTreeMap;
/// ///
/// const PUBLIC_KEY: &str = "XGX0JRS2Af3be3knz2fBiRbApjm2Dh61gXDJA8kcJNI"; /// const PUBLIC_KEY: &str = "XGX0JRS2Af3be3knz2fBiRbApjm2Dh61gXDJA8kcJNI";
/// ///
@ -241,9 +240,9 @@ pub fn canonical_json(value: &Value) -> Result<String, Error> {
/// ).unwrap(); /// ).unwrap();
/// ///
/// // Create the `PublicKeyMap` that will inform `verify_json` which signatures to verify. /// // Create the `PublicKeyMap` that will inform `verify_json` which signatures to verify.
/// let mut public_key_set = HashMap::new(); /// let mut public_key_set = BTreeMap::new();
/// public_key_set.insert("ed25519:1".into(), PUBLIC_KEY.to_string()); /// public_key_set.insert("ed25519:1".into(), PUBLIC_KEY.to_string());
/// let mut public_key_map = HashMap::new(); /// let mut public_key_map = BTreeMap::new();
/// public_key_map.insert("domain".into(), public_key_set); /// public_key_map.insert("domain".into(), public_key_set);
/// ///
/// // Verify at least one signature for each entity in `public_key_map`. /// // Verify at least one signature for each entity in `public_key_map`.
@ -552,7 +551,7 @@ where
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use std::collections::HashMap; /// # use std::collections::BTreeMap;
/// # use ruma_identifiers::RoomVersionId; /// # use ruma_identifiers::RoomVersionId;
/// # use ruma_signatures::verify_event; /// # use ruma_signatures::verify_event;
/// # /// #
@ -585,9 +584,9 @@ where
/// ).unwrap(); /// ).unwrap();
/// ///
/// // Create the `PublicKeyMap` that will inform `verify_json` which signatures to verify. /// // Create the `PublicKeyMap` that will inform `verify_json` which signatures to verify.
/// let mut public_key_set = HashMap::new(); /// let mut public_key_set = BTreeMap::new();
/// public_key_set.insert("ed25519:1".into(), PUBLIC_KEY.to_string()); /// public_key_set.insert("ed25519:1".into(), PUBLIC_KEY.to_string());
/// let mut public_key_map = HashMap::new(); /// let mut public_key_map = BTreeMap::new();
/// public_key_map.insert("domain".into(), public_key_set); /// public_key_map.insert("domain".into(), public_key_set);
/// ///
/// // Verify at least one signature for each entity in `public_key_map`. /// // Verify at least one signature for each entity in `public_key_map`.

View File

@ -1,7 +1,7 @@
//! Public and private key pairs. //! Public and private key pairs.
use std::{ use std::{
collections::HashMap, collections::BTreeMap,
fmt::{Debug, Formatter, Result as FmtResult}, fmt::{Debug, Formatter, Result as FmtResult},
}; };
@ -99,12 +99,12 @@ impl Debug for Ed25519KeyPair {
/// A map from entity names to sets of public keys for that entity. /// A map from entity names to sets of public keys for that entity.
/// ///
/// "Entity" is generally a homeserver, e.g. "example.com". /// "Entity" is generally a homeserver, e.g. "example.com".
pub type PublicKeyMap = HashMap<String, PublicKeySet>; pub type PublicKeyMap = BTreeMap<String, PublicKeySet>;
/// A set of public keys for a single homeserver. /// A set of public keys for a single homeserver.
/// ///
/// This is represented as a map from key ID to Base64-encoded signature. /// This is represented as a map from key ID to Base64-encoded signature.
pub type PublicKeySet = HashMap<String, String>; pub type PublicKeySet = BTreeMap<String, String>;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -172,7 +172,7 @@ fn split_id(id: &str) -> Result<(Algorithm, String), SplitError<'_>> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::collections::HashMap; use std::collections::BTreeMap;
use base64::{decode_config, STANDARD_NO_PAD}; use base64::{decode_config, STANDARD_NO_PAD};
use ring::signature::{Ed25519KeyPair as RingEd25519KeyPair, KeyPair as _}; use ring::signature::{Ed25519KeyPair as RingEd25519KeyPair, KeyPair as _};
@ -318,10 +318,10 @@ mod test {
fn verify_empty_json() { fn verify_empty_json() {
let value = from_str(r#"{"signatures":{"domain":{"ed25519:1":"lXjsnvhVlz8t3etR+6AEJ0IT70WujeHC1CFjDDsVx0xSig1Bx7lvoi1x3j/2/GPNjQM4a2gD34UqsXFluaQEBA"}}}"#).unwrap(); let value = from_str(r#"{"signatures":{"domain":{"ed25519:1":"lXjsnvhVlz8t3etR+6AEJ0IT70WujeHC1CFjDDsVx0xSig1Bx7lvoi1x3j/2/GPNjQM4a2gD34UqsXFluaQEBA"}}}"#).unwrap();
let mut signature_set = HashMap::new(); let mut signature_set = BTreeMap::new();
signature_set.insert("ed25519:1".into(), public_key_string()); signature_set.insert("ed25519:1".into(), public_key_string());
let mut public_key_map = HashMap::new(); let mut public_key_map = BTreeMap::new();
public_key_map.insert("domain".into(), signature_set); public_key_map.insert("domain".into(), signature_set);
assert!(verify_json(&public_key_map, &value).is_ok()); assert!(verify_json(&public_key_map, &value).is_ok());
@ -369,10 +369,10 @@ mod test {
r#"{"one":1,"signatures":{"domain":{"ed25519:1":"t6Ehmh6XTDz7qNWI0QI5tNPSliWLPQP/+Fzz3LpdCS7q1k2G2/5b5Embs2j4uG3ZeivejrzqSVoBcdocRpa+AQ"}},"two":"Two"}"# r#"{"one":1,"signatures":{"domain":{"ed25519:1":"t6Ehmh6XTDz7qNWI0QI5tNPSliWLPQP/+Fzz3LpdCS7q1k2G2/5b5Embs2j4uG3ZeivejrzqSVoBcdocRpa+AQ"}},"two":"Two"}"#
).unwrap(); ).unwrap();
let mut signature_set = HashMap::new(); let mut signature_set = BTreeMap::new();
signature_set.insert("ed25519:1".into(), public_key_string()); signature_set.insert("ed25519:1".into(), public_key_string());
let mut public_key_map = HashMap::new(); let mut public_key_map = BTreeMap::new();
public_key_map.insert("domain".into(), signature_set); public_key_map.insert("domain".into(), signature_set);
assert!(verify_json(&public_key_map, &value).is_ok()); assert!(verify_json(&public_key_map, &value).is_ok());
@ -388,10 +388,10 @@ mod test {
fn fail_verify_json() { fn fail_verify_json() {
let value = from_str(r#"{"not":"empty","signatures":{"domain":"lXjsnvhVlz8t3etR+6AEJ0IT70WujeHC1CFjDDsVx0xSig1Bx7lvoi1x3j/2/GPNjQM4a2gD34UqsXFluaQEBA"}}"#).unwrap(); let value = from_str(r#"{"not":"empty","signatures":{"domain":"lXjsnvhVlz8t3etR+6AEJ0IT70WujeHC1CFjDDsVx0xSig1Bx7lvoi1x3j/2/GPNjQM4a2gD34UqsXFluaQEBA"}}"#).unwrap();
let mut signature_set = HashMap::new(); let mut signature_set = BTreeMap::new();
signature_set.insert("ed25519:1".into(), public_key_string()); signature_set.insert("ed25519:1".into(), public_key_string());
let mut public_key_map = HashMap::new(); let mut public_key_map = BTreeMap::new();
public_key_map.insert("domain".into(), signature_set); public_key_map.insert("domain".into(), signature_set);
assert!(verify_json(&public_key_map, &value).is_err()); assert!(verify_json(&public_key_map, &value).is_err());
@ -466,10 +466,10 @@ mod test {
#[test] #[test]
fn verify_minimal_event() { fn verify_minimal_event() {
let mut signature_set = HashMap::new(); let mut signature_set = BTreeMap::new();
signature_set.insert("ed25519:1".into(), public_key_string()); signature_set.insert("ed25519:1".into(), public_key_string());
let mut public_key_map = HashMap::new(); let mut public_key_map = BTreeMap::new();
public_key_map.insert("domain".into(), signature_set); public_key_map.insert("domain".into(), signature_set);
let value = from_str( let value = from_str(