summaryrefslogtreecommitdiff
path: root/src/commit.c
diff options
context:
space:
mode:
authorVicent Marti <vicent@github.com>2016-02-09 16:26:58 +0100
committerVicent Marti <vicent@github.com>2016-02-09 16:26:58 +0100
commit488e2b85053a45dd2ce6a37b7d5cf70870be5ed8 (patch)
treeabcf704a4e39050de039bd8fb2b4c7636fc69c51 /src/commit.c
parent534cc5a3cbd301c709c1091a3dd9924ea52542cb (diff)
parenta65afb757e2675eb8889a9ce1f8809434cdb3af7 (diff)
downloadlibgit2-488e2b85053a45dd2ce6a37b7d5cf70870be5ed8.tar.gz
Merge pull request #3599 from libgit2/gpgsign
Introduce git_commit_extract_signature
Diffstat (limited to 'src/commit.c')
-rw-r--r--src/commit.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/commit.c b/src/commit.c
index 87301e0da..453506d2f 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -621,3 +621,89 @@ oom:
giterr_set_oom();
return -1;
}
+
+int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_repository *repo, git_oid *commit_id, const char *field)
+{
+ git_odb_object *obj;
+ git_odb *odb;
+ const char *buf;
+ const char *h, *eol;
+ int error;
+
+ git_buf_sanitize(signature);
+ git_buf_sanitize(signed_data);
+
+ if (!field)
+ field = "gpgsig";
+
+ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
+ return error;
+
+ if ((error = git_odb_read(&obj, odb, commit_id)) < 0)
+ return error;
+
+ buf = git_odb_object_data(obj);
+
+ while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') {
+ h++;
+ if (git__prefixcmp(buf, field)) {
+ if (git_buf_put(signed_data, buf, h - buf) < 0)
+ return -1;
+
+ buf = h;
+ continue;
+ }
+
+ h = buf;
+ h += strlen(field);
+ eol = strchr(h, '\n');
+ if (h[0] != ' ') {
+ buf = h;
+ continue;
+ }
+ if (!eol)
+ goto malformed;
+
+ h++; /* skip the SP */
+
+ git_buf_put(signature, h, eol - h);
+ if (git_buf_oom(signature))
+ goto oom;
+
+ /* If the next line starts with SP, it's multi-line, we must continue */
+ while (eol[1] == ' ') {
+ git_buf_putc(signature, '\n');
+ h = eol + 2;
+ eol = strchr(h, '\n');
+ if (!eol)
+ goto malformed;
+
+ git_buf_put(signature, h, eol - h);
+ }
+
+ if (git_buf_oom(signature))
+ goto oom;
+
+ git_odb_object_free(obj);
+ return git_buf_puts(signed_data, eol+1);
+ }
+
+ giterr_set(GITERR_INVALID, "this commit is not signed");
+ error = GIT_ENOTFOUND;
+ goto cleanup;
+
+malformed:
+ giterr_set(GITERR_OBJECT, "malformed header");
+ error = -1;
+ goto cleanup;
+oom:
+ giterr_set_oom();
+ error = -1;
+ goto cleanup;
+
+cleanup:
+ git_odb_object_free(obj);
+ git_buf_clear(signature);
+ git_buf_clear(signed_data);
+ return error;
+}