[libcamera-devel] [PATCH 08/11] libcamera: Add PubKey class
Niklas Söderlund
niklas.soderlund at ragnatech.se
Tue Apr 7 22:33:56 CEST 2020
Hi Laurent,
Thanks for your work.
On 2020-04-04 04:56:21 +0300, Laurent Pinchart wrote:
> Add a new PubKey class to handle public key signature verification. The
> implementation is based on the gnutls library, which is added as an
> optional dependency. If gnutls is not found, signature verification will
> unconditionally fail.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> src/libcamera/include/meson.build | 1 +
> src/libcamera/include/pub_key.h | 36 ++++++++++++
> src/libcamera/meson.build | 7 +++
> src/libcamera/pub_key.cpp | 97 +++++++++++++++++++++++++++++++
> 4 files changed, 141 insertions(+)
> create mode 100644 src/libcamera/include/pub_key.h
> create mode 100644 src/libcamera/pub_key.cpp
>
> diff --git a/src/libcamera/include/meson.build b/src/libcamera/include/meson.build
> index 921ed5a063cb..5aaa99472e4a 100644
> --- a/src/libcamera/include/meson.build
> +++ b/src/libcamera/include/meson.build
> @@ -21,6 +21,7 @@ libcamera_headers = files([
> 'message.h',
> 'pipeline_handler.h',
> 'process.h',
> + 'pub_key.h',
> 'semaphore.h',
> 'thread.h',
> 'utils.h',
> diff --git a/src/libcamera/include/pub_key.h b/src/libcamera/include/pub_key.h
> new file mode 100644
> index 000000000000..4d3bdd69bfd8
> --- /dev/null
> +++ b/src/libcamera/include/pub_key.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2020, Google Inc.
> + *
> + * pub_key.h - Public key signature verification
> + */
> +#ifndef __LIBCAMERA_PUB_KEY_H__
> +#define __LIBCAMERA_PUB_KEY_H__
> +
> +#include <stdint.h>
> +
> +#include <libcamera/span.h>
> +
> +struct gnutls_pubkey_st;
Nit, this forward declaration is only needed if HAVE_GNUTLS is set,
would it make to sens to make it conditional on that to make it clear?
With or without this fixed,
Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> +
> +namespace libcamera {
> +
> +class PubKey
> +{
> +public:
> + PubKey(Span<const uint8_t> key);
> + ~PubKey();
> +
> + bool isValid() const { return valid_; }
> + bool verify(Span<const uint8_t> data, Span<const uint8_t> sig) const;
> +
> +private:
> + bool valid_;
> +#if HAVE_GNUTLS
> + struct gnutls_pubkey_st *pubkey_;
> +#endif
> +};
> +
> +} /* namespace libcamera */
> +
> +#endif /* __LIBCAMERA_PUB_KEY_H__ */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index 4f5c41678781..c2a657e4938c 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -34,6 +34,7 @@ libcamera_sources = files([
> 'pipeline_handler.cpp',
> 'pixelformats.cpp',
> 'process.cpp',
> + 'pub_key.cpp',
> 'request.cpp',
> 'semaphore.cpp',
> 'signal.cpp',
> @@ -61,8 +62,13 @@ subdir('proxy')
>
> libatomic = cc.find_library('atomic', required : false)
> libdl = cc.find_library('dl')
> +libgnutls = cc.find_library('gnutls', required : false)
> libudev = dependency('libudev', required : false)
>
> +if libgnutls.found()
> + config_h.set('HAVE_GNUTLS', 1)
> +endif
> +
> if libudev.found()
> config_h.set('HAVE_LIBUDEV', 1)
> libcamera_sources += files([
> @@ -98,6 +104,7 @@ libcamera_sources += version_cpp
> libcamera_deps = [
> libatomic,
> libdl,
> + libgnutls,
> libudev,
> dependency('threads'),
> ]
> diff --git a/src/libcamera/pub_key.cpp b/src/libcamera/pub_key.cpp
> new file mode 100644
> index 000000000000..064d2dd200e1
> --- /dev/null
> +++ b/src/libcamera/pub_key.cpp
> @@ -0,0 +1,97 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2020, Google Inc.
> + *
> + * pub_key.cpp - Public key signature verification
> + */
> +
> +#include "pub_key.h"
> +
> +#if HAVE_GNUTLS
> +#include <gnutls/abstract.h>
> +#endif
> +
> +/**
> + * \file pub_key.h
> + * \brief Public key signature verification
> + */
> +
> +namespace libcamera {
> +
> +/**
> + * \class PubKey
> + * \brief Public key wrapper for signature verification
> + *
> + * The PubKey class wraps a public key and implements signature verification. It
> + * only supports RSA keys and the RSA-SHA256 signature algorithm.
> + */
> +
> +/**
> + * \brief Construct a PubKey from key data
> + * \param[in] key Key data encoded in DER format
> + */
> +PubKey::PubKey(Span<const uint8_t> key)
> + : valid_(false)
> +{
> +#if HAVE_GNUTLS
> + int ret = gnutls_pubkey_init(&pubkey_);
> + if (ret < 0)
> + return;
> +
> + const gnutls_datum_t gnuTlsKey{
> + const_cast<unsigned char *>(key.data()),
> + static_cast<unsigned int>(key.size())
> + };
> + ret = gnutls_pubkey_import(pubkey_, &gnuTlsKey, GNUTLS_X509_FMT_DER);
> + if (ret < 0)
> + return;
> +
> + valid_ = true;
> +#endif
> +}
> +
> +PubKey::~PubKey()
> +{
> +#if HAVE_GNUTLS
> + gnutls_pubkey_deinit(pubkey_);
> +#endif
> +}
> +
> +/**
> + * \fn bool PubKey::isValid() const
> + * \brief Check is the public key is valid
> + * \return True if the public key is valid, false otherwise
> + */
> +
> +/**
> + * \brief Verify signature on data
> + * \param[in] data The signed data
> + * \param[in] sig The signature
> + *
> + * Verify that the signature \a sig matches the signed \a data for the public
> + * key. The signture algorithm is hardcoded to RSA-SHA256.
> + *
> + * \return True if the signature is valid, false otherwise
> + */
> +bool PubKey::verify(Span<const uint8_t> data, Span<const uint8_t> sig) const
> +{
> +#if HAVE_GNUTLS
> + const gnutls_datum_t gnuTlsData{
> + const_cast<unsigned char *>(data.data()),
> + static_cast<unsigned int>(data.size())
> + };
> +
> + const gnutls_datum_t gnuTlsSig{
> + const_cast<unsigned char *>(sig.data()),
> + static_cast<unsigned int>(sig.size())
> + };
> +
> + int ret = gnutls_pubkey_verify_data2(pubkey_, GNUTLS_SIGN_RSA_SHA256, 0,
> + &gnuTlsData, &gnuTlsSig);
> + return ret >= 0;
> +#else
> + return false;
> +#endif
> +}
> +
> +} /* namespace libcamera */
> --
> Regards,
>
> Laurent Pinchart
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
--
Regards,
Niklas Söderlund
More information about the libcamera-devel
mailing list