@@ -148,10 +148,13 @@ impl NucValidator {
148148
149149 // Validations applied to proofs
150150 fn validate_proofs ( proofs : & [ & NucToken ] , root_keys : & HashSet < Box < [ u8 ] > > ) -> ValidationResult {
151- if let Some ( proof) = proofs. last ( ) {
152- if !root_keys. contains ( proof. issuer . public_key . as_slice ( ) ) {
153- return Err ( ValidationError :: Validation ( ValidationKind :: RootKeySignatureMissing ) ) ;
154- }
151+ let contains_root_signature = match proofs. last ( ) {
152+ Some ( proof) => root_keys. contains ( proof. issuer . public_key . as_slice ( ) ) ,
153+ // if there's no proof but also no root keys we don't need one.
154+ None => root_keys. is_empty ( ) ,
155+ } ;
156+ if !contains_root_signature {
157+ return Err ( ValidationError :: Validation ( ValidationKind :: RootKeySignatureMissing ) ) ;
155158 }
156159
157160 for proof in proofs {
@@ -459,11 +462,12 @@ mod tests {
459462
460463 struct Asserter {
461464 parameters : ValidationParameters ,
465+ root_keys : Vec < PublicKey > ,
462466 }
463467
464468 impl Asserter {
465469 fn new ( parameters : ValidationParameters ) -> Self {
466- Self { parameters }
470+ Self { parameters, root_keys : ROOT_PUBLIC_KEYS . clone ( ) }
467471 }
468472
469473 fn log_tokens ( envelope : & NucTokenEnvelope ) {
@@ -479,7 +483,7 @@ mod tests {
479483 Self :: log_tokens ( & envelope) ;
480484
481485 let expected_failure = expected_failure. into ( ) ;
482- match NucValidator :: new ( & ROOT_PUBLIC_KEYS ) . validate ( envelope, self . parameters ) {
486+ match NucValidator :: new ( & self . root_keys ) . validate ( envelope, self . parameters ) {
483487 Ok ( _) => panic ! ( "validation succeeded" ) ,
484488 Err ( e) if e. to_string ( ) == expected_failure. to_string ( ) => ( ) ,
485489 Err ( e) => panic ! ( "unexpected type of failure: {e}" ) ,
@@ -488,14 +492,14 @@ mod tests {
488492
489493 fn assert_success ( self , envelope : NucTokenEnvelope ) -> ValidatedNucToken {
490494 Self :: log_tokens ( & envelope) ;
491- NucValidator :: new ( & ROOT_PUBLIC_KEYS ) . validate ( envelope, self . parameters ) . expect ( "validation failed" )
495+ NucValidator :: new ( & self . root_keys ) . validate ( envelope, self . parameters ) . expect ( "validation failed" )
492496 }
493497 }
494498
495499 impl Default for Asserter {
496500 fn default ( ) -> Self {
497501 let parameters = ValidationParameters :: default ( ) ;
498- Self { parameters }
502+ Self :: new ( parameters)
499503 }
500504 }
501505
@@ -662,14 +666,17 @@ mod tests {
662666 let token = Chainer :: default ( ) . chain ( [ root] ) . encode ( ) ;
663667 let ( base, signature) = token. rsplit_once ( "." ) . unwrap ( ) ;
664668
665- // Change every byte in the signature and make sure validation fails every time.
669+ // Change a byte in the signature
666670 let signature = from_base64 ( signature) . unwrap ( ) ;
667671 let mut signature = signature. clone ( ) ;
668672 signature[ 0 ] ^= 1 ;
669673 let signature = to_base64 ( & signature) ;
670674 let token = format ! ( "{base}.{signature}" ) ;
671675 let envelope = NucTokenEnvelope :: decode ( & token) . expect ( "decode failed" ) ;
672- Asserter :: default ( ) . assert_failure ( envelope, ValidationKind :: InvalidSignatures ) ;
676+ let mut asserter = Asserter :: default ( ) ;
677+ // Don't require a root key signature
678+ asserter. root_keys = Vec :: new ( ) ;
679+ asserter. assert_failure ( envelope, ValidationKind :: InvalidSignatures ) ;
673680 }
674681
675682 #[ test]
@@ -968,4 +975,20 @@ mod tests {
968975 } ;
969976 Asserter :: new ( parameters) . assert_success ( envelope) ;
970977 }
978+
979+ #[ test]
980+ fn valid_no_root_keys_needed ( ) {
981+ let subject_key = SecretKey :: random ( & mut rand:: thread_rng ( ) ) ;
982+ let subject = Did :: from_secret_key ( & subject_key) ;
983+ let token = NucTokenBuilder :: delegation ( [ ] )
984+ . subject ( subject. clone ( ) )
985+ . audience ( subject)
986+ . command ( [ "nil" ] )
987+ . issued_by ( subject_key) ;
988+
989+ let envelope = Chainer :: default ( ) . chain ( [ token] ) ;
990+ let mut asserter = Asserter :: default ( ) ;
991+ asserter. root_keys = Vec :: new ( ) ;
992+ asserter. assert_success ( envelope) ;
993+ }
971994}
0 commit comments