Support integrity proofs created with minisign
This commit is contained in:
parent
64546ecabe
commit
8ad88f84b2
5 changed files with 76 additions and 16 deletions
|
@ -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() {
|
||||||
|
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(
|
verify_eip191_json_signature(
|
||||||
&did_pkh,
|
&did_pkh,
|
||||||
&signature_data.message,
|
&signature_data.message,
|
||||||
&signature_data.signature,
|
&signature_data.signature,
|
||||||
)?;
|
)?;
|
||||||
|
},
|
||||||
|
};
|
||||||
profile
|
profile
|
||||||
} else {
|
} else {
|
||||||
return Err(AuthenticationError::ActorError("unknown signer".to_string()));
|
return Err(AuthenticationError::ActorError("unknown signer".to_string()));
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"))?;
|
||||||
|
|
Loading…
Reference in a new issue