fix: verify_json algorithm

This commit is contained in:
Timo Kösters 2021-04-21 21:44:17 +02:00 committed by gnieto
parent 27e47eaddc
commit 4f16b9357c
2 changed files with 27 additions and 40 deletions

View File

@ -1,5 +1,7 @@
# [unreleased] # [unreleased]
* Fix verify_json signature check algorithm
# 0.7.0 # 0.7.0
Breaking changes: Breaking changes:

View File

@ -249,50 +249,34 @@ pub fn verify_json(
let signature_map = match object.get("signatures") { let signature_map = match object.get("signatures") {
Some(CanonicalJsonValue::Object(signatures)) => signatures.clone(), Some(CanonicalJsonValue::Object(signatures)) => signatures.clone(),
Some(_) => return Err(Error::new("field `signatures` must be a JSON object")), Some(_) => return Err(Error::new("field `signatures` must be a JSON object")),
None => return Err(Error::new("JSON object must contain a `signatures` field.")), None => return Err(Error::new("JSON object must contain a `signatures` field")),
}; };
for (entity_id, public_keys) in public_key_map { for (entity_id, signature_set) in signature_map {
let signature_set = match signature_map.get(entity_id) { let signature_set = match signature_set {
Some(CanonicalJsonValue::Object(set)) => set, CanonicalJsonValue::Object(set) => set,
Some(_) => return Err(Error::new("signature sets must be JSON objects")), _ => return Err(Error::new("signature sets must be JSON objects")),
};
let public_keys = match public_key_map.get(&entity_id) {
Some(keys) => keys,
None => { None => {
return Err(Error::new(format!("no signatures found for entity `{}`", entity_id))) return Err(Error::new(format!(
"no keys for signature in public_key_map for `{}`",
entity_id
)))
} }
}; };
let mut maybe_signature = None; for (key_id, signature) in &signature_set {
let mut maybe_public_key = None; let signature = match signature {
CanonicalJsonValue::String(s) => s,
for (key_id, public_key) in public_keys { _ => return Err(Error::new("signature must be a string")),
// Since only ed25519 is supported right now, we don't actually need to check what the
// algorithm is. If it split successfully, it's ed25519.
if split_id(key_id).is_err() {
break;
}
if let Some(signature) = signature_set.get(key_id) {
maybe_signature = Some(signature);
maybe_public_key = Some(public_key);
break;
}
}
let signature = match maybe_signature {
Some(CanonicalJsonValue::String(signature)) => signature,
Some(_) => return Err(Error::new("signature must be a string")),
None => {
return Err(Error::new("event is not signed with any of the given public keys"))
}
}; };
let public_key = match maybe_public_key { let public_key = public_keys
Some(public_key) => public_key, .get(key_id)
None => { .ok_or_else(|| Error::new("no key for signature in public_key_map"))?;
return Err(Error::new("event is not signed with any of the given public keys"))
}
};
let signature_bytes = decode_config(signature, STANDARD_NO_PAD)?; let signature_bytes = decode_config(signature, STANDARD_NO_PAD)?;
@ -300,6 +284,7 @@ pub fn verify_json(
verify_json_with(&Ed25519Verifier, &public_key_bytes, &signature_bytes, object)?; verify_json_with(&Ed25519Verifier, &public_key_bytes, &signature_bytes, object)?;
} }
}
Ok(()) Ok(())
} }