Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rust/signed_doc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catalyst-signed-doc"
version = "0.0.9"
version = "0.0.10"
edition.workspace = true
authors.workspace = true
homepage.workspace = true
Expand All @@ -11,7 +11,7 @@ license.workspace = true
workspace = true

[dependencies]
catalyst-types = { version = "0.0.9", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.9" }
catalyst-types = { version = "0.0.10", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.10" }
cbork-utils = { version = "0.0.2", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cbork-utils-v0.0.2" }

catalyst-signed-doc-macro = { version = "0.0.1", path = "../catalyst-signed-doc-macro" }
Expand Down
71 changes: 38 additions & 33 deletions rust/signed_doc/src/validator/rules/signature_kid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,28 @@

use std::collections::HashSet;

use catalyst_signed_doc_spec::signers::roles::{AdminRole, Roles, UserRole};
use catalyst_signed_doc_spec::signers::roles::{Roles, UserRole};
use catalyst_types::catalyst_id::role_index::RoleId;

use crate::CatalystSignedDocument;

/// COSE signature `kid` (Catalyst Id) role validation
#[derive(Debug)]
pub(crate) struct SignatureKidRule {
/// expected `RoleId` values for the `kid` field
/// expected `RoleId` values for the `kid` field.
/// if empty, document must be signed by admin kid
allowed_roles: HashSet<RoleId>,
}

impl SignatureKidRule {
/// Generating `SignatureKidRule` from specs
pub(crate) fn new(spec: &Roles) -> anyhow::Result<Self> {
anyhow::ensure!(
spec.user.is_empty() != spec.admin.is_empty(),
"If 'admin' is not empty 'user' roles cannot been specified'.
And vice versa, if 'user' is not empty 'admin' roles cannot been specified'"
);

let allowed_roles: HashSet<_> = spec
.user
.iter()
Expand All @@ -27,26 +34,8 @@ impl SignatureKidRule {
UserRole::Representative => RoleId::DelegatedRepresentative,
}
})
.chain(spec.admin.iter().map(|v| {
match v {
AdminRole::RootCA => RoleId::RootCA,
AdminRole::BrandCA => RoleId::BrandCA,
AdminRole::CampaignCA => RoleId::CampaignCA,
AdminRole::CategoryCA => RoleId::CategoryCA,
AdminRole::RootAdmin => RoleId::RootAdmin,
AdminRole::BrandAdmin => RoleId::BrandAdmin,
AdminRole::CampaignAdmin => RoleId::CampaignAdmin,
AdminRole::CategoryAdmin => RoleId::CategoryAdmin,
AdminRole::Moderator => RoleId::Moderator,
}
}))
.collect();

anyhow::ensure!(
!allowed_roles.is_empty(),
"A list of allowed roles cannot be empty"
);

Ok(Self { allowed_roles })
}

Expand All @@ -57,20 +46,36 @@ impl SignatureKidRule {
doc: &CatalystSignedDocument,
) -> anyhow::Result<bool> {
let contains_exp_role = doc.authors().iter().enumerate().all(|(i, kid)| {
let (role_index, _) = kid.role_and_rotation();
let res = self.allowed_roles.contains(&role_index);
if !res {
doc.report().invalid_value(
"kid",
role_index.to_string().as_str(),
format!("{:?}", self.allowed_roles).as_str(),
format!(
"Invalid Catalyst Signed Document signature at position [{i}] `kid` Catalyst Role value"
)
.as_str(),
);
if self.allowed_roles.is_empty() {
let res = kid.is_admin();
if !res {
doc.report().invalid_value(
"kid",
&kid.to_string(),
"Catalyst id must be in admin URI type.",
format!(
"Invalid Catalyst Signed Document signature at position [{i}] `kid` Catalyst Role value"
)
.as_str(),
);
}
res
} else {
let (role_index, _) = kid.role_and_rotation();
let res = self.allowed_roles.contains(&role_index);
if !res {
doc.report().invalid_value(
"kid",
role_index.to_string().as_str(),
format!("{:?}", self.allowed_roles).as_str(),
format!(
"Invalid Catalyst Signed Document signature at position [{i}] `kid` Catalyst Role value"
)
.as_str(),
);
}
res
}
res
});
if !contains_exp_role {
return Ok(false);
Expand Down
16 changes: 8 additions & 8 deletions rust/signed_doc/tests/brand_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ mod common;
|provider| {
let template = brand_parameters_form_template_doc(provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::Role0)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(Some(RoleId::Role0));
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand All @@ -51,8 +51,8 @@ mod common;
|provider| {
let template = brand_parameters_form_template_doc(provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand All @@ -77,8 +77,8 @@ mod common;
|provider| {
let template = brand_parameters_form_template_doc(provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand All @@ -102,8 +102,8 @@ mod common;
#[test_case(
|provider| {
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down
12 changes: 6 additions & 6 deletions rust/signed_doc/tests/brand_parameters_form_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ mod common;
#[test_case(
|provider| {
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::Role0)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(Some(RoleId::Role0));
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::SchemaJson,
Expand All @@ -42,8 +42,8 @@ mod common;
#[test_case(
|provider| {
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::SchemaJson,
Expand All @@ -63,8 +63,8 @@ mod common;
#[test_case(
|provider| {
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::SchemaJson,
Expand Down
20 changes: 10 additions & 10 deletions rust/signed_doc/tests/campaign_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ mod common;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = campaign_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::Role0)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(Some(RoleId::Role0));
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down Expand Up @@ -62,8 +62,8 @@ mod common;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = campaign_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down Expand Up @@ -94,8 +94,8 @@ mod common;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = campaign_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down Expand Up @@ -124,8 +124,8 @@ mod common;
let template = brand_parameters_form_template_doc(provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand All @@ -152,8 +152,8 @@ mod common;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = campaign_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down
16 changes: 8 additions & 8 deletions rust/signed_doc/tests/campaign_parameters_form_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ mod common;
let template = brand_parameters_form_template_doc(provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::Role0)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(Some(RoleId::Role0));
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::SchemaJson,
Expand All @@ -55,8 +55,8 @@ mod common;
let template = brand_parameters_form_template_doc(provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::SchemaJson,
Expand All @@ -82,8 +82,8 @@ mod common;
let template = brand_parameters_form_template_doc(provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let parameters = brand_parameters_doc(&template, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::SchemaJson,
Expand All @@ -106,8 +106,8 @@ mod common;
#[test_case(
|provider| {
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::SchemaJson,
Expand Down
20 changes: 10 additions & 10 deletions rust/signed_doc/tests/category_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ mod common;
let parameters = campaign_parameters_doc(&template, &parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = category_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::Role0)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(Some(RoleId::Role0));
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down Expand Up @@ -69,8 +69,8 @@ mod common;
let parameters = campaign_parameters_doc(&template, &parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = category_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down Expand Up @@ -103,8 +103,8 @@ mod common;
let parameters = campaign_parameters_doc(&template, &parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = category_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down Expand Up @@ -135,8 +135,8 @@ mod common;
let template = campaign_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let parameters = campaign_parameters_doc(&template, &parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down Expand Up @@ -165,8 +165,8 @@ mod common;
let parameters = campaign_parameters_doc(&template, &parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let template = category_parameters_form_template_doc(&parameters, provider).inspect(|v| provider.add_document(None, v).unwrap())?;
let id = UuidV7::new();
let (sk, kid) = create_dummy_key_pair(RoleId::BrandAdmin)
.inspect(|(sk, kid)| provider.add_sk(kid.clone(), sk.clone()))?;
let (sk, kid) = create_dummy_key_pair(None);
provider.add_sk(kid.clone(), sk.clone());
Builder::new()
.with_json_metadata(serde_json::json!({
"content-type": ContentType::Json,
Expand Down
Loading