[libcamera-devel] [PATCH 5/5] libcamera: pub_key: Support openssl as an alternative to gnutls
Eric Curtin
ecurtin at redhat.com
Mon Aug 8 11:09:08 CEST 2022
Was happy to see this change so we could build with just openssl if desired.
On Sun, 7 Aug 2022 at 03:15, Laurent Pinchart via libcamera-devel
<libcamera-devel at lists.libcamera.org> wrote:
>
> Support verify IPA signatures with openssl as an alternative to gnutls,
> to offer more flexibility in the selection of dependencies. Use gnutls
> by default, for no specific reason as both are equally well supported.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> README.rst | 2 +-
> include/libcamera/internal/pub_key.h | 8 +++++--
> src/libcamera/meson.build | 16 +++++++++----
> src/libcamera/pub_key.cpp | 35 ++++++++++++++++++++++++----
> 4 files changed, 50 insertions(+), 11 deletions(-)
>
> diff --git a/README.rst b/README.rst
> index 3606057ff706..e9dd4207ae55 100644
> --- a/README.rst
> +++ b/README.rst
> @@ -61,7 +61,7 @@ for the libcamera core: [required]
> libyaml-dev python3-yaml python3-ply python3-jinja2
>
> for IPA module signing: [recommended]
> - libgnutls28-dev openssl
> + Either libgnutls28-dev or libssl-dev, openssl
>
> Without IPA module signing, all IPA modules will be isolated in a
> separate process. This adds an unnecessary extra overhead at runtime.
> diff --git a/include/libcamera/internal/pub_key.h b/include/libcamera/internal/pub_key.h
> index a22ba037cff6..ea7d9af84515 100644
> --- a/include/libcamera/internal/pub_key.h
> +++ b/include/libcamera/internal/pub_key.h
> @@ -11,7 +11,9 @@
>
> #include <libcamera/base/span.h>
>
> -#if HAVE_GNUTLS
> +#if HAVE_CRYPTO
> +struct rsa_st;
> +#elif HAVE_GNUTLS
> struct gnutls_pubkey_st;
> #endif
>
> @@ -28,7 +30,9 @@ public:
>
> private:
> bool valid_;
> -#if HAVE_GNUTLS
> +#if HAVE_CRYPTO
> + struct rsa_st *pubkey_;
> +#elif HAVE_GNUTLS
> struct gnutls_pubkey_st *pubkey_;
> #endif
> };
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index e144d4f9ae70..ce1f0f2f3ef6 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -65,14 +65,22 @@ subdir('pipeline')
> subdir('proxy')
>
> libdl = cc.find_library('dl')
> -libgnutls = dependency('gnutls', required : false)
> libudev = dependency('libudev', required : false)
> libyaml = dependency('yaml-0.1', required : false)
>
> -if libgnutls.found()
> +# Use one of gnutls or libcrypto (provided by OpenSSL), trying gnutls first.
> +libcrypto = dependency('gnutls', required : false)
> +if libcrypto.found()
> config_h.set('HAVE_GNUTLS', 1)
> else
> - warning('gnutls not found, all IPA modules will be isolated')
> + libcrypto = dependency('libcrypto', required : false)
> + if libcrypto.found()
> + config_h.set('HAVE_CRYPTO', 1)
> + endif
> +endif
> +
> +if not libcrypto.found()
> + warning('Neither gnutls nor libcrypto found, all IPA modules will be isolated')
> endif
>
> if liblttng.found()
> @@ -137,8 +145,8 @@ libcamera_deps = [
> libatomic,
> libcamera_base,
> libcamera_base_private,
> + libcrypto,
> libdl,
> - libgnutls,
> liblttng,
> libudev,
> libyaml,
> diff --git a/src/libcamera/pub_key.cpp b/src/libcamera/pub_key.cpp
> index b2045a103bc0..723f311b91a2 100644
> --- a/src/libcamera/pub_key.cpp
> +++ b/src/libcamera/pub_key.cpp
> @@ -7,7 +7,12 @@
>
> #include "libcamera/internal/pub_key.h"
>
> -#if HAVE_GNUTLS
> +#if HAVE_CRYPTO
> +#include <openssl/bio.h>
> +#include <openssl/rsa.h>
> +#include <openssl/ssl.h>
> +#include <openssl/x509.h>
> +#elif HAVE_GNUTLS
> #include <gnutls/abstract.h>
> #endif
>
> @@ -33,7 +38,14 @@ namespace libcamera {
> PubKey::PubKey([[maybe_unused]] Span<const uint8_t> key)
> : valid_(false)
> {
> -#if HAVE_GNUTLS
> +#if HAVE_CRYPTO
> + const uint8_t *data = key.data();
> + pubkey_ = d2i_RSA_PUBKEY(nullptr, &data, key.size());
It's failing the build here on Fedora 36 at least:
FAILED: src/libcamera/libcamera.so.0.0.0.p/pub_key.cpp.o
ccache c++ -Isrc/libcamera/libcamera.so.0.0.0.p -Isrc/libcamera
-I../src/libcamera -Iinclude -I../include
-I../subprojects/libyaml/include
-Isubprojects/libyaml/__CMake_build/include
-I../subprojects/libyaml/__CMake_build/include
-Isubprojects/libyaml/__CMake_build
-I../subprojects/libyaml/__CMake_build -Isubprojects/libyaml
-I../subprojects/libyaml -Iinclude/libcamera -Iinclude/libcamera/ipa
-Iinclude/libcamera/internal -Isrc/libcamera/proxy
-fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch
-Wnon-virtual-dtor -Wextra -Werror -std=c++17 -O3 -Wshadow -include
/home/curtine/git/libcamera/build/config.h -fPIC -DYAML_DECLARE_STATIC
-D_CRT_SECURE_NO_WARNINGS -DLIBCAMERA_BASE_PRIVATE -MD -MQ
src/libcamera/libcamera.so.0.0.0.p/pub_key.cpp.o -MF
src/libcamera/libcamera.so.0.0.0.p/pub_key.cpp.o.d -o
src/libcamera/libcamera.so.0.0.0.p/pub_key.cpp.o -c
../src/libcamera/pub_key.cpp
../src/libcamera/pub_key.cpp: In constructor
‘libcamera::PubKey::PubKey(libcamera::Span<const unsigned char>)’:
../src/libcamera/pub_key.cpp:43:33: error: ‘RSA* d2i_RSA_PUBKEY(RSA**,
const unsigned char**, long int)’ is deprecated: Since OpenSSL 3.0
[-Werror=deprecated-declarations]
43 | pubkey_ = d2i_RSA_PUBKEY(nullptr, &data, key.size());
| ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/openssl/rsa.h:21,
from ../src/libcamera/pub_key.cpp:12:
/usr/include/openssl/x509.h:710:1: note: declared here
710 | DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(OSSL_DEPRECATEDIN_3_0,RSA,
RSA_PUBKEY)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/libcamera/pub_key.cpp: In destructor ‘libcamera::PubKey::~PubKey()’:
../src/libcamera/pub_key.cpp:68:17: error: ‘void RSA_free(RSA*)’ is
deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
68 | RSA_free(pubkey_);
| ~~~~~~~~^~~~~~~~~
/usr/include/openssl/rsa.h:293:28: note: declared here
293 | OSSL_DEPRECATEDIN_3_0 void RSA_free(RSA *r);
| ^~~~~~~~
../src/libcamera/pub_key.cpp: In member function ‘bool
libcamera::PubKey::verify(libcamera::Span<const unsigned char>,
libcamera::Span<const unsigned char>) const’:
../src/libcamera/pub_key.cpp:99:20: error: ‘int
SHA256_Init(SHA256_CTX*)’ is deprecated: Since OpenSSL 3.0
[-Werror=deprecated-declarations]
99 | SHA256_Init(&ctx);
| ~~~~~~~~~~~^~~~~~
In file included from /usr/include/openssl/x509.h:41,
from /usr/include/openssl/ssl.h:31,
from ../src/libcamera/pub_key.cpp:13:
/usr/include/openssl/sha.h:73:27: note: declared here
73 | OSSL_DEPRECATEDIN_3_0 int SHA256_Init(SHA256_CTX *c);
| ^~~~~~~~~~~
../src/libcamera/pub_key.cpp:100:22: error: ‘int
SHA256_Update(SHA256_CTX*, const void*, size_t)’ is deprecated: Since
OpenSSL 3.0 [-Werror=deprecated-declarations]
100 | SHA256_Update(&ctx, data.data(), data.size());
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/openssl/sha.h:74:27: note: declared here
74 | OSSL_DEPRECATEDIN_3_0 int SHA256_Update(SHA256_CTX *c,
| ^~~~~~~~~~~~~
../src/libcamera/pub_key.cpp:103:21: error: ‘int SHA256_Final(unsigned
char*, SHA256_CTX*)’ is deprecated: Since OpenSSL 3.0
[-Werror=deprecated-declarations]
103 | SHA256_Final(digest, &ctx);
| ~~~~~~~~~~~~^~~~~~~~~~~~~~
/usr/include/openssl/sha.h:76:27: note: declared here
76 | OSSL_DEPRECATEDIN_3_0 int SHA256_Final(unsigned char *md,
SHA256_CTX *c);
| ^~~~~~~~~~~~
../src/libcamera/pub_key.cpp:106:29: error: ‘int RSA_verify(int, const
unsigned char*, unsigned int, const unsigned char*, unsigned int,
RSA*)’ is deprecated: Since OpenSSL 3.0
[-Werror=deprecated-declarations]
106 | int ret = RSA_verify(NID_sha256, digest, SHA256_DIGEST_LENGTH,
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107 | sig.data(), sig.size(), pubkey_);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/openssl/rsa.h:351:27: note: declared here
351 | OSSL_DEPRECATEDIN_3_0 int RSA_verify(int type, const unsigned char *m,
| ^~~~~~~~~~
cc1plus: all warnings being treated as errors
> + if (!pubkey_)
> + return;
> +
> + valid_ = true;
> +#elif HAVE_GNUTLS
> int ret = gnutls_pubkey_init(&pubkey_);
> if (ret < 0)
> return;
> @@ -52,7 +64,9 @@ PubKey::PubKey([[maybe_unused]] Span<const uint8_t> key)
>
> PubKey::~PubKey()
> {
> -#if HAVE_GNUTLS
> +#if HAVE_CRYPTO
> + RSA_free(pubkey_);
> +#elif HAVE_GNUTLS
> gnutls_pubkey_deinit(pubkey_);
> #endif
> }
> @@ -79,7 +93,20 @@ bool PubKey::verify([[maybe_unused]] Span<const uint8_t> data,
> if (!valid_)
> return false;
>
> -#if HAVE_GNUTLS
> +#if HAVE_CRYPTO
> + /* Calculate the SHA256 digest of the data. */
> + SHA256_CTX ctx;
> + SHA256_Init(&ctx);
> + SHA256_Update(&ctx, data.data(), data.size());
> +
> + uint8_t digest[SHA256_DIGEST_LENGTH];
> + SHA256_Final(digest, &ctx);
> +
> + /* Decrypt the signature and verify it matches the digest. */
> + int ret = RSA_verify(NID_sha256, digest, SHA256_DIGEST_LENGTH,
> + sig.data(), sig.size(), pubkey_);
> + return ret == 1;
> +#elif HAVE_GNUTLS
> const gnutls_datum_t gnuTlsData{
> const_cast<unsigned char *>(data.data()),
> static_cast<unsigned int>(data.size())
> --
> Regards,
>
> Laurent Pinchart
>
More information about the libcamera-devel
mailing list