@@ -53,6 +53,13 @@ pub enum CertificateVerifierError {
53
53
#[ error( "certificate chain AVK unmatch error" ) ]
54
54
CertificateChainAVKUnmatch ,
55
55
56
+ /// Error raised when validating the certificate chain if the current [Certificate]
57
+ /// `protocol_parameters` don't match the signed `next_protocol_parameters` of the previous certificate
58
+ /// (if the certificates are on different epoch) or the `protocol_parameters` of the previous certificate
59
+ /// (if the certificates are on the same epoch).
60
+ #[ error( "certificate chain protocol parameters unmatch error" ) ]
61
+ CertificateChainProtocolParametersUnmatch ,
62
+
56
63
/// Error raised when validating the certificate chain if the current [Certificate]
57
64
/// `epoch` doesn't match the signed `current_epoch` of the current certificate
58
65
#[ error( "certificate epoch unmatch error" ) ]
@@ -286,6 +293,40 @@ impl MithrilCertificateVerifier {
286
293
287
294
Ok ( ( ) )
288
295
}
296
+
297
+ fn verify_protocol_parameters_chaining (
298
+ & self ,
299
+ certificate : & Certificate ,
300
+ previous_certificate : & Certificate ,
301
+ ) -> StdResult < ( ) > {
302
+ let previous_certificate_has_same_epoch = previous_certificate. epoch == certificate. epoch ;
303
+ let certificate_has_valid_protocol_parameters = if previous_certificate_has_same_epoch {
304
+ previous_certificate. metadata . protocol_parameters
305
+ == certificate. metadata . protocol_parameters
306
+ } else {
307
+ match & previous_certificate
308
+ . protocol_message
309
+ . get_message_part ( & ProtocolMessagePartKey :: NextProtocolParameters )
310
+ {
311
+ Some ( previous_certificate_next_protocol_parameters) => {
312
+ * * previous_certificate_next_protocol_parameters
313
+ == certificate. metadata . protocol_parameters . compute_hash ( )
314
+ }
315
+ None => false ,
316
+ }
317
+ } ;
318
+ if !certificate_has_valid_protocol_parameters {
319
+ debug ! (
320
+ self . logger,
321
+ "Previous certificate {:#?}" , previous_certificate
322
+ ) ;
323
+ return Err ( anyhow ! (
324
+ CertificateVerifierError :: CertificateChainProtocolParametersUnmatch
325
+ ) ) ;
326
+ }
327
+
328
+ Ok ( ( ) )
329
+ }
289
330
}
290
331
291
332
#[ cfg_attr( target_family = "wasm" , async_trait( ?Send ) ) ]
@@ -338,6 +379,7 @@ impl CertificateVerifier for MithrilCertificateVerifier {
338
379
previous_certificate,
339
380
) ?;
340
381
self . verify_aggregate_verification_key_chaining ( certificate, previous_certificate) ?;
382
+ self . verify_protocol_parameters_chaining ( certificate, previous_certificate) ?;
341
383
342
384
Ok ( ( ) )
343
385
}
@@ -846,22 +888,32 @@ mod tests {
846
888
}
847
889
848
890
#[ tokio:: test]
849
- async fn verify_certificate_ko_certificate_hash_not_matching ( ) {
891
+ async fn verify_standard_certificate_fails_if_certificate_chain_protocol_parameters_unmatch ( ) {
850
892
let ( total_certificates, certificates_per_epoch) = ( 5 , 1 ) ;
851
893
let ( fake_certificates, _) =
852
894
setup_certificate_chain ( total_certificates, certificates_per_epoch) ;
895
+ let verifier = MockDependencyInjector :: new ( ) . build_certificate_verifier ( ) ;
853
896
let mut certificate = fake_certificates[ 0 ] . clone ( ) ;
854
- certificate. hash = "another-hash" . to_string ( ) ;
855
- let previous_certificate = fake_certificates[ 1 ] . clone ( ) ;
856
- let mock_container = MockDependencyInjector :: new ( ) ;
857
- let verifier = mock_container. build_certificate_verifier ( ) ;
897
+ let mut previous_certificate = fake_certificates[ 1 ] . clone ( ) ;
898
+ previous_certificate. protocol_message . set_message_part (
899
+ ProtocolMessagePartKey :: NextProtocolParameters ,
900
+ "protocol-params-hash-123" . to_string ( ) ,
901
+ ) ;
902
+ previous_certificate. hash = previous_certificate. compute_hash ( ) ;
903
+ certificate
904
+ . previous_hash
905
+ . clone_from ( & previous_certificate. hash ) ;
906
+ certificate. hash = certificate. compute_hash ( ) ;
858
907
859
908
let error = verifier
860
909
. verify_standard_certificate ( & certificate, & previous_certificate)
861
910
. await
862
911
. expect_err ( "verify_standard_certificate should fail" ) ;
863
912
864
- assert_error_matches ! ( CertificateVerifierError :: CertificateHashUnmatch , error)
913
+ assert_error_matches ! (
914
+ CertificateVerifierError :: CertificateChainProtocolParametersUnmatch ,
915
+ error
916
+ )
865
917
}
866
918
867
919
#[ tokio:: test]
0 commit comments