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

[PATCH 1/5] Move commit GPG signature verification to commit.c

From
SGSebastian Götte <jaseg@physik.tu-berlin.de>
Date
Mar 25, 2013, 23:46 UTC
Message-ID
<5150E1C7.5000103@physik.tu-berlin.de>
In-Reply-To
<cover.1364254748.git.jaseg@physik-pool.tu-berlin.de>
Signed-off-by: Sebastian Götte <jaseg@physik-pool.tu-berlin.de>
---
 commit.c        | 59 +++++++++++++++++++++++++++++++++++++++++++++
 commit.h        |  9 +++++++
 gpg-interface.h |  8 ++++++
 pretty.c        | 75 ++++-----------------------------------------------------
 4 files changed, 81 insertions(+), 70 deletions(-)
diff --git a/commit.c b/commit.c
index e8eb0ae..1aeb17a 100644
--- a/commit.c
+++ b/commit.c
@@ -1023,6 +1023,65 @@ free_return:
 	free(buf);
 }
 
+static struct {
+	char result;
+	const char *check;
+} signature_check[] = {
+	{ 'G', "\n[GNUPG:] GOODSIG " },
+	{ 'B', "\n[GNUPG:] BADSIG " },
+};
+
+static void parse_signature_lines(struct signature *sig)
+{
+	const char *buf = sig->gpg_status;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(signature_check); i++) {
+		const char *found = strstr(buf, signature_check[i].check);
+		const char *next;
+		if (!found)
+			continue;
+		sig->check_result = signature_check[i].result;
+		found += strlen(signature_check[i].check);
+		sig->key = xmemdupz(found, 16);
+		found += 17;
+		next = strchrnul(found, '\n');
+		sig->signer = xmemdupz(found, next - found);
+		break;
+	}
+}
+
+void check_commit_signature(const struct commit* commit, struct signature *sig)
+{
+	struct strbuf payload = STRBUF_INIT;
+	struct strbuf signature = STRBUF_INIT;
+	struct strbuf gpg_output = STRBUF_INIT;
+	struct strbuf gpg_status = STRBUF_INIT;
+	int status;
+
+	sig->check_result = 'N';
+
+	if (parse_signed_commit(commit->object.sha1,
+				&payload, &signature) <= 0)
+		goto out;
+	status = verify_signed_buffer(payload.buf, payload.len,
+				      signature.buf, signature.len,
+				      &gpg_output, &gpg_status);
+	if (status && !gpg_output.len)
+		goto out;
+	sig->gpg_output = strbuf_detach(&gpg_output, NULL);
+	sig->gpg_status = strbuf_detach(&gpg_status, NULL);
+	parse_signature_lines(sig);
+
+ out:
+	strbuf_release(&gpg_status);
+	strbuf_release(&gpg_output);
+	strbuf_release(&payload);
+	strbuf_release(&signature);
+}
+
+
+
 void append_merge_tag_headers(struct commit_list *parents,
 			      struct commit_extra_header ***tail)
 {
diff --git a/commit.h b/commit.h
index 4138bb4..cf35472 100644
--- a/commit.h
+++ b/commit.h
@@ -5,6 +5,7 @@
 #include "tree.h"
 #include "strbuf.h"
 #include "decorate.h"
+#include "gpg-interface.h"
 
 struct commit_list {
 	struct commit *item;
@@ -230,4 +231,12 @@ extern void print_commit_list(struct commit_list *list,
 			      const char *format_cur,
 			      const char *format_last);
 
+/*
+ * Check the signature of the given commit. The result of the check is stored in
+ * sig->check_result, 'G' for a good signature, 'B' for a bad signature and 'N'
+ * for no signature at all.
+ * This may allocate memory for sig->gpg_output, sig->gpg_status, sig->signer and sig->key.
+ */
+extern void check_commit_signature(const struct commit* commit, struct signature *sig);
+
 #endif /* COMMIT_H */
diff --git a/gpg-interface.h b/gpg-interface.h
index cf99021..2a536d9 100644
--- a/gpg-interface.h
+++ b/gpg-interface.h
@@ -1,6 +1,14 @@
 #ifndef GPG_INTERFACE_H
 #define GPG_INTERFACE_H
 
+struct signature {
+	char *gpg_output;
+	char *gpg_status;
+	char check_result; /* 0 (not checked), N (checked but no further result), G (good) or B (bad) */
+	char *signer;
+	char *key;
+};
+
 extern int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key);
 extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status);
 extern int git_gpg_config(const char *, const char *, void *);
diff --git a/pretty.c b/pretty.c
index b57adef..3aac5d8 100644
--- a/pretty.c
+++ b/pretty.c
@@ -756,14 +756,7 @@ struct format_commit_context {
 	const struct pretty_print_context *pretty_ctx;
 	unsigned commit_header_parsed:1;
 	unsigned commit_message_parsed:1;
-	unsigned commit_signature_parsed:1;
-	struct {
-		char *gpg_output;
-		char *gpg_status;
-		char good_bad;
-		char *signer;
-		char *key;
-	} signature;
+	struct signature signature;
 	char *message;
 	size_t width, indent1, indent2;
 
@@ -946,64 +939,6 @@ static void rewrap_message_tail(struct strbuf *sb,
 	c->indent2 = new_indent2;
 }
 
-static struct {
-	char result;
-	const char *check;
-} signature_check[] = {
-	{ 'G', "\n[GNUPG:] GOODSIG " },
-	{ 'B', "\n[GNUPG:] BADSIG " },
-};
-
-static void parse_signature_lines(struct format_commit_context *ctx)
-{
-	const char *buf = ctx->signature.gpg_status;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(signature_check); i++) {
-		const char *found = strstr(buf, signature_check[i].check);
-		const char *next;
-		if (!found)
-			continue;
-		ctx->signature.good_bad = signature_check[i].result;
-		found += strlen(signature_check[i].check);
-		ctx->signature.key = xmemdupz(found, 16);
-		found += 17;
-		next = strchrnul(found, '\n');
-		ctx->signature.signer = xmemdupz(found, next - found);
-		break;
-	}
-}
-
-static void parse_commit_signature(struct format_commit_context *ctx)
-{
-	struct strbuf payload = STRBUF_INIT;
-	struct strbuf signature = STRBUF_INIT;
-	struct strbuf gpg_output = STRBUF_INIT;
-	struct strbuf gpg_status = STRBUF_INIT;
-	int status;
-
-	ctx->commit_signature_parsed = 1;
-
-	if (parse_signed_commit(ctx->commit->object.sha1,
-				&payload, &signature) <= 0)
-		goto out;
-	status = verify_signed_buffer(payload.buf, payload.len,
-				      signature.buf, signature.len,
-				      &gpg_output, &gpg_status);
-	if (status && !gpg_output.len)
-		goto out;
-	ctx->signature.gpg_output = strbuf_detach(&gpg_output, NULL);
-	ctx->signature.gpg_status = strbuf_detach(&gpg_status, NULL);
-	parse_signature_lines(ctx);
-
- out:
-	strbuf_release(&gpg_status);
-	strbuf_release(&gpg_output);
-	strbuf_release(&payload);
-	strbuf_release(&signature);
-}
-
-
 static int format_reflog_person(struct strbuf *sb,
 				char part,
 				struct reflog_walk_info *log,
@@ -1189,18 +1124,18 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
 	}
 
 	if (placeholder[0] == 'G') {
-		if (!c->commit_signature_parsed)
-			parse_commit_signature(c);
+		if (!c->signature.check_result)
+			check_commit_signature(c->commit, &(c->signature));
 		switch (placeholder[1]) {
 		case 'G':
 			if (c->signature.gpg_output)
 				strbuf_addstr(sb, c->signature.gpg_output);
 			break;
 		case '?':
-			switch (c->signature.good_bad) {
+			switch (c->signature.check_result) {
 			case 'G':
 			case 'B':
-				strbuf_addch(sb, c->signature.good_bad);
+				strbuf_addch(sb, c->signature.check_result);
 			}
 			break;
 		case 'S':
-- 
1.8.1.5
Previous: Sebastian GötteNext: Sebastian Götte
Message 8 of 62 in “Move commit GPG signature verification to commit.c”
  1. 1/4 Move commit GPG signature verification to commit.cSebastian Götte, Mar 23, 2013
  2. Junio C HamanoMar 25, 2013
  3. 0/5 Verify GPG signatures when merging and extend %G? pretty stringSebastian Götte, Mar 25, 2013
  4. Junio C HamanoMar 26, 2013
  5. 0/5 Verify GPG signatures when merging and extend %G? pretty stringSebastian Götte, Mar 26, 2013
  6. Junio C HamanoMar 26, 2013
  7. Sebastian GötteMar 26, 2013
  8. 1/5 Move commit GPG signature verification to commit.cSebastian Götte, Mar 25, 2013
  9. 2/5 commit.c/GPG signature verification: Also look at the first GPG status lineSebastian Götte, Mar 25, 2013
  10. 3/5 merge/pull: verify GPG signatures of commits being mergedSebastian Götte, Mar 25, 2013
  11. 4/5 merge/pull Check for untrusted good GPG signaturesSebastian Götte, Mar 25, 2013
  12. 5/5 pretty printing: extend %G? to include 'N' and 'U'Sebastian Götte, Mar 25, 2013
  13. 1/5 Move commit GPG signature verification to commit.cSebastian Götte, Mar 26, 2013
  14. 2/5 commit.c/GPG signature verification: Also look at the first GPG status lineSebastian Götte, Mar 26, 2013
  15. Junio C HamanoMar 28, 2013
  16. 3/5 merge/pull: verify GPG signatures of commits being mergedSebastian Götte, Mar 26, 2013
  17. Junio C HamanoMar 28, 2013
  18. 0/5 Verify GPG signatures when merging and extend %G? pretty stringSebastian Götte, Mar 30, 2013
  19. 4/5 merge/pull Check for untrusted good GPG signaturesSebastian Götte, Mar 26, 2013
  20. 5/5 pretty printing: extend %G? to include 'N' and 'U'Sebastian Götte, Mar 26, 2013
  21. 1/5 Move commit GPG signature verification to commit.cSebastian Götte, Mar 30, 2013
  22. Junio C HamanoMar 30, 2013
  23. 2/5 commit.c/GPG signature verification: Also look at the first GPG status lineSebastian Götte, Mar 30, 2013
  24. Junio C HamanoMar 30, 2013
  25. 3/5 merge/pull: verify GPG signatures of commits being mergedSebastian Götte, Mar 30, 2013
  26. Junio C HamanoMar 30, 2013
  27. 0/5 Verify GPG signatures when merging and extend %G? pretty stringSebastian Götte, Mar 30, 2013
  28. 4/5 merge/pull Check for untrusted good GPG signaturesSebastian Götte, Mar 30, 2013
  29. Thomas RastMar 31, 2013
  30. Sebastian GötteMar 31, 2013
  31. Thomas RastMar 31, 2013
  32. Sebastian GötteMar 31, 2013
  33. Thomas RastMar 31, 2013
  34. Sebastian GötteMar 31, 2013
  35. John KeepingMar 31, 2013
  36. 0/5 Verify GPG signatures when merging and extend %G? pretty stringSebastian Götte, Mar 31, 2013
  37. 5/5 pretty printing: extend %G? to include 'N' and 'U'Sebastian Götte, Mar 30, 2013
  38. 1/5 Move commit GPG signature verification to commit.cSebastian Götte, Mar 30, 2013
  39. 2/5 commit.c/GPG signature verification: Also look at the first GPG status lineSebastian Götte, Mar 30, 2013
  40. 3/5 merge/pull: verify GPG signatures of commits being mergedSebastian Götte, Mar 30, 2013
  41. 4/5 merge/pull Check for untrusted good GPG signaturesSebastian Götte, Mar 30, 2013
  42. 5/5 pretty printing: extend %G? to include 'N' and 'U'Sebastian Götte, Mar 30, 2013
  43. 1/5 Move commit GPG signature verification to commit.cSebastian Götte, Mar 31, 2013
  44. 2/5 commit.c/GPG signature verification: Also look at the first GPG status lineSebastian Götte, Mar 31, 2013
  45. John KeepingMar 31, 2013
  46. 3/5 merge/pull: verify GPG signatures of commits being mergedSebastian Götte, Mar 31, 2013
  47. 4/5 merge/pull Check for untrusted good GPG signaturesSebastian Götte, Mar 31, 2013
  48. John KeepingMar 31, 2013
  49. Thomas RastMar 31, 2013
  50. Sebastian GötteMar 31, 2013
  51. Thomas RastMar 31, 2013
  52. John KeepingMar 31, 2013
  53. 0/5 Verify GPG signatures when merging and extend %G? pretty stringSebastian Götte, Mar 31, 2013
  54. 5/5 pretty printing: extend %G? to include 'N' and 'U'Sebastian Götte, Mar 31, 2013
  55. 1/5 Move commit GPG signature verification to commit.cSebastian Götte, Mar 31, 2013
  56. 2/5 commit.c/GPG signature verification: Also look at the first GPG status lineSebastian Götte, Mar 31, 2013
  57. 3/5 merge/pull: verify GPG signatures of commits being mergedSebastian Götte, Mar 31, 2013
  58. Junio C HamanoApr 1, 2013
  59. Sebastian GötteApr 1, 2013
  60. Junio C HamanoApr 1, 2013
  61. 4/5 merge/pull Check for untrusted good GPG signaturesSebastian Götte, Mar 31, 2013
  62. 5/5 pretty printing: extend %G? to include 'N' and 'U'Sebastian Götte, Mar 31, 2013

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.