Skip to content

Commit ac1f9bb

Browse files
henning-schildgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c683565 commit ac1f9bb

File tree

1 file changed

+63
-21
lines changed

1 file changed

+63
-21
lines changed

gpg-interface.c

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,46 @@
77
#include "tempfile.h"
88

99
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 **extra_args_verify;
14+
const char **sigs;
15+
};
16+
17+
static const char *openpgp_verify_args[] = { "--keyid-format=long", NULL };
18+
static const char *openpgp_sigs[] = {
19+
"-----BEGIN PGP SIGNATURE-----",
20+
"-----BEGIN PGP MESSAGE-----", NULL };
21+
22+
static struct gpg_format gpg_formats[] = {
23+
{ .name = "openpgp", .program = "gpg",
24+
.extra_args_verify = openpgp_verify_args,
25+
.sigs = openpgp_sigs
26+
},
27+
};
28+
static struct gpg_format *current_format = &gpg_formats[0];
29+
30+
static struct gpg_format *get_format_by_name(const char *str)
31+
{
32+
int i;
33+
34+
for (i = 0; i < ARRAY_SIZE(gpg_formats); i++)
35+
if (!strcasecmp(gpg_formats[i].name, str))
36+
return gpg_formats + i;
37+
return NULL;
38+
}
1239

13-
#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
14-
#define PGP_MESSAGE "-----BEGIN PGP MESSAGE-----"
40+
static struct gpg_format *get_format_by_sig(const char *sig)
41+
{
42+
int i, j;
43+
44+
for (i = 0; i < ARRAY_SIZE(gpg_formats); i++)
45+
for (j = 0; gpg_formats[i].sigs[j]; j++)
46+
if (starts_with(sig, gpg_formats[i].sigs[j]))
47+
return gpg_formats + i;
48+
return NULL;
49+
}
1550

1651
void signature_check_clear(struct signature_check *sigc)
1752
{
@@ -102,20 +137,14 @@ void print_signature_buffer(const struct signature_check *sigc, unsigned flags)
102137
fputs(output, stderr);
103138
}
104139

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-
111140
size_t parse_signature(const char *buf, size_t size)
112141
{
113142
size_t len = 0;
114143
size_t match = size;
115144
while (len < size) {
116145
const char *eol;
117146

118-
if (is_gpg_start(buf + len))
147+
if (get_format_by_sig(buf + len))
119148
match = len;
120149

121150
eol = memchr(buf + len, '\n', size - len);
@@ -132,6 +161,9 @@ void set_signing_key(const char *key)
132161

133162
int git_gpg_config(const char *var, const char *value, void *cb)
134163
{
164+
struct gpg_format *fmt = NULL;
165+
char *fmtname = NULL;
166+
135167
if (!strcmp(var, "user.signingkey")) {
136168
if (!value)
137169
return config_error_nonbool(var);
@@ -140,18 +172,23 @@ int git_gpg_config(const char *var, const char *value, void *cb)
140172
}
141173

142174
if (!strcmp(var, "gpg.format")) {
143-
if (value && strcasecmp(value, "openpgp"))
144-
return error("malformed value for %s: %s", var, value);
145-
return git_config_string(&gpg_format, var, value);
146-
}
147-
148-
if (!strcmp(var, "gpg.program")) {
149175
if (!value)
150176
return config_error_nonbool(var);
151-
gpg_program = xstrdup(value);
177+
fmt = get_format_by_name(value);
178+
if (!fmt)
179+
return error("malformed value for %s: %s", var, value);
180+
current_format = fmt;
152181
return 0;
153182
}
154183

184+
if (!strcmp(var, "gpg.program"))
185+
fmtname = "openpgp";
186+
187+
if (fmtname) {
188+
fmt = get_format_by_name(fmtname);
189+
return git_config_string(&fmt->program, var, value);
190+
}
191+
155192
return 0;
156193
}
157194

@@ -170,7 +207,7 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
170207
struct strbuf gpg_status = STRBUF_INIT;
171208

172209
argv_array_pushl(&gpg.args,
173-
gpg_program,
210+
current_format->program,
174211
"--status-fd=2",
175212
"-bsau", signing_key,
176213
NULL);
@@ -208,6 +245,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
208245
struct strbuf *gpg_output, struct strbuf *gpg_status)
209246
{
210247
struct child_process gpg = CHILD_PROCESS_INIT;
248+
struct gpg_format *fmt;
211249
struct tempfile *temp;
212250
int ret;
213251
struct strbuf buf = STRBUF_INIT;
@@ -223,10 +261,14 @@ int verify_signed_buffer(const char *payload, size_t payload_size,
223261
return -1;
224262
}
225263

264+
fmt = get_format_by_sig(signature);
265+
if (!fmt)
266+
BUG("bad signature '%s'", signature);
267+
268+
argv_array_push(&gpg.args, fmt->program);
269+
argv_array_pushv(&gpg.args, fmt->extra_args_verify);
226270
argv_array_pushl(&gpg.args,
227-
gpg_program,
228271
"--status-fd=1",
229-
"--keyid-format=long",
230272
"--verify", temp->filename.buf, "-",
231273
NULL);
232274

0 commit comments

Comments
 (0)