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::{
|
use crate::json_signatures::verify::{
|
||||||
get_json_signature,
|
get_json_signature,
|
||||||
verify_jcs_rsa_signature,
|
verify_jcs_rsa_signature,
|
||||||
|
verify_jcs_eip191_signature,
|
||||||
JsonSignatureVerificationError as JsonSignatureError,
|
JsonSignatureVerificationError as JsonSignatureError,
|
||||||
JsonSigner,
|
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::models::profiles::types::DbActorProfile;
|
||||||
use crate::utils::crypto::deserialize_public_key;
|
use crate::utils::crypto::deserialize_public_key;
|
||||||
use super::fetcher::helpers::get_or_import_profile_by_actor_id;
|
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_profile = match signature_data.signer {
|
||||||
let actor_id = key_id_to_actor_id(key_id)?;
|
JsonSigner::ActorKeyId(ref key_id) => {
|
||||||
let actor_profile = match get_or_import_profile_by_actor_id(
|
let actor_id = key_id_to_actor_id(key_id)?;
|
||||||
db_client,
|
let actor_profile = match get_or_import_profile_by_actor_id(
|
||||||
&config.instance(),
|
db_client,
|
||||||
&config.media_dir(),
|
&config.instance(),
|
||||||
&actor_id,
|
&config.media_dir(),
|
||||||
).await {
|
&actor_id,
|
||||||
Ok(profile) => profile,
|
).await {
|
||||||
Err(HandlerError::DatabaseError(error)) => return Err(error.into()),
|
Ok(profile) => profile,
|
||||||
Err(other_error) => {
|
Err(HandlerError::DatabaseError(error)) => {
|
||||||
return Err(AuthenticationError::ActorError(other_error.to_string()));
|
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)
|
Ok(actor_profile)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::utils::crypto::verify_signature;
|
||||||
use super::canonicalization::{canonicalize_object, CanonicalizationError};
|
use super::canonicalization::{canonicalize_object, CanonicalizationError};
|
||||||
use super::create::{
|
use super::create::{
|
||||||
IntegrityProof,
|
IntegrityProof,
|
||||||
|
PROOF_TYPE_JCS_EIP191,
|
||||||
PROOF_TYPE_JCS_RSA,
|
PROOF_TYPE_JCS_RSA,
|
||||||
PROOF_KEY,
|
PROOF_KEY,
|
||||||
PROOF_PURPOSE,
|
PROOF_PURPOSE,
|
||||||
|
@ -18,6 +19,7 @@ use super::create::{
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum JsonSigner {
|
pub enum JsonSigner {
|
||||||
ActorKeyId(String),
|
ActorKeyId(String),
|
||||||
|
DidPkh(DidPkh),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SignatureData {
|
pub struct SignatureData {
|
||||||
|
@ -62,10 +64,19 @@ pub fn get_json_signature(
|
||||||
if proof.proof_purpose != PROOF_PURPOSE {
|
if proof.proof_purpose != PROOF_PURPOSE {
|
||||||
return Err(VerificationError::InvalidProof("invalid proof purpose"));
|
return Err(VerificationError::InvalidProof("invalid proof purpose"));
|
||||||
};
|
};
|
||||||
if proof.proof_type != PROOF_TYPE_JCS_RSA {
|
let signer = match proof.proof_type.as_str() {
|
||||||
return Err(VerificationError::InvalidProof("unsupported proof type"));
|
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 message = canonicalize_object(&object)?;
|
||||||
let signature_data = SignatureData {
|
let signature_data = SignatureData {
|
||||||
signer: signer,
|
signer: signer,
|
||||||
|
@ -110,8 +121,31 @@ mod tests {
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use crate::json_signatures::create::sign_object;
|
use crate::json_signatures::create::sign_object;
|
||||||
use crate::utils::crypto::generate_weak_private_key;
|
use crate::utils::crypto::generate_weak_private_key;
|
||||||
|
use crate::utils::currencies::Currency;
|
||||||
use super::*;
|
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]
|
#[test]
|
||||||
fn test_create_and_verify_signature() {
|
fn test_create_and_verify_signature() {
|
||||||
let signer_key = generate_weak_private_key().unwrap();
|
let signer_key = generate_weak_private_key().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue