apps: Add ipa-verify application
When packaging libcamera, distributions may break IPA module signatures if the packaging process strips binaries. This can be fixed by resigning the modules, but the process is error-prone. Add a command line ipa-verify utility that tests the signature on an IPA module to help packagers. The tool takes a single argument, the path to an IPA module shared object, and expects the signature file (.sign) to be in the same directory. In order to access the public key needed for signature verification, add a static function to the IPAManager class. As the class is internal to libcamera, this doesn't affect the public API. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Tested-by: Javier Martinez Canillas <javierm@redhat.com>
This commit is contained in:
parent
1d5a072c5e
commit
52579639ce
5 changed files with 101 additions and 0 deletions
|
@ -47,6 +47,13 @@ public:
|
|||
return proxy;
|
||||
}
|
||||
|
||||
#if HAVE_IPA_PUBKEY
|
||||
static const PubKey &pubKey()
|
||||
{
|
||||
return pubKey_;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
static IPAManager *self_;
|
||||
|
||||
|
|
64
src/apps/ipa-verify/main.cpp
Normal file
64
src/apps/ipa-verify/main.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2023, Ideas on Board Oy
|
||||
*
|
||||
* ipa_verify.cpp - Verify signature on an IPA module
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <libcamera/base/file.h>
|
||||
#include <libcamera/base/span.h>
|
||||
|
||||
#include "libcamera/internal/ipa_manager.h"
|
||||
#include "libcamera/internal/ipa_module.h"
|
||||
|
||||
using namespace libcamera;
|
||||
|
||||
namespace {
|
||||
|
||||
bool isSignatureValid(IPAModule *ipa)
|
||||
{
|
||||
File file{ ipa->path() };
|
||||
if (!file.open(File::OpenModeFlag::ReadOnly))
|
||||
return false;
|
||||
|
||||
Span<uint8_t> data = file.map();
|
||||
if (data.empty())
|
||||
return false;
|
||||
|
||||
return IPAManager::pubKey().verify(data, ipa->signature());
|
||||
}
|
||||
|
||||
void usage(char *argv0)
|
||||
{
|
||||
std::cout << "Usage: " << basename(argv0) << " ipa_name.so" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Verify the signature of an IPA module. The signature file ipa_name.so.sign is" << std::endl;
|
||||
std::cout << "expected to be in the same directory as the IPA module." << std::endl;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
usage(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
IPAModule module{ argv[1] };
|
||||
if (!module.isValid()) {
|
||||
std::cout << "Invalid IPA module " << argv[1] << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!isSignatureValid(&module)) {
|
||||
std::cout << "IPA module signature is invalid" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::cout << "IPA module signature is valid" << std::endl;
|
||||
return 0;
|
||||
}
|
15
src/apps/ipa-verify/meson.build
Normal file
15
src/apps/ipa-verify/meson.build
Normal file
|
@ -0,0 +1,15 @@
|
|||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
if not ipa_sign_module
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
ipa_verify_sources = files([
|
||||
'main.cpp',
|
||||
])
|
||||
|
||||
ipa_verify = executable('ipa_verify', ipa_verify_sources,
|
||||
dependencies : [
|
||||
libcamera_private,
|
||||
],
|
||||
install : false)
|
|
@ -18,3 +18,5 @@ subdir('lc-compliance')
|
|||
|
||||
subdir('cam')
|
||||
subdir('qcam')
|
||||
|
||||
subdir('ipa-verify')
|
||||
|
|
|
@ -279,6 +279,19 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,
|
|||
* found or if the IPA proxy fails to initialize
|
||||
*/
|
||||
|
||||
#if HAVE_IPA_PUBKEY
|
||||
/**
|
||||
* \fn IPAManager::pubKey()
|
||||
* \brief Retrieve the IPA module signing public key
|
||||
*
|
||||
* IPA module signature verification is normally handled internally by the
|
||||
* IPAManager class. This function is meant to be used by utilities that need to
|
||||
* verify signatures externally.
|
||||
*
|
||||
* \return The IPA module signing public key
|
||||
*/
|
||||
#endif
|
||||
|
||||
bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const
|
||||
{
|
||||
#if HAVE_IPA_PUBKEY
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue