Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,26 @@ signed-video-framework
| | | └── plugin.c
| | └── unthreaded-signing
| | └── plugin.c
| ├── src
| | ├── includes
| | | └── public header files
| | └── source files
| └── vendors
| └── axis-communications
| └── source files
| └── src
| ├── includes
| | └── public header files
| └── source files
└── tests
```

The repository is split into a library and tests. The library is further organized in
[source code](./lib/src/), [plugins](./lib/plugins/) and [vendors](./lib/vendors/). The source code
includes all necessary source files for both signing and validation, and there is no conceptual
difference in building the library for signing or for validation.
[source code](./lib/src/) and [plugins](./lib/plugins/). The source code includes all necessary
source files for both signing and validation, and there is no conceptual difference in building the
library for signing or for validation.

Signing is commonly device specific with separate calls for, e.g., reading and using private keys.
Therefore, the framework uses the concept of signing plugins which implements a set of
[interfaces](./lib/src/includes/signed_video_signing_plugin.h). The framework comes with both a
threaded and an unthreaded signing plugin.

Further, the framework allows for vendor specific metadata. Adding that on the signing side, and
interpreting it on the validation side is controlled through vendor specific code.

For instructions on how to use the APIs to integrate the Signed Video Framework in either a signing or a validation application, see [lib/](./lib/). Example applications are available in the [signed-video-framework-examples](https://github.com/AxisCommunications/signed-video-framework-examples) repository.
For instructions on how to use the APIs to integrate the Signed Video Framework in either a signing
or a validation application, see [lib/](./lib/). Example applications are available in the
[signed-video-framework-examples](https://github.com/AxisCommunications/signed-video-framework-examples) repository.

# Releases
There are no pre-built releases. The user is encouraged to build the library from a [release tag](https://github.com/AxisCommunications/signed-video-framework/tags).
Expand Down
19 changes: 5 additions & 14 deletions lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ lib
| | └── plugin.c
| └── unthreaded-signing
| └── plugin.c
├── src
| ├── includes
| | └── public header files
| └── source files
└── vendors
└── axis-communications
└── source files
└── src
├── includes
| └── public header files
└── source files
```

The library is organized in [source code](./src/), [plugins](./plugins/) and [vendors](./vendors/).
The library is organized in [source code](./src/) and [plugins](./plugins/).
The source code includes all necessary source files for both signing and validation, and there is no
conceptual difference in building the library for signing or for validation.

Expand All @@ -26,9 +23,3 @@ plugin. The interfaces can be found in
[signed_video_signing_plugin.h](./src/includes/signed_video_signing_plugin.h). The framework comes
with both a threaded and an unthreaded signing plugin. When building the library with the meson
structure in this repository, the library includes that plugin.

Vendor specific code and APIs are typically handling extra metadata added to the SEI/OBU Metadata,
which needs to be interpreted correctly when validating authenticity. With the meson option `vendor`
the user can select which vendor(s) to include in the build. Typically, when building for signing
the vendor for that camera is selected, whereas when building for validation all vendors are
included. By default, all vendors are added.
1 change: 0 additions & 1 deletion lib/meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Process plugins first to get the plugin sources used in src/
subdir('plugins')
subdir('vendors')
subdir('src')
9 changes: 2 additions & 7 deletions lib/src/legacy/legacy_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@
#include <stdbool.h>
#include <string.h> // strcmp

#include "legacy_validation.h" // Has public declarations

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
#include "axis-communications/sv_vendor_axis_communications_internal.h"
#endif
#include "legacy/legacy_bu_list.h"
#include "legacy/legacy_internal.h"
#include "legacy/legacy_tlv.h" // legacy_tlv_decode()
#include "legacy_validation.h" // Has public declarations
#include "sv_authenticity.h" // update_accumulated_validation()
#include "sv_axis_communications_internal.h"
#include "sv_openssl_internal.h" // sv_openssl_verify_hash()
#include "sv_tlv.h" // sv_tlv_find_tag()

Expand Down Expand Up @@ -754,7 +751,6 @@ legacy_prepare_for_validation(legacy_sv_t *self)
SV_THROW_IF_WITH_MSG(validation_flags->signing_present && !self->has_public_key,
SV_NOT_SUPPORTED, "No public key present");

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
// If "Axis Communications AB" can be identified from the |product_info|, get
// |supplemental_authenticity| from |vendor_handle|.
if (sei && strcmp(self->product_info->manufacturer, "Axis Communications AB") == 0) {
Expand All @@ -780,7 +776,6 @@ legacy_prepare_for_validation(legacy_sv_t *self)
}
}
}
#endif

// If we have received a SEI there is a signature to use for verification.
if (self->gop_state.has_sei || self->bu_list->first_item->bu->is_golden_sei) {
Expand Down
2 changes: 0 additions & 2 deletions lib/src/legacy/legacy_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,10 +979,8 @@ legacy_sv_create(signed_video_t *parent)
SV_THROW_WITH_MSG(legacy_reset_gop_hash(self), "Could not reset gop_hash");

// Borrow vendor handle from |parent|.
#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
self->vendor_handle = parent->vendor_handle;
SV_THROW_IF(!self->vendor_handle, SV_MEMORY);
#endif

// Initialize validation members
self->bu_list = legacy_bu_list_create();
Expand Down
15 changes: 1 addition & 14 deletions lib/src/legacy/legacy_tlv.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@
#endif
#include <string.h>

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
#include "axis-communications/sv_vendor_axis_communications_internal.h"
#endif
#include "includes/signed_video_common.h" // Return codes
#include "includes/signed_video_openssl.h" // sign_or_verify_data_t
#include "sv_authenticity.h" // allocate_memory_and_copy_string, transfer_product_info()
#include "sv_axis_communications_internal.h"
#include "sv_openssl_internal.h" // openssl_public_key_malloc()
#include "sv_tlv.h" // sv_read_8bits, sv_read_16bits, sv_read_32bits, sv_read_64bits_signed

Expand Down Expand Up @@ -382,15 +380,13 @@ legacy_decode_public_key(legacy_sv_t *self, const uint8_t *data, size_t data_siz
// Convert to EVP_PKEY_CTX
SV_THROW(openssl_public_key_malloc(self->verify_data, &self->pem_public_key));

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
// If "Axis Communications AB" can be identified from the |product_info|, set |public_key| to
// |vendor_handle|.
if (strcmp(self->product_info->manufacturer, "Axis Communications AB") == 0) {
// Set public key.
SV_THROW(set_axis_communications_public_key(self->vendor_handle, self->verify_data->key,
self->latest_validation->public_key_has_changed));
}
#endif

SV_THROW_IF(data_ptr != data + data_size, SV_AUTHENTICATION_ERROR);
#ifdef PRINT_DECODED_SEI
Expand Down Expand Up @@ -549,18 +545,9 @@ legacy_decode_crypto_info(legacy_sv_t *self, const uint8_t *data, size_t data_si
*
*/
static svrc_t
#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
legacy_decode_axis_communications(legacy_sv_t *self, const uint8_t *data, size_t data_size)
{
return decode_axis_communications_handle(self->vendor_handle, data, data_size);
#else
legacy_decode_axis_communications(legacy_sv_t ATTR_UNUSED *self,
const uint8_t ATTR_UNUSED *data,
size_t ATTR_UNUSED data_size)
{
// Vendor Axis Communications not selected.
return SV_NOT_SUPPORTED;
#endif
}

static svrc_t
Expand Down
8 changes: 3 additions & 5 deletions lib/src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ signedvideoframework_public_headers = files(
'includes/signed_video_openssl.h',
'includes/signed_video_sign.h',
'includes/signed_video_signing_plugin.h',
'includes/sv_vendor_axis_communications.h'
)

signedvideoframework_sources = files(
'legacy_validation.h',
'sv_auth.c',
'sv_authenticity.c',
'sv_authenticity.h',
'sv_axis_communications.c',
'sv_axis_communications_internal.h',
'sv_bu_list.c',
'sv_bu_list.h',
'sv_codec_av1.c',
Expand Down Expand Up @@ -41,13 +44,8 @@ legacy_sources = files(

# Add source files from plugins, vendors, legacy code
signedvideoframework_sources += plugin_sources
signedvideoframework_sources += vendor_sources
signedvideoframework_sources += legacy_sources

# Add vendor specific public headers
if build_with_axis
signedvideoframework_public_headers += files('includes/sv_vendor_axis_communications.h')
endif
# Add ONVIF Media Signing source files and public headers
if populated_media_signing_submodule
signedvideoframework_sources += mediasigningframework_sources
Expand Down
8 changes: 1 addition & 7 deletions lib/src/sv_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@
#include <assert.h> // assert
#include <stdlib.h> // free

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
#include "axis-communications/sv_vendor_axis_communications_internal.h"
#endif
#include "includes/signed_video_auth.h"
#include "includes/signed_video_openssl.h" // pem_pkey_t, sign_or_verify_data_t
#include "legacy_validation.h"
#include "sv_authenticity.h" // sv_create_local_authenticity_report_if_needed()
#include "sv_axis_communications_internal.h"
#include "sv_bu_list.h" // bu_list_append()
#include "sv_defines.h" // svrc_t
#include "sv_internal.h" // gop_info_t, validation_flags_t
Expand Down Expand Up @@ -987,7 +985,6 @@ prepare_for_validation(signed_video_t *self, bu_list_item_t **sei)
}
validation_flags->waiting_for_signature = !(*sei)->bu->is_signed;

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
// If "Axis Communications AB" can be identified from the |product_info|, get
// |supplemental_authenticity| from |vendor_handle|.
if (strcmp(self->product_info.manufacturer, "Axis Communications AB") == 0) {
Expand All @@ -1013,7 +1010,6 @@ prepare_for_validation(signed_video_t *self, bu_list_item_t **sei)
}
}
}
#endif

SV_CATCH()
SV_DONE(status)
Expand Down Expand Up @@ -1410,11 +1406,9 @@ detect_onvif_media_signing(signed_video_t *self, const bu_info_t *bu)
SV_TRY()
self->onvif = onvif_media_signing_create(codec);
SV_THROW_IF(!self->onvif, SV_EXTERNAL_ERROR);
#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
// Get the root CA certificate from Axis code.
trusted_certificate = get_axis_communications_trusted_certificate();
trusted_certificate_size = strlen(trusted_certificate);
#endif
SV_THROW(msrc_to_svrc(onvif_media_signing_set_trusted_certificate(
self->onvif, trusted_certificate, trusted_certificate_size, false)));
// If the ONVIF Media Signing session has successfully been set up, register all
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "includes/sv_vendor_axis_communications.h"

#include <assert.h>
#include <openssl/bio.h> // BIO_*
#include <openssl/evp.h> // EVP_*
Expand All @@ -29,9 +27,10 @@
#include <stdbool.h>
#include <stdlib.h> // malloc, memcpy, calloc, free

#include "includes/sv_vendor_axis_communications.h"
#include "sv_axis_communications_internal.h"
#include "sv_internal.h" // signed_video_t
#include "sv_tlv.h"
#include "sv_vendor_axis_communications_internal.h"

#define NUM_UNTRUSTED_CERTIFICATES 2 // |certificate_chain| has 2 untrusted certificates.
#define CHIP_ID_SIZE 18
Expand Down
8 changes: 1 addition & 7 deletions lib/src/sv_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,12 @@
#include <stdlib.h> // free, calloc, malloc
#include <string.h> // size_t

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
#include "axis-communications/sv_vendor_axis_communications_internal.h"
#endif
#include "includes/signed_video_common.h"
#include "includes/signed_video_helpers.h" // onvif_media_signing_parse_sei()
#include "includes/signed_video_openssl.h" // pem_pkey_t, sign_or_verify_data_t
#include "includes/signed_video_signing_plugin.h"
#include "sv_authenticity.h" // sv_latest_validation_init()
#include "sv_axis_communications_internal.h"
#include "sv_bu_list.h" // bu_list_create(), bu_list_free()
#include "sv_codec_internal.h" // parse_h264_nalu_header(), parse_av1_obu_header()
#include "sv_defines.h" // svrc_t
Expand Down Expand Up @@ -990,10 +988,8 @@ signed_video_create(SignedVideoCodec codec)
SV_THROW_IF_WITH_MSG(!self->gop_info, SV_MEMORY, "Could not allocate gop_info");
self->gop_info->num_in_partial_gop = 0;
// Setup vendor handle.
#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
self->vendor_handle = sv_vendor_axis_communications_setup();
SV_THROW_IF(!self->vendor_handle, SV_MEMORY);
#endif

// Initialize signing members
// Signing plugin is setup when the private key is set.
Expand Down Expand Up @@ -1091,9 +1087,7 @@ signed_video_free(signed_video_t *self)
// Teardown the plugin before closing.
sv_signing_plugin_session_teardown(self->plugin_handle);
// Teardown the vendor handle.
#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
sv_vendor_axis_communications_teardown(self->vendor_handle);
#endif
// Teardown the crypto handle.
sv_openssl_free_handle(self->crypto_handle);

Expand Down
6 changes: 1 addition & 5 deletions lib/src/sv_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@
#include <stdlib.h> // free, malloc
#include <string.h> // size_t, strncpy

#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
#include "axis-communications/sv_vendor_axis_communications_internal.h"
#endif
#include "includes/signed_video_openssl.h" // pem_pkey_t
#include "includes/signed_video_sign.h"
#include "includes/signed_video_signing_plugin.h"
#include "sv_authenticity.h" // allocate_memory_and_copy_string
#include "sv_axis_communications_internal.h"
#include "sv_codec_internal.h" // METADATA_TYPE_USER_PRIVATE
#include "sv_defines.h" // svrc_t, sv_tlv_tag_t
#include "sv_internal.h" // gop_info_t
Expand Down Expand Up @@ -798,11 +796,9 @@ initialize_onvif(signed_video_t *self)
SV_TRY()
// Port settings to ONVIF
SV_THROW(port_settings_to_onvif(self));
#ifdef SV_VENDOR_AXIS_COMMUNICATIONS
// Retrieve the certificate chain
certificate_chain = get_axis_communications_certificate_chain(self->vendor_handle);
SV_THROW_IF(!certificate_chain, SV_MEMORY);
#endif
// Set the signing key pair for ONVIF media signing
SV_THROW(msrc_to_svrc(onvif_media_signing_set_signing_key_pair(self->onvif, self->private_key,
self->private_key_size, certificate_chain, strlen(certificate_chain), false)));
Expand Down
Loading