Support integrity proofs created with minisign

This commit is contained in:
silverpill 2022-11-10 18:47:22 +00:00
parent 64546ecabe
commit 8ad88f84b2
5 changed files with 76 additions and 16 deletions

View file

@ -13,6 +13,7 @@ use crate::identity::did::Did;
use crate::json_signatures::verify::{ use crate::json_signatures::verify::{
get_json_signature, get_json_signature,
verify_eip191_json_signature, verify_eip191_json_signature,
verify_minisign_json_signature,
verify_rsa_json_signature, verify_rsa_json_signature,
JsonSignatureVerificationError as JsonSignatureError, JsonSignatureVerificationError as JsonSignatureError,
JsonSigner, JsonSigner,
@ -137,8 +138,7 @@ pub async fn verify_signed_activity(
verify_rsa_json_signature(&signature_data, &public_key)?; verify_rsa_json_signature(&signature_data, &public_key)?;
actor_profile actor_profile
}, },
JsonSigner::DidPkh(did_pkh) => { JsonSigner::Did(did) => {
let did = Did::Pkh(did_pkh.clone());
let mut profiles: Vec<_> = search_profiles_by_did_only(db_client, &did) let mut profiles: Vec<_> = search_profiles_by_did_only(db_client, &did)
.await?.into_iter() .await?.into_iter()
// Exclude local profiles // Exclude local profiles
@ -151,11 +151,22 @@ pub async fn verify_signed_activity(
); );
}; };
if let Some(profile) = profiles.pop() { if let Some(profile) = profiles.pop() {
verify_eip191_json_signature( match did {
&did_pkh, Did::Key(did_key) => {
&signature_data.message, verify_minisign_json_signature(
&signature_data.signature, &did_key,
)?; &signature_data.message,
&signature_data.signature,
)?;
},
Did::Pkh(did_pkh) => {
verify_eip191_json_signature(
&did_pkh,
&signature_data.message,
&signature_data.signature,
)?;
},
};
profile profile
} else { } else {
return Err(AuthenticationError::ActorError("unknown signer".to_string())); return Err(AuthenticationError::ActorError("unknown signer".to_string()));

View file

@ -14,3 +14,6 @@ pub const PROOF_TYPE_JCS_RSA: &str = "JcsRsaSignature2022";
// Similar to EthereumPersonalSignature2021 but with JCS // Similar to EthereumPersonalSignature2021 but with JCS
pub const PROOF_TYPE_JCS_EIP191: &str ="JcsEip191Signature2022"; pub const PROOF_TYPE_JCS_EIP191: &str ="JcsEip191Signature2022";
// Version 2022A
pub const PROOF_TYPE_JCS_MINISIGN: &str = "MitraJcsMinisignSignature2022A";

View file

@ -4,8 +4,13 @@ use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use crate::identity::{ use crate::identity::{
did_key::DidKey,
did_pkh::DidPkh, did_pkh::DidPkh,
signatures::{PROOF_TYPE_JCS_EIP191, PROOF_TYPE_JCS_RSA}, signatures::{
PROOF_TYPE_JCS_EIP191,
PROOF_TYPE_JCS_MINISIGN,
PROOF_TYPE_JCS_RSA,
},
}; };
use crate::utils::canonicalization::{ use crate::utils::canonicalization::{
canonicalize_object, canonicalize_object,
@ -55,6 +60,19 @@ impl IntegrityProof {
proof_value: signature.to_string(), proof_value: signature.to_string(),
} }
} }
pub fn jcs_minisign(
signer: &DidKey,
signature: &str,
) -> Self {
Self {
proof_type: PROOF_TYPE_JCS_MINISIGN.to_string(),
proof_purpose: PROOF_PURPOSE.to_string(),
verification_method: signer.to_string(),
created: Utc::now(),
proof_value: signature.to_string(),
}
}
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]

View file

@ -3,8 +3,15 @@ use serde_json::Value;
use crate::ethereum::identity::verify_eip191_signature; use crate::ethereum::identity::verify_eip191_signature;
use crate::identity::{ use crate::identity::{
did::Did,
did_key::DidKey,
did_pkh::DidPkh, did_pkh::DidPkh,
signatures::{PROOF_TYPE_JCS_EIP191, PROOF_TYPE_JCS_RSA}, minisign::verify_minisign_signature,
signatures::{
PROOF_TYPE_JCS_EIP191,
PROOF_TYPE_JCS_MINISIGN,
PROOF_TYPE_JCS_RSA,
},
}; };
use crate::utils::canonicalization::{ use crate::utils::canonicalization::{
canonicalize_object, canonicalize_object,
@ -20,7 +27,7 @@ use super::create::{
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum JsonSigner { pub enum JsonSigner {
ActorKeyId(String), ActorKeyId(String),
DidPkh(DidPkh), Did(Did),
} }
pub struct SignatureData { pub struct SignatureData {
@ -67,9 +74,14 @@ pub fn get_json_signature(
}; };
let signer = match proof.proof_type.as_str() { let signer = match proof.proof_type.as_str() {
PROOF_TYPE_JCS_EIP191 => { PROOF_TYPE_JCS_EIP191 => {
let did = proof.verification_method.parse() let did_pkh: DidPkh = proof.verification_method.parse()
.map_err(|_| VerificationError::InvalidProof("invalid DID"))?; .map_err(|_| VerificationError::InvalidProof("invalid DID"))?;
JsonSigner::DidPkh(did) JsonSigner::Did(Did::Pkh(did_pkh))
},
PROOF_TYPE_JCS_MINISIGN => {
let did_key: DidKey = proof.verification_method.parse()
.map_err(|_| VerificationError::InvalidProof("invalid DID"))?;
JsonSigner::Did(Did::Key(did_key))
}, },
PROOF_TYPE_JCS_RSA => { PROOF_TYPE_JCS_RSA => {
JsonSigner::ActorKeyId(proof.verification_method) JsonSigner::ActorKeyId(proof.verification_method)
@ -111,6 +123,15 @@ pub fn verify_eip191_json_signature(
.map_err(|_| VerificationError::InvalidSignature) .map_err(|_| VerificationError::InvalidSignature)
} }
pub fn verify_minisign_json_signature(
signer: &DidKey,
message: &str,
signature: &str,
) -> Result<(), VerificationError> {
verify_minisign_signature(signer, message, signature)
.map_err(|_| VerificationError::InvalidSignature)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json::json; use serde_json::json;
@ -133,10 +154,10 @@ mod tests {
}, },
}); });
let signature_data = get_json_signature(&signed_object).unwrap(); let signature_data = get_json_signature(&signed_object).unwrap();
let expected_signer = JsonSigner::DidPkh(DidPkh::from_address( let expected_signer = JsonSigner::Did(Did::Pkh(DidPkh::from_address(
&Currency::Ethereum, &Currency::Ethereum,
"0xb9c5714089478a327f09197987f16f9e5d936e8a", "0xb9c5714089478a327f09197987f16f9e5d936e8a",
)); )));
assert_eq!(signature_data.signer, expected_signer); assert_eq!(signature_data.signer, expected_signer);
assert_eq!(signature_data.signature, "xxx"); assert_eq!(signature_data.signature, "xxx");
} }

View file

@ -33,7 +33,10 @@ use crate::identity::{
}; };
use crate::json_signatures::{ use crate::json_signatures::{
create::{add_integrity_proof, IntegrityProof}, create::{add_integrity_proof, IntegrityProof},
verify::verify_eip191_json_signature, verify::{
verify_eip191_json_signature,
verify_minisign_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;
@ -267,7 +270,11 @@ async fn send_signed_update(
let canonical_json = canonicalize_object(&activity) let canonical_json = canonicalize_object(&activity)
.map_err(|_| HttpError::InternalError)?; .map_err(|_| HttpError::InternalError)?;
let proof = match signer { let proof = match signer {
Did::Key(_) => return Err(ValidationError("unsupported DID type").into()), Did::Key(signer) => {
verify_minisign_json_signature(&signer, &canonical_json, &data.signature)
.map_err(|_| ValidationError("invalid signature"))?;
IntegrityProof::jcs_minisign(&signer, &data.signature)
},
Did::Pkh(signer) => { Did::Pkh(signer) => {
verify_eip191_json_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"))?;