refactor(crypto): Simplify the signature checking method

This commit is contained in:
Damir Jelić
2022-05-27 13:58:08 +02:00
parent dd49a8bd43
commit 7f87abf408
+27 -43
View File
@@ -15,27 +15,28 @@
use std::convert::TryInto;
use ruma::{serde::CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId};
use serde::Deserialize;
use serde_json::Value;
use vodozemac::{olm::Account, Ed25519SecretKey, Ed25519Signature};
use crate::error::SignatureError;
use crate::{error::SignatureError, types::Signatures};
fn to_signable_json(mut value: Value) -> Result<String, SignatureError> {
let json_object = value.as_object_mut().ok_or(SignatureError::NotAnObject)?;
let _ = json_object.remove("signatures");
let _ = json_object.remove("unsigned");
let canonical_json: CanonicalJsonValue = value.try_into()?;
Ok(canonical_json.to_string())
}
pub trait SignJson {
fn sign_json(&self, value: Value) -> Result<Ed25519Signature, SignatureError>;
fn to_signable_json(mut value: Value) -> Result<String, SignatureError> {
let json_object = value.as_object_mut().ok_or(SignatureError::NotAnObject)?;
let _ = json_object.remove("signatures");
let _ = json_object.remove("unsigned");
let canonical_json: CanonicalJsonValue = value.try_into()?;
Ok(canonical_json.to_string())
}
}
impl SignJson for Account {
fn sign_json(&self, value: Value) -> Result<Ed25519Signature, SignatureError> {
let serialized = Self::to_signable_json(value)?;
let serialized = to_signable_json(value)?;
Ok(self.sign(serialized.as_ref()))
}
@@ -43,7 +44,7 @@ impl SignJson for Account {
impl SignJson for Ed25519SecretKey {
fn sign_json(&self, value: Value) -> Result<Ed25519Signature, SignatureError> {
let serialized = Self::to_signable_json(value)?;
let serialized = to_signable_json(value)?;
Ok(self.sign(serialized.as_ref()))
}
@@ -78,44 +79,27 @@ impl VerifyJson for vodozemac::Ed25519PublicKey {
&self,
user_id: &UserId,
key_id: &DeviceKeyId,
mut json: Value,
json: Value,
) -> Result<(), SignatureError> {
#[derive(Debug, Deserialize)]
struct SignedJson {
#[serde(default)]
signatures: Signatures,
}
if key_id.algorithm() != DeviceKeyAlgorithm::Ed25519 {
return Err(SignatureError::UnsupportedAlgorithm);
}
let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?;
let unsigned = json_object.remove("unsigned");
let signatures = json_object.remove("signatures");
let signed_json: SignedJson = serde_json::from_value(json.clone())?;
let canonicalized = to_signable_json(json)?;
let canonical_json: CanonicalJsonValue =
json.clone().try_into().map_err(|_| SignatureError::NotAnObject)?;
let canonical_json: String = canonical_json.to_string();
let signatures = signatures.ok_or(SignatureError::NoSignatureFound)?;
let signature_object = signatures.as_object().ok_or(SignatureError::NoSignatureFound)?;
let signature =
signature_object.get(user_id.as_str()).ok_or(SignatureError::NoSignatureFound)?;
let signature =
signature.get(key_id.to_string()).ok_or(SignatureError::NoSignatureFound)?;
let signature = signature.as_str().ok_or(SignatureError::NoSignatureFound)?;
let signature = vodozemac::Ed25519Signature::from_base64(signature)?;
let ret = self
.verify(canonical_json.as_bytes(), &signature)
.map_err(SignatureError::VerificationError);
let json_object = json.as_object_mut().ok_or(SignatureError::NotAnObject)?;
if let Some(u) = unsigned {
json_object.insert("unsigned".to_owned(), u);
if let Some(signature) = signed_json.signatures.get_signature(user_id, key_id) {
self.verify(canonicalized.as_bytes(), &signature)
.map_err(SignatureError::VerificationError)
} else {
Err(SignatureError::NoSignatureFound)
}
json_object.insert("signatures".to_owned(), signatures);
ret
}
}