gpg-interface: introduce an abstraction for multiple gpg formats
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Henning Schild committed
Jul 17, 2018 at 14:50 UTC
58af57e1c886a7c9fed7fb35f2dd8dd14cc5e4e0
1 file changed
+67
-21
gpg-interface.c
+67
-21
@@ -7,11 +7,52 @@
7
#include "tempfile.h"
8
9
static char *configured_signing_key;
10
-static const char *gpg_format = "openpgp";
11
-static const char *gpg_program = "gpg";
10
+struct gpg_format {
11
+ const char *name;
12
+ const char *program;
13
+ const char **verify_args;
14
+ const char **sigs;
15
+};
16
+
17
+static const char *openpgp_verify_args[] = {
18
+ "--keyid-format=long",
19
+ NULL
20
+};
21
+static const char *openpgp_sigs[] = {
22
+ "-----BEGIN PGP SIGNATURE-----",
23
+ "-----BEGIN PGP MESSAGE-----",
24
+ NULL
25
+};
26
+
27
+static struct gpg_format gpg_format[] = {
28
+ { .name = "openpgp", .program = "gpg",
29
+ .verify_args = openpgp_verify_args,
30
+ .sigs = openpgp_sigs
31
+ },
32
+};
33
+
34
+static struct gpg_format *use_format = &gpg_format[0];
35
13
-#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
14
-#define PGP_MESSAGE "-----BEGIN PGP MESSAGE-----"
36
+static struct gpg_format *get_format_by_name(const char *str)
37
+{
38
+ int i;
39
+
40
+ for (i = 0; i < ARRAY_SIZE(gpg_format); i++)
41
+ if (!strcmp(gpg_format[i].name, str))
42
+ return gpg_format + i;
43
+ return NULL;
44
+}
45
+
46
+static struct gpg_format *get_format_by_sig(const char *sig)
47
+{
48
+ int i, j;
49
+
50
+ for (i = 0; i < ARRAY_SIZE(gpg_format); i++)
51
+ for (j = 0; gpg_format[i].sigs[j]; j++)
52
+ if (starts_with(sig, gpg_format[i].sigs[j]))
53
+ return gpg_format + i;
54
+ return NULL;
55
+}
56
57
void signature_check_clear(struct signature_check *sigc)
58
{
@@ -102,12 +143,6 @@ void print_signature_buffer(const struct signature_check *sigc, unsigned flags)
143
fputs(output, stderr);
144
}
145
105
-static int is_gpg_start(const char *line)
106
-{
107
- return starts_with(line, PGP_SIGNATURE) ||
108
- starts_with(line, PGP_MESSAGE);
109
-}
110
-
146
size_t parse_signature(const char *buf, size_t size)
147
{
148
size_t len = 0;
@@ -115,7 +150,7 @@ size_t parse_signature(const char *buf, size_t size)
150
while (len < size) {
151
const char *eol;
152
118
- if (is_gpg_start(buf + len))
153
+ if (get_format_by_sig(buf + len))
154
match = len;
155
156
eol = memchr(buf + len, '\n', size - len);
@@ -132,6 +167,9 @@ void set_signing_key(const char *key)
167
168
int git_gpg_config(const char *var, const char *value, void *cb)
169
{
170
+ struct gpg_format *fmt = NULL;
171
+ char *fmtname = NULL;
172
+
173
if (!strcmp(var, "user.signingkey")) {
174
if (!value)
175
return config_error_nonbool(var);
@@ -142,17 +180,20 @@ int git_gpg_config(const char *var, const char *value, void *cb)
180
if (!strcmp(var, "gpg.format")) {
181
if (!value)
182
return config_error_nonbool(var);
145
- if (strcmp(value, "openpgp"))
183
+ fmt = get_format_by_name(value);
184
+ if (!fmt)
185
return error("unsupported value for %s: %s",
186
var, value);
148
- return git_config_string(&gpg_format, var, value);
187
+ use_format = fmt;
188
+ return 0;
189
}
190
151
- if (!strcmp(var, "gpg.program")) {
152
- if (!value)
153
- return config_error_nonbool(var);
154
- gpg_program = xstrdup(value);
155
- return 0;
191
+ if (!strcmp(var, "gpg.program"))
192
+ fmtname = "openpgp";
193
+
194
+ if (fmtname) {
195
+ fmt = get_format_by_name(fmtname);
196
+ return git_config_string(&fmt->program, var, value);
197
}
198
199
return 0;
@@ -173,7 +214,7 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
214
struct strbuf gpg_status = STRBUF_INIT;
215
216
argv_array_pushl(&gpg.args,
176
- gpg_program,
217
+ use_format->program,
218
"--status-fd=2",
219
"-bsau", signing_key,
220
NULL);
@@ -211,6 +252,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
252
struct strbuf *gpg_output, struct strbuf *gpg_status)
253
{
254
struct child_process gpg = CHILD_PROCESS_INIT;
255
+ struct gpg_format *fmt;
256
struct tempfile *temp;
257
int ret;
258
struct strbuf buf = STRBUF_INIT;
@@ -226,10 +268,14 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
268
return -1;
269
}
270
271
+ fmt = get_format_by_sig(signature);
272
+ if (!fmt)
273
+ BUG("bad signature '%s'", signature);
274
+
275
+ argv_array_push(&gpg.args, fmt->program);
276
+ argv_array_pushv(&gpg.args, fmt->verify_args);
277
argv_array_pushl(&gpg.args,
230
- gpg_program,
278
"--status-fd=1",
232
- "--keyid-format=long",
279
"--verify", temp->filename.buf, "-",
280
NULL);
281