@@ -536,7 +536,6 @@ verify_hashes_with_sei(signed_video_t *self, bu_list_item_t *sei)
536
536
(!sei -> bu -> is_signed || (sei -> bu -> is_signed && sei -> verified_signature == 1 ));
537
537
bool gop_hash_ok = verify_gop_hash (self );
538
538
bool linked_hash_ok = verify_linked_hash (self , true);
539
- self -> validation_flags .sei_in_sync |= linked_hash_ok ;
540
539
// For complete and successful validation both the GOP hash and the linked hash have
541
540
// to be correct (given that the signature could be verified successfully of course).
542
541
// If the gop hash could not be verified correct, there is a second chance by
@@ -694,6 +693,7 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
694
693
gop_info_t * gop_info = self -> gop_info ;
695
694
validation_flags_t * validation_flags = & (self -> validation_flags );
696
695
signed_video_latest_validation_t * latest = self -> latest_validation ;
696
+ size_t hash_size = self -> verify_data -> hash_size ;
697
697
698
698
SignedVideoAuthenticityResult valid = SV_AUTH_RESULT_NOT_OK ;
699
699
// Initialize to "Unknown"
@@ -751,6 +751,29 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
751
751
valid = SV_AUTH_RESULT_OK_WITH_MISSING_INFO ;
752
752
DEBUG_LOG ("Successful validation, but detected missing Bitstream Units" );
753
753
}
754
+
755
+ // Determine if the SEIs are in sync.
756
+ if (!validation_flags -> sei_in_sync ) {
757
+ // If at least one BU could be validated successfully it is by definition also in
758
+ // sync.
759
+ validation_flags -> sei_in_sync |= has_valid_bu ;
760
+ // If the computed and received link hashes are identical the SEI is in sync. There is
761
+ // one exception though, and that is when the received SEI is the first of a stream.
762
+ // In that case the computed linked hash AND the received one have all zeros.
763
+ const uint8_t * received_linked_hash = self -> received_linked_hash ;
764
+ bool is_start_of_stream = hash_is_empty (received_linked_hash , hash_size );
765
+ if (!is_start_of_stream ) {
766
+ // Comparing linked hashes is enough.
767
+ validation_flags -> sei_in_sync |= verify_linked_hash (self , false);
768
+ }
769
+ // One special case is if the signature is not verified correctly, but the (partial)
770
+ // GOP is correctly verified (GOP hashes match). If the SEI is not in sync it will
771
+ // never get in sync and validation will never reach a verdict.
772
+ if (validation_flags -> num_lost_seis == 0 ) {
773
+ validation_flags -> sei_in_sync |= verify_success ;
774
+ }
775
+ }
776
+
754
777
// If we lose an entire GOP (part from the associated SEI) it will be seen as valid. Here we fix
755
778
// it afterwards.
756
779
// TODO: Move this inside the verify_hashes_ functions. We should not need to perform any special
@@ -793,10 +816,6 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
793
816
}
794
817
if (latest -> public_key_has_changed ) valid = SV_AUTH_RESULT_NOT_OK ;
795
818
796
- if (valid == SV_AUTH_RESULT_OK ) {
797
- validation_flags -> sei_in_sync = true;
798
- }
799
-
800
819
// Update |latest_validation| with the validation result.
801
820
if (latest -> authenticity <= SV_AUTH_RESULT_SIGNATURE_PRESENT ) {
802
821
// Still either pending validation or video has no signature. Update with the current
@@ -815,12 +834,19 @@ validate_authenticity(signed_video_t *self, bu_list_item_t *sei)
815
834
latest -> number_of_expected_picture_nalus += num_expected ;
816
835
}
817
836
// Update |current_partial_gop| and |num_lost_seis| w.r.t. if SEI is in sync.
818
- if (validation_flags -> sei_in_sync ) {
819
- gop_info -> current_partial_gop = gop_info -> next_partial_gop ;
820
- validation_flags -> num_lost_seis = 0 ;
821
- } else {
822
- validation_flags -> num_lost_seis =
823
- gop_info -> next_partial_gop - gop_info -> current_partial_gop - 1 ;
837
+ // Only update if SEIs have not been reordered.
838
+ if (validation_flags -> num_lost_seis >= 0 ) {
839
+ if (validation_flags -> sei_in_sync && (validation_flags -> num_lost_seis < 2 )) {
840
+ gop_info -> current_partial_gop = gop_info -> next_partial_gop ;
841
+ validation_flags -> num_lost_seis = 0 ;
842
+ } else {
843
+ // Only update |num_lost_seis| if decreased. For example, if a validation was
844
+ // performed with an "old" re-ordered SEI |next_partial_gop| is incorrect.
845
+ int new_num_lost_seis = gop_info -> next_partial_gop - gop_info -> current_partial_gop - 1 ;
846
+ if (new_num_lost_seis < validation_flags -> num_lost_seis ) {
847
+ validation_flags -> num_lost_seis = new_num_lost_seis ;
848
+ }
849
+ }
824
850
}
825
851
}
826
852
0 commit comments