From 64546ecabe693c773cc49de577b30c76ce1de534 Mon Sep 17 00:00:00 2001 From: silverpill Date: Thu, 10 Nov 2022 21:52:45 +0000 Subject: [PATCH] Refactor signature verifiers --- src/activitypub/actors/attachments.rs | 4 +-- src/activitypub/authentication.rs | 8 +++--- src/ethereum/identity.rs | 36 +++++++++++++++++++-------- src/identity/minisign.rs | 14 +++++++---- src/json_signatures/verify.rs | 21 +++++----------- src/mastodon_api/accounts/views.rs | 10 ++++---- 6 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/activitypub/actors/attachments.rs b/src/activitypub/actors/attachments.rs index c29363e..c42f33e 100644 --- a/src/activitypub/actors/attachments.rs +++ b/src/activitypub/actors/attachments.rs @@ -11,7 +11,7 @@ use crate::frontend::get_subscription_page_url; use crate::identity::{ claims::create_identity_claim, did::Did, - minisign::verify_minisign_identity_proof, + minisign::verify_minisign_signature, signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN}, }; use crate::models::profiles::types::{ @@ -55,7 +55,7 @@ pub fn parse_identity_proof( if proof_type != PROOF_TYPE_ID_MINISIGN { return Err(ValidationError("unknown proof type")); }; - verify_minisign_identity_proof( + verify_minisign_signature( did_key, &message, &signature, diff --git a/src/activitypub/authentication.rs b/src/activitypub/authentication.rs index 6910f90..64a5443 100644 --- a/src/activitypub/authentication.rs +++ b/src/activitypub/authentication.rs @@ -12,8 +12,8 @@ use crate::http_signatures::verify::{ use crate::identity::did::Did; use crate::json_signatures::verify::{ get_json_signature, - verify_jcs_rsa_signature, - verify_jcs_eip191_signature, + verify_eip191_json_signature, + verify_rsa_json_signature, JsonSignatureVerificationError as JsonSignatureError, JsonSigner, }; @@ -134,7 +134,7 @@ pub async fn verify_signed_activity( .ok_or(AuthenticationError::ActorError("invalid profile".to_string()))?; let public_key = deserialize_public_key(&actor.public_key.public_key_pem)?; - verify_jcs_rsa_signature(&signature_data, &public_key)?; + verify_rsa_json_signature(&signature_data, &public_key)?; actor_profile }, JsonSigner::DidPkh(did_pkh) => { @@ -151,7 +151,7 @@ pub async fn verify_signed_activity( ); }; if let Some(profile) = profiles.pop() { - verify_jcs_eip191_signature( + verify_eip191_json_signature( &did_pkh, &signature_data.message, &signature_data.signature, diff --git a/src/ethereum/identity.rs b/src/ethereum/identity.rs index df9a68d..f7d77d0 100644 --- a/src/ethereum/identity.rs +++ b/src/ethereum/identity.rs @@ -1,22 +1,36 @@ -use crate::errors::ValidationError; use crate::identity::did_pkh::DidPkh; -use super::signatures::recover_address; +use super::signatures::{recover_address, SignatureError}; use super::utils::address_to_string; +#[derive(thiserror::Error, Debug)] +pub enum Eip191VerificationError { + #[error(transparent)] + InvalidSignature(#[from] SignatureError), + + #[error("invalid signer")] + InvalidSigner, +} + +pub fn verify_eip191_signature( + did: &DidPkh, + message: &str, + signature: &str, +) -> Result<(), Eip191VerificationError> { + let signature_data = signature.parse()?; + let signer = recover_address(message.as_bytes(), &signature_data)?; + if address_to_string(signer) != did.address.to_lowercase() { + return Err(Eip191VerificationError::InvalidSigner); + }; + Ok(()) +} + /// Verifies proof of address ownership pub fn verify_eip191_identity_proof( did: &DidPkh, message: &str, signature: &str, -) -> Result<(), ValidationError> { - let signature_data = signature.parse() - .map_err(|_| ValidationError("invalid signature string"))?; - let signer = recover_address(message.as_bytes(), &signature_data) - .map_err(|_| ValidationError("invalid signature"))?; - if address_to_string(signer) != did.address.to_lowercase() { - return Err(ValidationError("invalid proof")); - }; - Ok(()) +) -> Result<(), Eip191VerificationError> { + verify_eip191_signature(did, message, signature) } #[cfg(test)] diff --git a/src/identity/minisign.rs b/src/identity/minisign.rs index 6d51193..4857ec8 100644 --- a/src/identity/minisign.rs +++ b/src/identity/minisign.rs @@ -79,7 +79,7 @@ fn parse_minisign_signature(signature_b64: &str) Ok(signature) } -fn verify_signature( +fn verify_ed25519_signature( message: &str, signer: [u8; 32], signature: [u8; 64], @@ -105,7 +105,7 @@ pub enum VerificationError { SignatureError(#[from] SignatureError), } -pub fn verify_minisign_identity_proof( +pub fn verify_minisign_signature( signer: &DidKey, message: &str, signature: &str, @@ -113,7 +113,11 @@ pub fn verify_minisign_identity_proof( let ed25519_key = signer.try_ed25519_key()?; let ed25519_signature = parse_minisign_signature(signature)?; let message = format!("{}\n", message); - verify_signature(&message, ed25519_key, ed25519_signature)?; + verify_ed25519_signature( + &message, + ed25519_key, + ed25519_signature, + )?; Ok(()) } @@ -122,13 +126,13 @@ mod tests { use super::*; #[test] - fn test_verify_minisign_identity_proof() { + fn test_verify_minisign_signature() { let minisign_key = "RWSA58rRENpGFYwAjRjbdST7VHFoIuH9JBHfO2u6i5JgANPIoQhABAF/"; let message = "test"; let minisign_signature = "RUSA58rRENpGFVKxdZGMG1WdIJ+dlyP83qOqw6GP0H/Li6Brug2A3mFKLtleIRLi6IIG0smzOlX5CEsisNnc897OUHIOSNLsQQs="; let signer = minisign_key_to_did(minisign_key).unwrap(); - verify_minisign_identity_proof(&signer, message, minisign_signature).unwrap(); + verify_minisign_signature(&signer, message, minisign_signature).unwrap(); } } diff --git a/src/json_signatures/verify.rs b/src/json_signatures/verify.rs index 1c97493..c3e8ae7 100644 --- a/src/json_signatures/verify.rs +++ b/src/json_signatures/verify.rs @@ -1,10 +1,7 @@ use rsa::RsaPublicKey; use serde_json::Value; -use crate::ethereum::{ - signatures::recover_address, - utils::address_to_string, -}; +use crate::ethereum::identity::verify_eip191_signature; use crate::identity::{ did_pkh::DidPkh, signatures::{PROOF_TYPE_JCS_EIP191, PROOF_TYPE_JCS_RSA}, @@ -90,7 +87,7 @@ pub fn get_json_signature( Ok(signature_data) } -pub fn verify_jcs_rsa_signature( +pub fn verify_rsa_json_signature( signature_data: &SignatureData, signer_key: &RsaPublicKey, ) -> Result<(), VerificationError> { @@ -105,19 +102,13 @@ pub fn verify_jcs_rsa_signature( Ok(()) } -pub fn verify_jcs_eip191_signature( +pub fn verify_eip191_json_signature( signer: &DidPkh, message: &str, signature: &str, ) -> Result<(), VerificationError> { - let signature_data = signature.parse() - .map_err(|_| VerificationError::InvalidProof("invalid proof"))?; - let signer_address = recover_address(message.as_bytes(), &signature_data) - .map_err(|_| VerificationError::InvalidSignature)?; - if address_to_string(signer_address) != signer.address.to_lowercase() { - return Err(VerificationError::InvalidSignature); - }; - Ok(()) + verify_eip191_signature(signer, message, signature) + .map_err(|_| VerificationError::InvalidSignature) } #[cfg(test)] @@ -178,7 +169,7 @@ mod tests { assert_eq!(signature_data.signer, expected_signer); let signer_public_key = RsaPublicKey::from(signer_key); - let result = verify_jcs_rsa_signature( + let result = verify_rsa_json_signature( &signature_data, &signer_public_key, ); diff --git a/src/mastodon_api/accounts/views.rs b/src/mastodon_api/accounts/views.rs index c197861..a5ab54d 100644 --- a/src/mastodon_api/accounts/views.rs +++ b/src/mastodon_api/accounts/views.rs @@ -27,13 +27,13 @@ use crate::identity::{ did_pkh::DidPkh, minisign::{ minisign_key_to_did, - verify_minisign_identity_proof, + verify_minisign_signature, }, signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN}, }; use crate::json_signatures::{ create::{add_integrity_proof, IntegrityProof}, - verify::verify_jcs_eip191_signature, + verify::verify_eip191_json_signature, }; use crate::mastodon_api::oauth::auth::get_current_user; use crate::mastodon_api::pagination::get_paginated_response; @@ -269,7 +269,7 @@ async fn send_signed_update( let proof = match signer { Did::Key(_) => return Err(ValidationError("unsupported DID type").into()), Did::Pkh(signer) => { - verify_jcs_eip191_signature(&signer, &canonical_json, &data.signature) + verify_eip191_json_signature(&signer, &canonical_json, &data.signature) .map_err(|_| ValidationError("invalid signature"))?; IntegrityProof::jcs_eip191(&signer, &data.signature) }, @@ -350,7 +350,7 @@ async fn create_identity_proof( // Verify proof let proof_type = match did { Did::Key(ref did_key) => { - verify_minisign_identity_proof( + verify_minisign_signature( did_key, &message, &proof_data.signature, @@ -375,7 +375,7 @@ async fn create_identity_proof( did_pkh, &message, &proof_data.signature, - )?; + ).map_err(|_| ValidationError("invalid signature"))?; PROOF_TYPE_ID_EIP191 }, };