[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