From 473147ed0454b4e12dd33724302edcf0a7fbfd6b Mon Sep 17 00:00:00 2001 From: silverpill Date: Wed, 23 Nov 2022 11:40:36 +0000 Subject: [PATCH] Move signature type check to activitypub::authentication module --- src/activitypub/authentication.rs | 25 ++++++++++++++++++++----- src/activitypub/receiver.rs | 2 +- src/json_signatures/verify.rs | 23 +++++++++-------------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/activitypub/authentication.rs b/src/activitypub/authentication.rs index c4e5cc0..84e330e 100644 --- a/src/activitypub/authentication.rs +++ b/src/activitypub/authentication.rs @@ -9,7 +9,7 @@ use crate::http_signatures::verify::{ verify_http_signature, HttpSignatureVerificationError as HttpSignatureError, }; -use crate::identity::did::Did; +use crate::identity::{did::Did, signatures::SignatureType}; use crate::json_signatures::verify::{ get_json_signature, verify_ed25519_json_signature, @@ -38,6 +38,9 @@ pub enum AuthenticationError { #[error("no JSON signature")] NoJsonSignature, + #[error("invalid JSON signature type")] + InvalidJsonSignatureType, + #[error("invalid key ID")] InvalidKeyId(#[from] url::ParseError), @@ -51,7 +54,7 @@ pub enum AuthenticationError { InvalidPublicKey(#[from] rsa::pkcs8::Error), #[error("actor and request signer do not match")] - InvalidSigner, + UnexpectedSigner, } fn key_id_to_actor_id(key_id: &str) -> Result { @@ -116,6 +119,9 @@ pub async fn verify_signed_activity( let actor_profile = match signature_data.signer { JsonSigner::ActorKeyId(ref key_id) => { + if signature_data.signature_type != SignatureType::JcsRsaSignature { + return Err(AuthenticationError::InvalidJsonSignatureType); + }; let actor_id = key_id_to_actor_id(key_id)?; let actor_profile = match get_or_import_profile_by_actor_id( db_client, @@ -151,21 +157,30 @@ pub async fn verify_signed_activity( ); }; if let Some(profile) = profiles.pop() { - match did { - Did::Key(did_key) => { + match signature_data.signature_type { + SignatureType::JcsEd25519Signature => { + let did_key = match did { + Did::Key(did_key) => did_key, + _ => return Err(AuthenticationError::InvalidJsonSignatureType), + }; verify_ed25519_json_signature( &did_key, &signature_data.message, &signature_data.signature, )?; }, - Did::Pkh(did_pkh) => { + SignatureType::JcsEip191Signature => { + let did_pkh = match did { + Did::Pkh(did_pkh) => did_pkh, + _ => return Err(AuthenticationError::InvalidJsonSignatureType), + }; verify_eip191_json_signature( &did_pkh, &signature_data.message, &signature_data.signature, )?; }, + _ => return Err(AuthenticationError::InvalidJsonSignatureType), }; profile } else { diff --git a/src/activitypub/receiver.rs b/src/activitypub/receiver.rs index 2252079..5bd70ef 100644 --- a/src/activitypub/receiver.rs +++ b/src/activitypub/receiver.rs @@ -141,7 +141,7 @@ fn require_actor_signature(actor_id: &str, signer_id: &str) signer_id, actor_id, ); - return Err(AuthenticationError::InvalidSigner); + return Err(AuthenticationError::UnexpectedSigner); }; Ok(()) } diff --git a/src/json_signatures/verify.rs b/src/json_signatures/verify.rs index 0f79498..f707a64 100644 --- a/src/json_signatures/verify.rs +++ b/src/json_signatures/verify.rs @@ -1,5 +1,8 @@ +use std::str::FromStr; + use rsa::RsaPublicKey; use serde_json::Value; +use url::Url; use crate::ethereum::identity::verify_eip191_signature; use crate::identity::{ @@ -74,20 +77,12 @@ pub fn get_json_signature( }; let signature_type = proof.proof_type.parse() .map_err(|_| VerificationError::InvalidProof("unsupported proof type"))?; - let signer = match signature_type { - SignatureType::JcsEip191Signature => { - let did_pkh: DidPkh = proof.verification_method.parse() - .map_err(|_| VerificationError::InvalidProof("invalid DID"))?; - JsonSigner::Did(Did::Pkh(did_pkh)) - }, - SignatureType::JcsEd25519Signature => { - let did_key: DidKey = proof.verification_method.parse() - .map_err(|_| VerificationError::InvalidProof("invalid DID"))?; - JsonSigner::Did(Did::Key(did_key)) - }, - SignatureType::JcsRsaSignature => { - JsonSigner::ActorKeyId(proof.verification_method) - }, + let signer = if let Ok(did) = Did::from_str(&proof.verification_method) { + JsonSigner::Did(did) + } else if Url::parse(&proof.verification_method).is_ok() { + JsonSigner::ActorKeyId(proof.verification_method) + } else { + return Err(VerificationError::InvalidProof("unsupported verification method")); }; let message = canonicalize_object(&object)?; let signature = decode_multibase_base58btc(&proof.proof_value)?;