@@ -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,80 @@ 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. It is also allowed to have one deleted and one undefined
200+ // certificate.
201+ if matches ! ( metadata. x509_certs. first( ) , Some ( X509DerCert :: X509Cert ( _) ) )
202+ || matches ! (
203+ metadata. c509_certs. first( ) ,
204+ Some ( C509Cert :: C509Certificate ( _) )
205+ )
206+ {
207+ report. other ( "Only role 0 can contain a certificate at 0 index" , context) ;
208+ }
209+ if matches ! ( metadata. x509_certs. first( ) , Some ( X509DerCert :: Deleted ) )
210+ && matches ! ( metadata. c509_certs. first( ) , Some ( C509Cert :: Deleted ) )
211+ {
212+ report. other (
213+ "It isn't allowed to have both certificate to be deleted at 0 index" ,
214+ context,
215+ ) ;
216+ }
217+ }
218+
219+ // It isn't allowed for any role to use a public key at 0 index.
220+ if !matches ! (
221+ metadata. pub_keys. first( ) ,
222+ None | Some ( SimplePublicKeyType :: Undefined )
223+ ) {
224+ report. other (
225+ "The public key cannot be used for the role 0, only a certificate" ,
226+ context,
227+ ) ;
174228 }
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) ;
229+ // It isn't allowed for the role 0 to have a certificate in the
230+ // `C509CertInMetadatumReference` form and other roles must not contain certificate at 0
231+ // index.
232+ if matches ! (
233+ metadata. c509_certs. first( ) ,
234+ Some ( C509Cert :: C509CertInMetadatumReference ( _) )
235+ ) {
236+ report. other (
237+ "C509 certificate at 0 index cannot be in metadatum reference" ,
238+ context,
239+ ) ;
178240 }
179241
180242 for ( number, data) in & metadata. role_data {
0 commit comments