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::{
get_json_signature,
verify_eip191_json_signature,
verify_minisign_json_signature,
verify_rsa_json_signature,
JsonSignatureVerificationError as JsonSignatureError,
JsonSigner,
@ -137,8 +138,7 @@ pub async fn verify_signed_activity(
verify_rsa_json_signature(&signature_data, &public_key)?;
actor_profile
},
JsonSigner::DidPkh(did_pkh) => {
let did = Did::Pkh(did_pkh.clone());
JsonSigner::Did(did) => {
let mut profiles: Vec<_> = search_profiles_by_did_only(db_client, &did)
.await?.into_iter()
// Exclude local profiles
@ -151,11 +151,22 @@ pub async fn verify_signed_activity(
);
};
if let Some(profile) = profiles.pop() {
match did {
Did::Key(did_key) => {
verify_minisign_json_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
} else {
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
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 crate::identity::{
did_key::DidKey,
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::{
canonicalize_object,
@ -55,6 +60,19 @@ impl IntegrityProof {
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)]

View file

@ -3,8 +3,15 @@ use serde_json::Value;
use crate::ethereum::identity::verify_eip191_signature;
use crate::identity::{
did::Did,
did_key::DidKey,
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::{
canonicalize_object,
@ -20,7 +27,7 @@ use super::create::{
#[derive(Debug, PartialEq)]
pub enum JsonSigner {
ActorKeyId(String),
DidPkh(DidPkh),
Did(Did),
}
pub struct SignatureData {
@ -67,9 +74,14 @@ pub fn get_json_signature(
};
let signer = match proof.proof_type.as_str() {
PROOF_TYPE_JCS_EIP191 => {
let did = proof.verification_method.parse()
let did_pkh: DidPkh = proof.verification_method.parse()
.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 => {
JsonSigner::ActorKeyId(proof.verification_method)
@ -111,6 +123,15 @@ pub fn verify_eip191_json_signature(
.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)]
mod tests {
use serde_json::json;
@ -133,10 +154,10 @@ mod tests {
},
});
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,
"0xb9c5714089478a327f09197987f16f9e5d936e8a",
));
)));
assert_eq!(signature_data.signer, expected_signer);
assert_eq!(signature_data.signature, "xxx");
}

View file

@ -33,7 +33,10 @@ use crate::identity::{
};
use crate::json_signatures::{
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::pagination::get_paginated_response;
@ -267,7 +270,11 @@ async fn send_signed_update(
let canonical_json = canonicalize_object(&activity)
.map_err(|_| HttpError::InternalError)?;
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) => {
verify_eip191_json_signature(&signer, &canonical_json, &data.signature)
.map_err(|_| ValidationError("invalid signature"))?;