[libcamera-devel] [PATCH 5/5] libcamera: pub_key: Support openssl as an alternative to gnutls

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Aug 8 17:46:14 CEST 2022


Hi Eric,

On Mon, Aug 08, 2022 at 10:09:08AM +0100, Eric Curtin wrote:
> 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 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:

Aarrghhhh why are there so many versions of the same package ? :-)

Thank you for testing, I'll see if I can fix this.

> 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