Skip to content

Commit bd804fe

Browse files
One more update for the role data validation
1 parent 5c53373 commit bd804fe

File tree

1 file changed

+70
-12
lines changed

1 file changed

+70
-12
lines changed

rust/rbac-registration/src/cardano/cip509/validation.rs

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use pallas::{
2222
use super::utils::cip19::compare_key_hash;
2323
use crate::cardano::cip509::{
2424
rbac::Cip509RbacMetadata, types::TxInputHash, C509Cert, Cip0134UriSet, LocalRefInt, RoleData,
25-
RoleNumber, X509DerCert,
25+
RoleNumber, SimplePublicKeyType, X509DerCert,
2626
};
2727

2828
/// Context-specific primitive type with tag number 6 (`raw_tag` 134) for
@@ -163,18 +163,76 @@ fn extract_stake_addresses(uris: Option<&Cip0134UriSet>) -> Vec<VKeyHash> {
163163
pub fn validate_role_data(metadata: &Cip509RbacMetadata, report: &ProblemReport) {
164164
let context = "Role data validation";
165165

166-
let has_x_0_cert = matches!(metadata.x509_certs.first(), Some(X509DerCert::X509Cert(_)));
167-
let has_c_0_cert = matches!(
168-
metadata.c509_certs.first(),
169-
Some(C509Cert::C509Certificate(_))
170-
);
171-
// There should be only one role 0 certificate.
172-
if has_x_0_cert && has_c_0_cert {
173-
report.other("Only one certificate can be defined at index 0", context);
166+
if metadata.role_data.contains_key(&RoleNumber::ROLE_0) {
167+
// For the role 0 there must be exactly once certificate and it must not have `deleted`,
168+
// `undefined` or `C509CertInMetadatumReference` values.
169+
if matches!(metadata.x509_certs.first(), Some(X509DerCert::X509Cert(_)))
170+
&& matches!(
171+
metadata.c509_certs.first(),
172+
Some(C509Cert::C509Certificate(_))
173+
)
174+
{
175+
report.other(
176+
"Only one certificate can be defined at index 0 for the role 0",
177+
context,
178+
);
179+
}
180+
if matches!(
181+
metadata.c509_certs.first(),
182+
Some(C509Cert::C509CertInMetadatumReference(_))
183+
) {
184+
report.other(
185+
"C509 certificate at 0 index cannot be in metadatum reference",
186+
context,
187+
);
188+
}
189+
if !matches!(metadata.x509_certs.first(), Some(X509DerCert::X509Cert(_)))
190+
&& !matches!(
191+
metadata.c509_certs.first(),
192+
Some(C509Cert::C509Certificate(_))
193+
)
194+
{
195+
report.other("The role 0 certificate must be present", context);
196+
}
197+
} else {
198+
// For other roles there still must be exactly one certificate at 0 index, but it must
199+
// have the `undefined` value.
200+
if matches!(metadata.x509_certs.first(), Some(X509DerCert::X509Cert(_)))
201+
|| matches!(
202+
metadata.c509_certs.first(),
203+
Some(C509Cert::C509Certificate(_))
204+
)
205+
{
206+
report.other("Only role 0 can contain a certificate at 0 index", context);
207+
}
208+
if matches!(metadata.x509_certs.first(), Some(X509DerCert::Deleted))
209+
|| matches!(metadata.c509_certs.first(), Some(C509Cert::Deleted))
210+
{
211+
report.other("Only role 0 can delete a certificate at 0 index", context);
212+
}
213+
}
214+
215+
// It isn't allowed for any role to use a public key at 0 index.
216+
if !matches!(
217+
metadata.pub_keys.first(),
218+
None | Some(SimplePublicKeyType::Undefined)
219+
) {
220+
report.other(
221+
"The public key cannot be used for the role 0, only a certificate",
222+
context,
223+
);
174224
}
175-
// Only role 0 can contain certificates at 0 index.
176-
if !metadata.role_data.contains_key(&RoleNumber::ROLE_0) && (has_x_0_cert || has_c_0_cert) {
177-
report.other("Only role 0 can contain certificates at index 0", context);
225+
// It isn't allowed for the role 0 to have a certificate in the
226+
// `C509CertInMetadatumReference` form and other roles must not contain certificate at 0
227+
// index.
228+
if matches!(
229+
metadata.c509_certs.first(),
230+
Some(C509Cert::C509CertInMetadatumReference(_))
231+
) {
232+
report.other(
233+
"C509 certificate at 0 index cannot be in metadatum reference",
234+
context,
235+
);
178236
}
179237

180238
for (number, data) in &metadata.role_data {

0 commit comments

Comments
 (0)