git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 3/7] gpg-interface: introduce an abstraction for multiple gpg formats

From
Henning Schild <henning.schild@siemens.com>
Date
Jul 13, 2018, 08:41 UTC
Message-ID
<38e2eb70233709aa73345d64c94d59d4ccc681ec.1531470729.git.henning.schild@siemens.com>
In-Reply-To
<cover.1531470729.git.henning.schild@siemens.com>

Create a struct that holds the format details for the supported formats. At the moment that is still just "openpgp". This commit prepares for the introduction of more formats, that might use other programs and match other signatures.

Signed-off-by: Henning Schild <henning.schild@siemens.com>
---
 gpg-interface.c | 84 ++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 63 insertions(+), 21 deletions(-)
diff --git a/gpg-interface.c b/gpg-interface.c
index 960c40086..699651fd9 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -7,11 +7,46 @@
 #include "tempfile.h"
 
 static char *configured_signing_key;
-static const char *gpg_format = "openpgp";
-static const char *gpg_program = "gpg";
+struct gpg_format {
+	const char *name;
+	const char *program;
+	const char **extra_args_verify;
+	const char **sigs;
+};
+
+static const char *openpgp_verify_args[] = { "--keyid-format=long", NULL };
+static const char *openpgp_sigs[] = {
+	"-----BEGIN PGP SIGNATURE-----",
+	"-----BEGIN PGP MESSAGE-----", NULL };
+
+static struct gpg_format gpg_formats[] = {
+	{ .name = "openpgp", .program = "gpg",
+	  .extra_args_verify = openpgp_verify_args,
+	  .sigs = openpgp_sigs
+	},
+};
+static struct gpg_format *current_format = &gpg_formats[0];
+
+static struct gpg_format *get_format_by_name(const char *str)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(gpg_formats); i++)
+		if (!strcasecmp(gpg_formats[i].name, str))
+			return gpg_formats + i;
+	return NULL;
+}
 
-#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
-#define PGP_MESSAGE "-----BEGIN PGP MESSAGE-----"
+static struct gpg_format *get_format_by_sig(const char *sig)
+{
+	int i, j;
+
+	for (i = 0; i < ARRAY_SIZE(gpg_formats); i++)
+		for (j = 0; gpg_formats[i].sigs[j]; j++)
+			if (starts_with(sig, gpg_formats[i].sigs[j]))
+				return gpg_formats + i;
+	return NULL;
+}
 
 void signature_check_clear(struct signature_check *sigc)
 {
@@ -102,12 +137,6 @@ void print_signature_buffer(const struct signature_check *sigc, unsigned flags)
 		fputs(output, stderr);
 }
 
-static int is_gpg_start(const char *line)
-{
-	return starts_with(line, PGP_SIGNATURE) ||
-		starts_with(line, PGP_MESSAGE);
-}
-
 size_t parse_signature(const char *buf, size_t size)
 {
 	size_t len = 0;
@@ -115,7 +144,7 @@ size_t parse_signature(const char *buf, size_t size)
 	while (len < size) {
 		const char *eol;
 
-		if (is_gpg_start(buf + len))
+		if (get_format_by_sig(buf + len))
 			match = len;
 
 		eol = memchr(buf + len, '\n', size - len);
@@ -132,6 +161,9 @@ void set_signing_key(const char *key)
 
 int git_gpg_config(const char *var, const char *value, void *cb)
 {
+	struct gpg_format *fmt = NULL;
+	char *fmtname = NULL;
+
 	if (!strcmp(var, "user.signingkey")) {
 		if (!value)
 			return config_error_nonbool(var);
@@ -140,18 +172,23 @@ int git_gpg_config(const char *var, const char *value, void *cb)
 	}
 
 	if (!strcmp(var, "gpg.format")) {
-		if (value && strcasecmp(value, "openpgp"))
-			return error("malformed value for %s: %s", var, value);
-		return git_config_string(&gpg_format, var, value);
-	}
-
-	if (!strcmp(var, "gpg.program")) {
 		if (!value)
 			return config_error_nonbool(var);
-		gpg_program = xstrdup(value);
+		fmt = get_format_by_name(value);
+		if (!fmt)
+			return error("malformed value for %s: %s", var, value);
+		current_format = fmt;
 		return 0;
 	}
 
+	if (!strcmp(var, "gpg.program"))
+		fmtname = "openpgp";
+
+	if (fmtname) {
+		fmt = get_format_by_name(fmtname);
+		return git_config_string(&fmt->program, var, value);
+	}
+
 	return 0;
 }
 
@@ -170,7 +207,7 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
 	struct strbuf gpg_status = STRBUF_INIT;
 
 	argv_array_pushl(&gpg.args,
-			 gpg_program,
+			 current_format->program,
 			 "--status-fd=2",
 			 "-bsau", signing_key,
 			 NULL);
@@ -208,6 +245,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
 			 struct strbuf *gpg_output, struct strbuf *gpg_status)
 {
 	struct child_process gpg = CHILD_PROCESS_INIT;
+	struct gpg_format *fmt;
 	struct tempfile *temp;
 	int ret;
 	struct strbuf buf = STRBUF_INIT;
@@ -223,10 +261,14 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
 		return -1;
 	}
 
+	fmt = get_format_by_sig(signature);
+	if (!fmt)
+		BUG("bad signature '%s'", signature);
+
+	argv_array_push(&gpg.args, fmt->program);
+	argv_array_pushv(&gpg.args, fmt->extra_args_verify);
 	argv_array_pushl(&gpg.args,
-			 gpg_program,
 			 "--status-fd=1",
-			 "--keyid-format=long",
 			 "--verify", temp->filename.buf, "-",
 			 NULL);
 
-- 
2.16.4
Previous: Junio C HamanoNext: Junio C Hamano
Message 12 of 19 in “X509 (gpgsm) commit signing support”
  1. 0/7 X509 (gpgsm) commit signing supportHenning Schild, Jul 13, 2018
  2. 2/7 t/t7510: check the validation of the new config gpg.formatHenning Schild, Jul 13, 2018
  3. Junio C HamanoJul 16, 2018
  4. 1/7 gpg-interface: add new config to select how to sign a commitHenning Schild, Jul 13, 2018
  5. Junio C HamanoJul 16, 2018
  6. Jeff KingJul 16, 2018
  7. Henning SchildJul 17, 2018
  8. brian m. carlsonJul 17, 2018
  9. Jeff KingJul 17, 2018
  10. 4/7 gpg-interface: do not hardcode the key string len anymoreHenning Schild, Jul 13, 2018
  11. Junio C HamanoJul 16, 2018
  12. 3/7 gpg-interface: introduce an abstraction for multiple gpg formatsHenning Schild, Jul 13, 2018
  13. Junio C HamanoJul 16, 2018
  14. Henning SchildJul 17, 2018
  15. 5/7 gpg-interface: introduce new config to select per gpg format programHenning Schild, Jul 13, 2018
  16. Junio C HamanoJul 16, 2018
  17. Henning SchildJul 17, 2018
  18. 6/7 gpg-interface: introduce new signature format "x509" using gpgsmHenning Schild, Jul 13, 2018
  19. 7/7 gpg-interface t: extend the existing GPG tests with GPGSMHenning Schild, Jul 13, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.