@@ -22,7 +22,7 @@ use pallas::{
2222use super :: utils:: cip19:: compare_key_hash;
2323use 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> {
163163pub 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