Skip to content

Commit 3b8b2a9

Browse files
authored
Moves validate_stream() to test_helper.c (#506)
This enables running validation in several files. Validation of FH-TG has been added. Co-authored-by: bjornvolcker <[email protected]>
1 parent e1dc707 commit 3b8b2a9

File tree

4 files changed

+206
-177
lines changed

4 files changed

+206
-177
lines changed

tests/check/check_codec_av1.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,21 @@ START_TEST(signed_stream_with_fh)
6060
setting.with_fh = true;
6161
test_stream_t *list = create_signed_stream("ItPtPtItPtPtItPtPtItPtPtItPtPt", setting);
6262
test_stream_check_types(list, "ItPtPtItSPtPtItSPtPtItSPtPtItSPtPt");
63+
64+
// ItPtPtItSPtPtItSPtPtItSPtPtItSPtPt
65+
//
66+
// ItPtPtItS ......PP. (valid, 2 pending)
67+
// ItSPtPtItS .......PP. (valid, 2 pending)
68+
// ItSPtPtItS .......PP. (valid, 2 pending)
69+
// ItSPtPtItS .......PP. (valid, 2 pending)
70+
// 8 pending
71+
// ItSPtPt PP.PPPP (valid, 7 pending)
72+
signed_video_accumulated_validation_t final_validation = {
73+
SV_AUTH_RESULT_OK, false, 34, 27, 7, SV_PUBKEY_VALIDATION_NOT_FEASIBLE, true, 0, 0};
74+
const struct validation_stats expected = {
75+
.valid_gops = 4, .pending_bu = 8, .final_validation = &final_validation};
76+
validate_stream(NULL, list, expected, true);
77+
6378
test_stream_free(list);
6479
}
6580
END_TEST

tests/check/check_signed_video_auth.c

Lines changed: 1 addition & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include "sv_internal.h" // set_hash_list_size()
3131
#include "sv_openssl_internal.h" // openssl_read_pubkey_from_private_key()
3232
#include "sv_tlv.h" // sv_write_byte_many()
33-
#include "test_helpers.h" // sv_setting, create_signed_stream()
33+
#include "test_helpers.h" // sv_setting, create_signed_stream(), validation_stats, validate_stream()
3434
#include "test_stream.h" // test_stream_create()
3535

3636
#define TMP_FIX_TO_ALLOW_TWO_INVALID_SEIS_AT_STARTUP true
@@ -61,182 +61,6 @@ teardown()
6161
* TODO: Currently, validation is triggered already on the second I-frame, which triggers an
6262
* unsigned GOP.
6363
*/
64-
65-
/* Struct to accumulate validation results used to compare against expected values. */
66-
struct validation_stats {
67-
int valid_gops;
68-
int valid_gops_with_missing_info;
69-
int invalid_gops;
70-
int unsigned_gops;
71-
int missed_bu;
72-
int pending_bu;
73-
int has_signature;
74-
bool public_key_has_changed;
75-
bool has_no_timestamp;
76-
signed_video_accumulated_validation_t *final_validation;
77-
};
78-
79-
/* General comments to the validation tests.
80-
* All tests loop through the settings in settings[NUM_SETTINGS]; See signed_video_helpers.h. The
81-
* index in the loop is _i and something the check test framework provides.
82-
*/
83-
84-
/* validate_stream(...)
85-
*
86-
* Helper function to validate the authentication result.
87-
* It takes a test stream |list| as input together with |expected| values of
88-
* valid gops
89-
* invalid gops
90-
* unsigned gops, that is gops without signature
91-
* missed number of gops
92-
* etc
93-
*
94-
* Note that the items in the |list| are consumed, that is, deleted after usage.
95-
*
96-
* If a NULL pointer |list| is passed in no action is taken.
97-
* If a NULL pointer |sv| is passed in a new session is created. This is
98-
* convenient if there are no other actions to take on |sv| outside this scope,
99-
* like reset.
100-
*/
101-
static void
102-
validate_stream(signed_video_t *sv,
103-
test_stream_t *list,
104-
struct validation_stats expected,
105-
bool check_version)
106-
{
107-
if (!list) return;
108-
109-
bool internal_sv = false;
110-
if (!sv) {
111-
sv = signed_video_create(list->codec);
112-
internal_sv = true;
113-
}
114-
115-
signed_video_authenticity_t *auth_report = NULL;
116-
signed_video_latest_validation_t *latest = NULL;
117-
118-
int valid_gops = 0;
119-
int valid_gops_with_missing_info = 0;
120-
int invalid_gops = 0;
121-
int unsigned_gops = 0;
122-
int missed_bu = 0;
123-
int pending_bu = 0;
124-
int has_signature = 0;
125-
bool public_key_has_changed = false;
126-
bool has_timestamp = false;
127-
// Loop through all items in the stream
128-
test_stream_item_t *item = list->first_item;
129-
while (item) {
130-
SignedVideoReturnCode rc =
131-
signed_video_add_nalu_and_authenticate(sv, item->data, item->data_size, &auth_report);
132-
ck_assert_int_eq(rc, SV_OK);
133-
134-
if (auth_report) {
135-
latest = &(auth_report->latest_validation);
136-
ck_assert(latest);
137-
if (latest->number_of_expected_picture_nalus >= 0) {
138-
missed_bu +=
139-
latest->number_of_expected_picture_nalus - latest->number_of_received_picture_nalus;
140-
}
141-
pending_bu += latest->number_of_pending_picture_nalus;
142-
switch (latest->authenticity) {
143-
case SV_AUTH_RESULT_OK_WITH_MISSING_INFO:
144-
valid_gops_with_missing_info++;
145-
break;
146-
case SV_AUTH_RESULT_OK:
147-
valid_gops++;
148-
break;
149-
case SV_AUTH_RESULT_NOT_OK:
150-
invalid_gops++;
151-
break;
152-
case SV_AUTH_RESULT_SIGNATURE_PRESENT:
153-
has_signature++;
154-
break;
155-
case SV_AUTH_RESULT_NOT_SIGNED:
156-
unsigned_gops++;
157-
break;
158-
default:
159-
break;
160-
}
161-
public_key_has_changed |= latest->public_key_has_changed;
162-
has_timestamp |= latest->has_timestamp;
163-
164-
if (latest->has_timestamp) {
165-
if (sv->onvif || sv->legacy_sv) {
166-
// Media Signing and Legacy code only have one timestamp
167-
ck_assert_int_eq(latest->start_timestamp, latest->end_timestamp);
168-
} else {
169-
ck_assert_int_lt(latest->start_timestamp, latest->end_timestamp);
170-
}
171-
}
172-
173-
// Check if product_info has been received and set correctly.
174-
if ((latest->authenticity != SV_AUTH_RESULT_NOT_SIGNED) &&
175-
(latest->authenticity != SV_AUTH_RESULT_SIGNATURE_PRESENT)) {
176-
#ifdef NO_ONVIF_MEDIA_SIGNING
177-
ck_assert_int_eq(strcmp(auth_report->product_info.hardware_id, HW_ID), 0);
178-
ck_assert_int_eq(strcmp(auth_report->product_info.address, ADDR), 0);
179-
#endif
180-
ck_assert_int_eq(strcmp(auth_report->product_info.firmware_version, FW_VER), 0);
181-
ck_assert_int_eq(strcmp(auth_report->product_info.serial_number, SER_NO), 0);
182-
ck_assert_int_eq(strcmp(auth_report->product_info.manufacturer, MANUFACT), 0);
183-
184-
// Check if code version used when signing the video is equal to the code version used when
185-
// validating the authenticity.
186-
if (check_version && strlen(auth_report->version_on_signing_side) != 0) {
187-
ck_assert(!signed_video_compare_versions(
188-
auth_report->version_on_signing_side, auth_report->this_version));
189-
}
190-
}
191-
// Get an authenticity report from separate API and compare accumulated results.
192-
signed_video_authenticity_t *extra_auth_report = signed_video_get_authenticity_report(sv);
193-
ck_assert_int_eq(
194-
memcmp(&auth_report->accumulated_validation, &extra_auth_report->accumulated_validation,
195-
sizeof(signed_video_accumulated_validation_t)),
196-
0);
197-
signed_video_authenticity_report_free(extra_auth_report);
198-
199-
// We are done with auth_report.
200-
latest = NULL;
201-
signed_video_authenticity_report_free(auth_report);
202-
}
203-
// Move to next Bitstream Unit.
204-
item = item->next;
205-
}
206-
// Check GOP statistics against expected.
207-
ck_assert_int_eq(valid_gops, expected.valid_gops);
208-
ck_assert_int_eq(valid_gops_with_missing_info, expected.valid_gops_with_missing_info);
209-
ck_assert_int_eq(invalid_gops, expected.invalid_gops);
210-
ck_assert_int_eq(unsigned_gops, expected.unsigned_gops);
211-
ck_assert_int_eq(missed_bu, expected.missed_bu);
212-
ck_assert_int_eq(pending_bu, expected.pending_bu);
213-
ck_assert_int_eq(has_signature, expected.has_signature);
214-
ck_assert_int_eq(public_key_has_changed, expected.public_key_has_changed);
215-
ck_assert_int_eq(has_timestamp, !expected.has_no_timestamp);
216-
217-
// Get the authenticity report and compare the stats against expected.
218-
if (expected.final_validation) {
219-
auth_report = signed_video_get_authenticity_report(sv);
220-
ck_assert_int_eq(
221-
auth_report->accumulated_validation.authenticity, expected.final_validation->authenticity);
222-
ck_assert_int_eq(auth_report->accumulated_validation.public_key_has_changed,
223-
expected.final_validation->public_key_has_changed);
224-
ck_assert_int_eq(auth_report->accumulated_validation.number_of_received_nalus,
225-
expected.final_validation->number_of_received_nalus);
226-
ck_assert_int_eq(auth_report->accumulated_validation.number_of_validated_nalus,
227-
expected.final_validation->number_of_validated_nalus);
228-
ck_assert_int_eq(auth_report->accumulated_validation.number_of_pending_nalus,
229-
expected.final_validation->number_of_pending_nalus);
230-
ck_assert_int_eq(auth_report->accumulated_validation.public_key_validation,
231-
expected.final_validation->public_key_validation);
232-
ck_assert_int_eq(auth_report->accumulated_validation.has_timestamp,
233-
expected.final_validation->has_timestamp);
234-
signed_video_authenticity_report_free(auth_report);
235-
}
236-
237-
if (internal_sv) signed_video_free(sv);
238-
}
239-
24064
/* Test description
24165
* The public API signed_video_add_nalu_and_authenticate(...) is checked for invalid parameters, and
24266
* invalid Bitstream Units.

tests/check/test_helpers.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,3 +601,157 @@ tlv_has_mandatory_tags(const uint8_t *tlv_data, size_t tlv_data_size)
601601
}
602602
return has_mandatory_tags;
603603
}
604+
605+
/* validate_stream(...)
606+
*
607+
* Helper function to validate the authentication result.
608+
* It takes a test stream |list| as input together with |expected| values of
609+
* valid gops
610+
* invalid gops
611+
* unsigned gops, that is gops without signature
612+
* missed number of gops
613+
* etc
614+
*
615+
* If a NULL pointer |list| is passed in no action is taken.
616+
* If a NULL pointer |sv| is passed in a new session is created. This is
617+
* convenient if there are no other actions to take on |sv| outside this scope,
618+
* like reset.
619+
*/
620+
void
621+
validate_stream(signed_video_t *sv,
622+
test_stream_t *list,
623+
struct validation_stats expected,
624+
bool check_version)
625+
{
626+
if (!list) return;
627+
628+
bool internal_sv = false;
629+
if (!sv) {
630+
sv = signed_video_create(list->codec);
631+
internal_sv = true;
632+
}
633+
634+
signed_video_authenticity_t *auth_report = NULL;
635+
signed_video_latest_validation_t *latest = NULL;
636+
637+
int valid_gops = 0;
638+
int valid_gops_with_missing_info = 0;
639+
int invalid_gops = 0;
640+
int unsigned_gops = 0;
641+
int missed_bu = 0;
642+
int pending_bu = 0;
643+
int has_signature = 0;
644+
bool public_key_has_changed = false;
645+
bool has_timestamp = false;
646+
// Loop through all items in the stream
647+
test_stream_item_t *item = list->first_item;
648+
while (item) {
649+
SignedVideoReturnCode rc =
650+
signed_video_add_nalu_and_authenticate(sv, item->data, item->data_size, &auth_report);
651+
ck_assert_int_eq(rc, SV_OK);
652+
653+
if (auth_report) {
654+
latest = &(auth_report->latest_validation);
655+
ck_assert(latest);
656+
if (latest->number_of_expected_picture_nalus >= 0) {
657+
missed_bu +=
658+
latest->number_of_expected_picture_nalus - latest->number_of_received_picture_nalus;
659+
}
660+
pending_bu += latest->number_of_pending_picture_nalus;
661+
switch (latest->authenticity) {
662+
case SV_AUTH_RESULT_OK_WITH_MISSING_INFO:
663+
valid_gops_with_missing_info++;
664+
break;
665+
case SV_AUTH_RESULT_OK:
666+
valid_gops++;
667+
break;
668+
case SV_AUTH_RESULT_NOT_OK:
669+
invalid_gops++;
670+
break;
671+
case SV_AUTH_RESULT_SIGNATURE_PRESENT:
672+
has_signature++;
673+
break;
674+
case SV_AUTH_RESULT_NOT_SIGNED:
675+
unsigned_gops++;
676+
break;
677+
default:
678+
break;
679+
}
680+
public_key_has_changed |= latest->public_key_has_changed;
681+
has_timestamp |= latest->has_timestamp;
682+
683+
if (latest->has_timestamp) {
684+
if (sv->onvif || sv->legacy_sv) {
685+
// Media Signing and Legacy code only have one timestamp
686+
ck_assert_int_eq(latest->start_timestamp, latest->end_timestamp);
687+
} else {
688+
ck_assert_int_lt(latest->start_timestamp, latest->end_timestamp);
689+
}
690+
}
691+
692+
// Check if product_info has been received and set correctly.
693+
if ((latest->authenticity != SV_AUTH_RESULT_NOT_SIGNED) &&
694+
(latest->authenticity != SV_AUTH_RESULT_SIGNATURE_PRESENT)) {
695+
#ifdef NO_ONVIF_MEDIA_SIGNING
696+
ck_assert_int_eq(strcmp(auth_report->product_info.hardware_id, HW_ID), 0);
697+
ck_assert_int_eq(strcmp(auth_report->product_info.address, ADDR), 0);
698+
#endif
699+
ck_assert_int_eq(strcmp(auth_report->product_info.firmware_version, FW_VER), 0);
700+
ck_assert_int_eq(strcmp(auth_report->product_info.serial_number, SER_NO), 0);
701+
ck_assert_int_eq(strcmp(auth_report->product_info.manufacturer, MANUFACT), 0);
702+
703+
// Check if code version used when signing the video is equal to the code version used when
704+
// validating the authenticity.
705+
if (check_version && strlen(auth_report->version_on_signing_side) != 0) {
706+
ck_assert(!signed_video_compare_versions(
707+
auth_report->version_on_signing_side, auth_report->this_version));
708+
}
709+
}
710+
// Get an authenticity report from separate API and compare accumulated results.
711+
signed_video_authenticity_t *extra_auth_report = signed_video_get_authenticity_report(sv);
712+
ck_assert_int_eq(
713+
memcmp(&auth_report->accumulated_validation, &extra_auth_report->accumulated_validation,
714+
sizeof(signed_video_accumulated_validation_t)),
715+
0);
716+
signed_video_authenticity_report_free(extra_auth_report);
717+
718+
// We are done with auth_report.
719+
latest = NULL;
720+
signed_video_authenticity_report_free(auth_report);
721+
}
722+
// Move to next Bitstream Unit.
723+
item = item->next;
724+
}
725+
// Check GOP statistics against expected.
726+
ck_assert_int_eq(valid_gops, expected.valid_gops);
727+
ck_assert_int_eq(valid_gops_with_missing_info, expected.valid_gops_with_missing_info);
728+
ck_assert_int_eq(invalid_gops, expected.invalid_gops);
729+
ck_assert_int_eq(unsigned_gops, expected.unsigned_gops);
730+
ck_assert_int_eq(missed_bu, expected.missed_bu);
731+
ck_assert_int_eq(pending_bu, expected.pending_bu);
732+
ck_assert_int_eq(has_signature, expected.has_signature);
733+
ck_assert_int_eq(public_key_has_changed, expected.public_key_has_changed);
734+
ck_assert_int_eq(has_timestamp, !expected.has_no_timestamp);
735+
736+
// Get the authenticity report and compare the stats against expected.
737+
if (expected.final_validation) {
738+
auth_report = signed_video_get_authenticity_report(sv);
739+
ck_assert_int_eq(
740+
auth_report->accumulated_validation.authenticity, expected.final_validation->authenticity);
741+
ck_assert_int_eq(auth_report->accumulated_validation.public_key_has_changed,
742+
expected.final_validation->public_key_has_changed);
743+
ck_assert_int_eq(auth_report->accumulated_validation.number_of_received_nalus,
744+
expected.final_validation->number_of_received_nalus);
745+
ck_assert_int_eq(auth_report->accumulated_validation.number_of_validated_nalus,
746+
expected.final_validation->number_of_validated_nalus);
747+
ck_assert_int_eq(auth_report->accumulated_validation.number_of_pending_nalus,
748+
expected.final_validation->number_of_pending_nalus);
749+
ck_assert_int_eq(auth_report->accumulated_validation.public_key_validation,
750+
expected.final_validation->public_key_validation);
751+
ck_assert_int_eq(auth_report->accumulated_validation.has_timestamp,
752+
expected.final_validation->has_timestamp);
753+
signed_video_authenticity_report_free(auth_report);
754+
}
755+
756+
if (internal_sv) signed_video_free(sv);
757+
}

0 commit comments

Comments
 (0)