summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/include/meson.build1
-rw-r--r--src/libcamera/include/pub_key.h38
-rw-r--r--src/libcamera/meson.build7
-rw-r--r--src/libcamera/pub_key.cpp97
4 files changed, 143 insertions, 0 deletions
diff --git a/src/libcamera/include/meson.build b/src/libcamera/include/meson.build
index 921ed5a0..5aaa9947 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 00000000..f35bf373
--- /dev/null
+++ b/src/libcamera/include/pub_key.h
@@ -0,0 +1,38 @@
+/* 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>
+
+#if HAVE_GNUTLS
+struct gnutls_pubkey_st;
+#endif
+
+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 4f5c4167..c2a657e4 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 00000000..064d2dd2
--- /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 */