Verify activities containing EIP-155 integrity proof
This commit is contained in:
parent
cdd3bfb6df
commit
7f9b2a8768
2 changed files with 84 additions and 21 deletions
|
@ -12,10 +12,14 @@ use crate::http_signatures::verify::{
|
|||
use crate::json_signatures::verify::{
|
||||
get_json_signature,
|
||||
verify_jcs_rsa_signature,
|
||||
verify_jcs_eip191_signature,
|
||||
JsonSignatureVerificationError as JsonSignatureError,
|
||||
JsonSigner,
|
||||
};
|
||||
use crate::models::profiles::queries::get_profile_by_remote_actor_id;
|
||||
use crate::models::profiles::queries::{
|
||||
get_profile_by_remote_actor_id,
|
||||
search_profiles_by_did_only,
|
||||
};
|
||||
use crate::models::profiles::types::DbActorProfile;
|
||||
use crate::utils::crypto::deserialize_public_key;
|
||||
use super::fetcher::helpers::get_or_import_profile_by_actor_id;
|
||||
|
@ -108,25 +112,50 @@ pub async fn verify_signed_activity(
|
|||
}
|
||||
})?;
|
||||
|
||||
let JsonSigner::ActorKeyId(ref key_id) = signature_data.signer;
|
||||
let actor_id = key_id_to_actor_id(key_id)?;
|
||||
let actor_profile = match get_or_import_profile_by_actor_id(
|
||||
db_client,
|
||||
&config.instance(),
|
||||
&config.media_dir(),
|
||||
&actor_id,
|
||||
).await {
|
||||
Ok(profile) => profile,
|
||||
Err(HandlerError::DatabaseError(error)) => return Err(error.into()),
|
||||
Err(other_error) => {
|
||||
return Err(AuthenticationError::ActorError(other_error.to_string()));
|
||||
let actor_profile = match signature_data.signer {
|
||||
JsonSigner::ActorKeyId(ref key_id) => {
|
||||
let actor_id = key_id_to_actor_id(key_id)?;
|
||||
let actor_profile = match get_or_import_profile_by_actor_id(
|
||||
db_client,
|
||||
&config.instance(),
|
||||
&config.media_dir(),
|
||||
&actor_id,
|
||||
).await {
|
||||
Ok(profile) => profile,
|
||||
Err(HandlerError::DatabaseError(error)) => {
|
||||
return Err(error.into());
|
||||
},
|
||||
Err(other_error) => {
|
||||
return Err(AuthenticationError::ActorError(other_error.to_string()));
|
||||
},
|
||||
};
|
||||
let actor = actor_profile.actor_json.as_ref()
|
||||
.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)?;
|
||||
actor_profile
|
||||
},
|
||||
JsonSigner::DidPkh(ref signer) => {
|
||||
let mut profiles = search_profiles_by_did_only(db_client, signer).await?;
|
||||
if profiles.len() > 1 {
|
||||
log::info!(
|
||||
"signer with multiple profiles ({})",
|
||||
profiles.len(),
|
||||
);
|
||||
};
|
||||
if let Some(profile) = profiles.pop() {
|
||||
verify_jcs_eip191_signature(
|
||||
signer,
|
||||
&signature_data.message,
|
||||
&signature_data.signature,
|
||||
)?;
|
||||
profile
|
||||
} else {
|
||||
return Err(AuthenticationError::ActorError("unknown signer".to_string()));
|
||||
}
|
||||
},
|
||||
};
|
||||
let actor = actor_profile.actor_json.as_ref()
|
||||
.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)?;
|
||||
|
||||
Ok(actor_profile)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::utils::crypto::verify_signature;
|
|||
use super::canonicalization::{canonicalize_object, CanonicalizationError};
|
||||
use super::create::{
|
||||
IntegrityProof,
|
||||
PROOF_TYPE_JCS_EIP191,
|
||||
PROOF_TYPE_JCS_RSA,
|
||||
PROOF_KEY,
|
||||
PROOF_PURPOSE,
|
||||
|
@ -18,6 +19,7 @@ use super::create::{
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub enum JsonSigner {
|
||||
ActorKeyId(String),
|
||||
DidPkh(DidPkh),
|
||||
}
|
||||
|
||||
pub struct SignatureData {
|
||||
|
@ -62,10 +64,19 @@ pub fn get_json_signature(
|
|||
if proof.proof_purpose != PROOF_PURPOSE {
|
||||
return Err(VerificationError::InvalidProof("invalid proof purpose"));
|
||||
};
|
||||
if proof.proof_type != PROOF_TYPE_JCS_RSA {
|
||||
return Err(VerificationError::InvalidProof("unsupported proof type"));
|
||||
let signer = match proof.proof_type.as_str() {
|
||||
PROOF_TYPE_JCS_EIP191 => {
|
||||
let did = proof.verification_method.parse()
|
||||
.map_err(|_| VerificationError::InvalidProof("invalid DID"))?;
|
||||
JsonSigner::DidPkh(did)
|
||||
},
|
||||
PROOF_TYPE_JCS_RSA => {
|
||||
JsonSigner::ActorKeyId(proof.verification_method)
|
||||
},
|
||||
_ => {
|
||||
return Err(VerificationError::InvalidProof("unsupported proof type"));
|
||||
},
|
||||
};
|
||||
let signer = JsonSigner::ActorKeyId(proof.verification_method);
|
||||
let message = canonicalize_object(&object)?;
|
||||
let signature_data = SignatureData {
|
||||
signer: signer,
|
||||
|
@ -110,8 +121,31 @@ mod tests {
|
|||
use serde_json::json;
|
||||
use crate::json_signatures::create::sign_object;
|
||||
use crate::utils::crypto::generate_weak_private_key;
|
||||
use crate::utils::currencies::Currency;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_json_signature_eip155() {
|
||||
let signed_object = json!({
|
||||
"type": "Test",
|
||||
"id": "https://example.org/objects/1",
|
||||
"proof": {
|
||||
"type": "JcsEip191Signature2022",
|
||||
"proofPurpose": "assertionMethod",
|
||||
"verificationMethod": "did:pkh:eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a",
|
||||
"created": "2020-11-05T19:23:24Z",
|
||||
"proofValue": "xxx",
|
||||
},
|
||||
});
|
||||
let signature_data = get_json_signature(&signed_object).unwrap();
|
||||
let expected_signer = JsonSigner::DidPkh(DidPkh::from_address(
|
||||
&Currency::Ethereum,
|
||||
"0xb9c5714089478a327f09197987f16f9e5d936e8a",
|
||||
));
|
||||
assert_eq!(signature_data.signer, expected_signer);
|
||||
assert_eq!(signature_data.signature, "xxx");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_and_verify_signature() {
|
||||
let signer_key = generate_weak_private_key().unwrap();
|
||||
|
|
Loading…
Reference in a new issue