diff mbox series

[1/1] Add support for gpg signing

Message ID DM6PR07MB637745C0F487CD7AE29E000384F9A@DM6PR07MB6377.namprd07.prod.outlook.com
State Changes Requested
Delegated to: Stefano Babic
Headers show
Series [1/1] Add support for gpg signing | expand

Commit Message

Fong, Amy Sept. 20, 2023, 4:09 p.m. UTC

Comments

Stefano Babic Sept. 20, 2023, 4:45 p.m. UTC | #1
Hi Amy,

On 20.09.23 18:09, 'Fong, Amy' via swupdate wrote:
> 
> -- 
> You received this message because you are subscribed to the Google 
> Groups "swupdate" group.
> To unsubscribe from this group and stop receiving emails from it, send 
> an email to swupdate+unsubscribe@googlegroups.com 
> <mailto:swupdate+unsubscribe@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/swupdate/DM6PR07MB637745C0F487CD7AE29E000384F9A%40DM6PR07MB6377.namprd07.prod.outlook.com <https://groups.google.com/d/msgid/swupdate/DM6PR07MB637745C0F487CD7AE29E000384F9A%40DM6PR07MB6377.namprd07.prod.outlook.com?utm_medium=email&utm_source=footer>.

It is not possible to review the patch if attached. Please send your 
patch inline, using git send-email to post it to the ML - thanks !

Best regards,
Stefano Babic
diff mbox series

Patch

From b346d02daf524490255559f07bde5119334d5812 Mon Sep 17 00:00:00 2001
From: Amy Fong <Amy_Fong@mentor.com>
Date: Wed, 20 Sep 2023 12:01:58 -0400
Subject: [PATCH] gpg: add optional gpg signing verification

This change introduces a Kconfig parameter allowing gpg verification.
The environment variable GPG_HOMEDIR, if set, is used to specify the
home directory.

Signed-off-by: Amy Fong <Amy_Fong@mentor.com>
---
 Kconfig                       |   2 +
 Makefile.flags                |   5 ++
 corelib/Makefile              |   1 +
 corelib/swupdate_gpg_verify.c | 126 ++++++++++++++++++++++++++++++++++
 4 files changed, 134 insertions(+)
 create mode 100644 corelib/swupdate_gpg_verify.c

diff --git a/Kconfig b/Kconfig
index 636c4ac..187a656 100644
--- a/Kconfig
+++ b/Kconfig
@@ -431,6 +431,8 @@  choice
 		bool "mbedTLS"
 		depends on HAVE_MBEDTLS
 
+	config SIGALG_GPG
+		bool "GPG signing"
 endchoice
 
 
diff --git a/Makefile.flags b/Makefile.flags
index 2d27a8f..5046a69 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -305,3 +305,8 @@  endif
 # (we stole scripts/checkstack.pl from the kernel... thanks guys!)
 # Reduced from 20k to 16k in 1.9.0.
 FLTFLAGS += -s 16000
+
+ifeq ($(CONFIG_SIGALG_GPG),y)
+LDLIBS += gpgme
+endif
+
diff --git a/corelib/Makefile b/corelib/Makefile
index 5f6f8e9..f5dda73 100644
--- a/corelib/Makefile
+++ b/corelib/Makefile
@@ -32,6 +32,7 @@  endif
 lib-$(CONFIG_SIGALG_RAWRSA)	+= swupdate_rsa_verify_mbedtls.o
 lib-$(CONFIG_SIGALG_RSAPSS)	+= swupdate_rsa_verify_mbedtls.o
 endif
+lib-$(CONFIG_SIGALG_GPG)	+= swupdate_gpg_verify.o
 lib-$(CONFIG_LIBCONFIG)		+= swupdate_settings.o \
 				   parsing_library_libconfig.o
 lib-$(CONFIG_JSON)		+= parsing_library_libjson.o server_utils.o
diff --git a/corelib/swupdate_gpg_verify.c b/corelib/swupdate_gpg_verify.c
new file mode 100644
index 0000000..781c3bc
--- /dev/null
+++ b/corelib/swupdate_gpg_verify.c
@@ -0,0 +1,126 @@ 
+/*
+ * Author: Amy Fong
+ * Copyright (C) 2023, Siemens AG
+ *
+ * SPDX-License-Identifier:     GPL-2.0-only
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "swupdate.h"
+#include "sslapi.h"
+#include "util.h"
+
+#include <errno.h>
+#include <locale.h>
+#include <gpgme.h>
+
+static gpg_error_t
+status_cb(void *opaque, const char *keyword, const char *value)
+{
+	(void)opaque;
+	TRACE("status_cb: %s %s\n", keyword, value);
+	return 0;
+}
+
+int swupdate_verify_file(struct swupdate_digest *dgst, const char *sigfile,
+			 const char *file, const char *signer_name)
+{
+	gpgme_ctx_t ctx;
+	gpgme_error_t err;
+	gpgme_data_t image_sig, image;
+	FILE *fp_sig = NULL;
+	FILE *fp = NULL;
+	gpgme_signature_t sig;
+	char *gpg_home_dir = NULL;
+	int status = 0;
+	gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
+	gpgme_verify_result_t result;
+
+	TRACE("Enter swupdate_verify_file: gpg verify");
+	/* Initialize the locale environment.  */
+	setlocale(LC_ALL, "");
+	(void)gpgme_check_version(NULL);
+
+	err = gpgme_new(&ctx);
+	if (err) {
+		ERROR("Failed to create new gpg context: %s",
+		      gpgme_strerror(err));
+		status = -EFAULT;
+		goto out;
+	}
+
+	gpgme_set_protocol(ctx, protocol);
+	gpgme_set_status_cb(ctx, status_cb, NULL);
+	gpgme_set_ctx_flag(ctx, "full-status", "1");
+
+	fp_sig = fopen(sigfile, "rb");
+	if (!fp_sig) {
+		ERROR("Failed to open %s", sigfile);
+		status = -EBADF;
+		goto out;
+	}
+	err = gpgme_data_new_from_stream(&image_sig, fp_sig);
+	if (err) {
+		ERROR("error allocating data object: %s", gpgme_strerror(err));
+		status = -ENOMEM;
+		goto out;
+	}
+
+	fp = fopen(file, "rb");
+	if (!fp) {
+		ERROR("Failed to open %s", file);
+		status = -EBADF;
+		goto out;
+	}
+	err = gpgme_data_new_from_stream(&image, fp);
+	if (err) {
+		ERROR("error allocating data object: %s", gpgme_strerror(err));
+		status = -ENOMEM;
+		goto out;
+	}
+
+	gpg_home_dir = getenv("GPG_HOMEDIR");
+	if (gpg_home_dir != NULL) {
+		err = gpgme_ctx_set_engine_info(ctx, protocol, NULL, gpg_home_dir);
+		if (err) {
+			ERROR("Something went wrong while setting the engine info: %s",
+			      gpgme_strerror(err));
+			status = -EFAULT;
+			goto out;
+		}
+	}
+
+	err = gpgme_op_verify(ctx, image_sig, image, NULL);
+	result = gpgme_op_verify_result(ctx);
+	if (err) {
+		ERROR("verify failed: %s\n", gpgme_strerror(err));
+		status = -EBADMSG;
+		goto out;
+	}
+
+	if (result) {
+		for (sig = result->signatures; sig; sig = sig->next) {
+			if (sig->status == GPG_ERR_NO_ERROR) {
+				TRACE("Verified OK\n");
+				status = 0;
+				goto out;
+			}
+		}
+	}
+	TRACE(" Verification failed\n");
+	status = -EBADMSG;
+
+ out:
+	gpgme_data_release(image);
+	gpgme_data_release(image_sig);
+	gpgme_release(ctx);
+
+	if (fp)
+		fclose(fp);
+	if (fp_sig)
+		fclose(fp_sig);
+
+	return status;
+}
-- 
2.39.2