Skip to content

Commit 867386d

Browse files
ebiedermgitster
authored andcommitted
tag: sign both hashes
When we write a tag the object oid is specific to the hash algorithm. This matters when a tag is signed. The hash transition plan calls for signatures on both the sha1 form and the sha256 form of the object, and for both of those signatures to live in the tag object. To generate tag object with multiple signatures, first compute the unsigned form of the tag, and then if the tag is being signed compute the unsigned form of the tag with the compatibilityr hash. Then compute compute the signatures of both buffers. Once the signatures are computed add them to both buffers. This allows computing the compatibility hash in do_sign, saving write_object_file the expense of recomputing the compatibility tag just to compute it's hash. Signed-off-by: Eric W. Biederman <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6bcc5fa commit 867386d

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

builtin/tag.c

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "ref-filter.h"
2929
#include "date.h"
3030
#include "write-or-die.h"
31+
#include "object-file-convert.h"
3132

3233
static const char * const git_tag_usage[] = {
3334
N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
@@ -174,9 +175,43 @@ static int verify_tag(const char *name, const char *ref UNUSED,
174175
return 0;
175176
}
176177

177-
static int do_sign(struct strbuf *buffer)
178+
static int do_sign(struct strbuf *buffer, struct object_id **compat_oid,
179+
struct object_id *compat_oid_buf)
178180
{
179-
return sign_buffer(buffer, buffer, get_signing_key());
181+
const struct git_hash_algo *compat = the_repository->compat_hash_algo;
182+
struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT;
183+
struct strbuf compat_buf = STRBUF_INIT;
184+
const char *keyid = get_signing_key();
185+
int ret = -1;
186+
187+
if (sign_buffer(buffer, &sig, keyid))
188+
return -1;
189+
190+
if (compat) {
191+
const struct git_hash_algo *algo = the_repository->hash_algo;
192+
193+
if (convert_object_file(&compat_buf, algo, compat,
194+
buffer->buf, buffer->len, OBJ_TAG, 1))
195+
goto out;
196+
if (sign_buffer(&compat_buf, &compat_sig, keyid))
197+
goto out;
198+
add_header_signature(&compat_buf, &sig, algo);
199+
strbuf_addbuf(&compat_buf, &compat_sig);
200+
hash_object_file(compat, compat_buf.buf, compat_buf.len,
201+
OBJ_TAG, compat_oid_buf);
202+
*compat_oid = compat_oid_buf;
203+
}
204+
205+
if (compat_sig.len)
206+
add_header_signature(buffer, &compat_sig, compat);
207+
208+
strbuf_addbuf(buffer, &sig);
209+
ret = 0;
210+
out:
211+
strbuf_release(&sig);
212+
strbuf_release(&compat_sig);
213+
strbuf_release(&compat_buf);
214+
return ret;
180215
}
181216

182217
static const char tag_template[] =
@@ -249,9 +284,11 @@ static void write_tag_body(int fd, const struct object_id *oid)
249284

250285
static int build_tag_object(struct strbuf *buf, int sign, struct object_id *result)
251286
{
252-
if (sign && do_sign(buf) < 0)
287+
struct object_id *compat_oid = NULL, compat_oid_buf;
288+
if (sign && do_sign(buf, &compat_oid, &compat_oid_buf) < 0)
253289
return error(_("unable to sign the tag"));
254-
if (write_object_file(buf->buf, buf->len, OBJ_TAG, result) < 0)
290+
if (write_object_file_flags(buf->buf, buf->len, OBJ_TAG, result,
291+
compat_oid, 0) < 0)
255292
return error(_("unable to write tag file"));
256293
return 0;
257294
}

0 commit comments

Comments
 (0)