Refactor signature verifiers

This commit is contained in:
silverpill 2022-11-10 21:52:45 +00:00
parent db00ad1623
commit 64546ecabe
6 changed files with 51 additions and 42 deletions

View file

@ -11,7 +11,7 @@ use crate::frontend::get_subscription_page_url;
use crate::identity::{ use crate::identity::{
claims::create_identity_claim, claims::create_identity_claim,
did::Did, did::Did,
minisign::verify_minisign_identity_proof, minisign::verify_minisign_signature,
signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN}, signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN},
}; };
use crate::models::profiles::types::{ use crate::models::profiles::types::{
@ -55,7 +55,7 @@ pub fn parse_identity_proof(
if proof_type != PROOF_TYPE_ID_MINISIGN { if proof_type != PROOF_TYPE_ID_MINISIGN {
return Err(ValidationError("unknown proof type")); return Err(ValidationError("unknown proof type"));
}; };
verify_minisign_identity_proof( verify_minisign_signature(
did_key, did_key,
&message, &message,
&signature, &signature,

View file

@ -12,8 +12,8 @@ use crate::http_signatures::verify::{
use crate::identity::did::Did; use crate::identity::did::Did;
use crate::json_signatures::verify::{ use crate::json_signatures::verify::{
get_json_signature, get_json_signature,
verify_jcs_rsa_signature, verify_eip191_json_signature,
verify_jcs_eip191_signature, verify_rsa_json_signature,
JsonSignatureVerificationError as JsonSignatureError, JsonSignatureVerificationError as JsonSignatureError,
JsonSigner, JsonSigner,
}; };
@ -134,7 +134,7 @@ pub async fn verify_signed_activity(
.ok_or(AuthenticationError::ActorError("invalid profile".to_string()))?; .ok_or(AuthenticationError::ActorError("invalid profile".to_string()))?;
let public_key = let public_key =
deserialize_public_key(&actor.public_key.public_key_pem)?; 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 actor_profile
}, },
JsonSigner::DidPkh(did_pkh) => { JsonSigner::DidPkh(did_pkh) => {
@ -151,7 +151,7 @@ pub async fn verify_signed_activity(
); );
}; };
if let Some(profile) = profiles.pop() { if let Some(profile) = profiles.pop() {
verify_jcs_eip191_signature( verify_eip191_json_signature(
&did_pkh, &did_pkh,
&signature_data.message, &signature_data.message,
&signature_data.signature, &signature_data.signature,

View file

@ -1,22 +1,36 @@
use crate::errors::ValidationError;
use crate::identity::did_pkh::DidPkh; use crate::identity::did_pkh::DidPkh;
use super::signatures::recover_address; use super::signatures::{recover_address, SignatureError};
use super::utils::address_to_string; 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 /// Verifies proof of address ownership
pub fn verify_eip191_identity_proof( pub fn verify_eip191_identity_proof(
did: &DidPkh, did: &DidPkh,
message: &str, message: &str,
signature: &str, signature: &str,
) -> Result<(), ValidationError> { ) -> Result<(), Eip191VerificationError> {
let signature_data = signature.parse() verify_eip191_signature(did, message, signature)
.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(())
} }
#[cfg(test)] #[cfg(test)]

View file

@ -79,7 +79,7 @@ fn parse_minisign_signature(signature_b64: &str)
Ok(signature) Ok(signature)
} }
fn verify_signature( fn verify_ed25519_signature(
message: &str, message: &str,
signer: [u8; 32], signer: [u8; 32],
signature: [u8; 64], signature: [u8; 64],
@ -105,7 +105,7 @@ pub enum VerificationError {
SignatureError(#[from] SignatureError), SignatureError(#[from] SignatureError),
} }
pub fn verify_minisign_identity_proof( pub fn verify_minisign_signature(
signer: &DidKey, signer: &DidKey,
message: &str, message: &str,
signature: &str, signature: &str,
@ -113,7 +113,11 @@ pub fn verify_minisign_identity_proof(
let ed25519_key = signer.try_ed25519_key()?; let ed25519_key = signer.try_ed25519_key()?;
let ed25519_signature = parse_minisign_signature(signature)?; let ed25519_signature = parse_minisign_signature(signature)?;
let message = format!("{}\n", message); let message = format!("{}\n", message);
verify_signature(&message, ed25519_key, ed25519_signature)?; verify_ed25519_signature(
&message,
ed25519_key,
ed25519_signature,
)?;
Ok(()) Ok(())
} }
@ -122,13 +126,13 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_verify_minisign_identity_proof() { fn test_verify_minisign_signature() {
let minisign_key = let minisign_key =
"RWSA58rRENpGFYwAjRjbdST7VHFoIuH9JBHfO2u6i5JgANPIoQhABAF/"; "RWSA58rRENpGFYwAjRjbdST7VHFoIuH9JBHfO2u6i5JgANPIoQhABAF/";
let message = "test"; let message = "test";
let minisign_signature = let minisign_signature =
"RUSA58rRENpGFVKxdZGMG1WdIJ+dlyP83qOqw6GP0H/Li6Brug2A3mFKLtleIRLi6IIG0smzOlX5CEsisNnc897OUHIOSNLsQQs="; "RUSA58rRENpGFVKxdZGMG1WdIJ+dlyP83qOqw6GP0H/Li6Brug2A3mFKLtleIRLi6IIG0smzOlX5CEsisNnc897OUHIOSNLsQQs=";
let signer = minisign_key_to_did(minisign_key).unwrap(); 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();
} }
} }

View file

@ -1,10 +1,7 @@
use rsa::RsaPublicKey; use rsa::RsaPublicKey;
use serde_json::Value; use serde_json::Value;
use crate::ethereum::{ use crate::ethereum::identity::verify_eip191_signature;
signatures::recover_address,
utils::address_to_string,
};
use crate::identity::{ use crate::identity::{
did_pkh::DidPkh, did_pkh::DidPkh,
signatures::{PROOF_TYPE_JCS_EIP191, PROOF_TYPE_JCS_RSA}, signatures::{PROOF_TYPE_JCS_EIP191, PROOF_TYPE_JCS_RSA},
@ -90,7 +87,7 @@ pub fn get_json_signature(
Ok(signature_data) Ok(signature_data)
} }
pub fn verify_jcs_rsa_signature( pub fn verify_rsa_json_signature(
signature_data: &SignatureData, signature_data: &SignatureData,
signer_key: &RsaPublicKey, signer_key: &RsaPublicKey,
) -> Result<(), VerificationError> { ) -> Result<(), VerificationError> {
@ -105,19 +102,13 @@ pub fn verify_jcs_rsa_signature(
Ok(()) Ok(())
} }
pub fn verify_jcs_eip191_signature( pub fn verify_eip191_json_signature(
signer: &DidPkh, signer: &DidPkh,
message: &str, message: &str,
signature: &str, signature: &str,
) -> Result<(), VerificationError> { ) -> Result<(), VerificationError> {
let signature_data = signature.parse() verify_eip191_signature(signer, message, signature)
.map_err(|_| VerificationError::InvalidProof("invalid proof"))?; .map_err(|_| VerificationError::InvalidSignature)
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(())
} }
#[cfg(test)] #[cfg(test)]
@ -178,7 +169,7 @@ mod tests {
assert_eq!(signature_data.signer, expected_signer); assert_eq!(signature_data.signer, expected_signer);
let signer_public_key = RsaPublicKey::from(signer_key); let signer_public_key = RsaPublicKey::from(signer_key);
let result = verify_jcs_rsa_signature( let result = verify_rsa_json_signature(
&signature_data, &signature_data,
&signer_public_key, &signer_public_key,
); );

View file

@ -27,13 +27,13 @@ use crate::identity::{
did_pkh::DidPkh, did_pkh::DidPkh,
minisign::{ minisign::{
minisign_key_to_did, minisign_key_to_did,
verify_minisign_identity_proof, verify_minisign_signature,
}, },
signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN}, signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN},
}; };
use crate::json_signatures::{ use crate::json_signatures::{
create::{add_integrity_proof, IntegrityProof}, 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::oauth::auth::get_current_user;
use crate::mastodon_api::pagination::get_paginated_response; use crate::mastodon_api::pagination::get_paginated_response;
@ -269,7 +269,7 @@ async fn send_signed_update(
let proof = match signer { let proof = match signer {
Did::Key(_) => return Err(ValidationError("unsupported DID type").into()), Did::Key(_) => return Err(ValidationError("unsupported DID type").into()),
Did::Pkh(signer) => { 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"))?; .map_err(|_| ValidationError("invalid signature"))?;
IntegrityProof::jcs_eip191(&signer, &data.signature) IntegrityProof::jcs_eip191(&signer, &data.signature)
}, },
@ -350,7 +350,7 @@ async fn create_identity_proof(
// Verify proof // Verify proof
let proof_type = match did { let proof_type = match did {
Did::Key(ref did_key) => { Did::Key(ref did_key) => {
verify_minisign_identity_proof( verify_minisign_signature(
did_key, did_key,
&message, &message,
&proof_data.signature, &proof_data.signature,
@ -375,7 +375,7 @@ async fn create_identity_proof(
did_pkh, did_pkh,
&message, &message,
&proof_data.signature, &proof_data.signature,
)?; ).map_err(|_| ValidationError("invalid signature"))?;
PROOF_TYPE_ID_EIP191 PROOF_TYPE_ID_EIP191
}, },
}; };