diff options
Diffstat (limited to 'src/libcamera/pub_key.cpp')
-rw-r--r-- | src/libcamera/pub_key.cpp | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/src/libcamera/pub_key.cpp b/src/libcamera/pub_key.cpp index 9bb08fda..64dfa234 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/evp.h> +#include <openssl/rsa.h> +#include <openssl/sha.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_PUBKEY(nullptr, &data, key.size()); + 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 + EVP_PKEY_free(pubkey_); +#elif HAVE_GNUTLS gnutls_pubkey_deinit(pubkey_); #endif } @@ -76,7 +90,35 @@ PubKey::~PubKey() bool PubKey::verify([[maybe_unused]] Span<const uint8_t> data, [[maybe_unused]] Span<const uint8_t> sig) const { -#if HAVE_GNUTLS + if (!valid_) + return false; + +#if HAVE_CRYPTO + /* + * Create and initialize a public key algorithm context for signature + * verification. + */ + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pubkey_, nullptr); + if (!ctx) + return false; + + if (EVP_PKEY_verify_init(ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0 || + EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0) { + EVP_PKEY_CTX_free(ctx); + return false; + } + + /* Calculate the SHA256 digest of the data. */ + uint8_t digest[SHA256_DIGEST_LENGTH]; + SHA256(data.data(), data.size(), digest); + + /* Decrypt the signature and verify it matches the digest. */ + int ret = EVP_PKEY_verify(ctx, sig.data(), sig.size(), digest, + SHA256_DIGEST_LENGTH); + EVP_PKEY_CTX_free(ctx); + return ret == 1; +#elif HAVE_GNUTLS const gnutls_datum_t gnuTlsData{ const_cast<unsigned char *>(data.data()), static_cast<unsigned int>(data.size()) |