From 26ed995290c4bef8656a8bea3bfb50c1d7c60b7e Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 28 Feb 2024 12:52:21 +0100 Subject: [PATCH] modules/git: Recognize SSH signed tags too Just like commits, tags can be signed with either an OpenPGP, or with an SSH key. While the latter is supported already, SSH-signed tags have not been. This patch teaches the git module to recognize and handle SSH-signed tags too. This will stop the signatures appearing in release notes, but are currently unused otherwise. Signed-off-by: Gergely Nagy --- modules/git/repo_tag.go | 7 ++++++- modules/git/tag.go | 39 ++++++++++++++++++++++++++++++--------- modules/git/tag_test.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go index e8c5ce6fb..eab4ca5a5 100644 --- a/modules/git/repo_tag.go +++ b/modules/git/repo_tag.go @@ -185,10 +185,15 @@ func parseTagRef(ref map[string]string) (tag *Tag, err error) { tag.Tagger = parseSignatureFromCommitLine(ref["creator"]) tag.Message = ref["contents"] - // strip PGP signature if present in contents field + // strip the signature if present in contents field pgpStart := strings.Index(tag.Message, beginpgp) if pgpStart >= 0 { tag.Message = tag.Message[0:pgpStart] + } else { + sshStart := strings.Index(tag.Message, beginssh) + if sshStart >= 0 { + tag.Message = tag.Message[0:sshStart] + } } // annotated tag with GPG signature diff --git a/modules/git/tag.go b/modules/git/tag.go index 94e5cd7c6..66dc9cc08 100644 --- a/modules/git/tag.go +++ b/modules/git/tag.go @@ -14,6 +14,8 @@ import ( const ( beginpgp = "\n-----BEGIN PGP SIGNATURE-----\n" endpgp = "\n-----END PGP SIGNATURE-----" + beginssh = "\n-----BEGIN SSH SIGNATURE-----\n" + endssh = "\n-----END SSH SIGNATURE-----" ) // Tag represents a Git tag. @@ -71,17 +73,36 @@ l: break l } } - idx := strings.LastIndex(tag.Message, beginpgp) - if idx > 0 { - endSigIdx := strings.Index(tag.Message[idx:], endpgp) - if endSigIdx > 0 { - tag.Signature = &CommitGPGSignature{ - Signature: tag.Message[idx+1 : idx+endSigIdx+len(endpgp)], - Payload: string(data[:bytes.LastIndex(data, []byte(beginpgp))+1]), - } - tag.Message = tag.Message[:idx+1] + + extractTagSignature := func(signatureBeginMark, signatureEndMark string) (bool, *CommitGPGSignature, string) { + idx := strings.LastIndex(tag.Message, signatureBeginMark) + if idx == -1 { + return false, nil, "" } + + endSigIdx := strings.Index(tag.Message[idx:], signatureEndMark) + if endSigIdx == -1 { + return false, nil, "" + } + + return true, &CommitGPGSignature{ + Signature: tag.Message[idx+1 : idx+endSigIdx+len(signatureEndMark)], + Payload: string(data[:bytes.LastIndex(data, []byte(signatureBeginMark))+1]), + }, tag.Message[:idx+1] } + + // Try to find an OpenPGP signature + found, sig, message := extractTagSignature(beginpgp, endpgp) + if !found { + // If not found, try an SSH one + found, sig, message = extractTagSignature(beginssh, endssh) + } + // If either is found, update the tag Signature and Message + if found { + tag.Signature = sig + tag.Message = message + } + return tag, nil } diff --git a/modules/git/tag_test.go b/modules/git/tag_test.go index f980b0c56..d71501929 100644 --- a/modules/git/tag_test.go +++ b/modules/git/tag_test.go @@ -46,6 +46,41 @@ ono`), tag: Tag{ Message: "test message\no\n\nono", Signature: nil, }}, + {data: []byte(`object d8d1fdb5b20eaca882e34ee510eb55941a242b24 +type commit +tag v0 +tagger Jane Doe 1709146405 +0100 + +v0 +-----BEGIN SSH SIGNATURE----- +U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgvD4pK7baygXxoWoVoKjVEc/xZh +6w+1FUn5hypFqJXNAAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 +AAAAQKFeTnxi9ssRqSg+sJcmjAgpgoPq1k5SXm306+mJmkPwvhim8f9Gz6uy1AddPmXaD7 +5LVB3fV2GmmFDKGB+wCAo= +-----END SSH SIGNATURE----- +`), tag: Tag{ + Name: "", + ID: Sha1ObjectFormat.EmptyObjectID(), + Object: &Sha1Hash{0xd8, 0xd1, 0xfd, 0xb5, 0xb2, 0x0e, 0xac, 0xa8, 0x82, 0xe3, 0x4e, 0xe5, 0x10, 0xeb, 0x55, 0x94, 0x1a, 0x24, 0x2b, 0x24}, + Type: "commit", + Tagger: &Signature{Name: "Jane Doe", Email: "jane.doe@example.com", When: time.Unix(1709146405, 0)}, + Message: "v0\n", + Signature: &CommitGPGSignature{ + Signature: `-----BEGIN SSH SIGNATURE----- +U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgvD4pK7baygXxoWoVoKjVEc/xZh +6w+1FUn5hypFqJXNAAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 +AAAAQKFeTnxi9ssRqSg+sJcmjAgpgoPq1k5SXm306+mJmkPwvhim8f9Gz6uy1AddPmXaD7 +5LVB3fV2GmmFDKGB+wCAo= +-----END SSH SIGNATURE-----`, + Payload: `object d8d1fdb5b20eaca882e34ee510eb55941a242b24 +type commit +tag v0 +tagger Jane Doe 1709146405 +0100 + +v0 +`, + }, + }}, } for _, test := range testData {