@@ -17,13 +17,12 @@ limitations under the License.
1717package git
1818
1919import (
20- "bytes"
2120 "errors"
2221 "fmt"
2322 "strings"
2423 "time"
2524
26- "github.com/ProtonMail/go-crypto/openpgp "
25+ "github.com/fluxcd/pkg/git/signatures "
2726)
2827
2928const (
@@ -113,19 +112,38 @@ func (c *Commit) AbsoluteReference() string {
113112 return c .Hash .Digest ()
114113}
115114
115+ // wrapper function to ensure backwards compatibility
116+ func (c * Commit ) Verify (keyRings ... string ) (string , error ) {
117+ return c .VerifyGPG (keyRings ... )
118+ }
119+
116120// Verify the Signature of the commit with the given key rings.
117121// It returns the fingerprint of the key the signature was verified
118122// with, or an error. It does not verify the signature of the referencing
119123// tag (if present). Users are expected to explicitly verify the referencing
120124// tag's signature using `c.ReferencingTag.Verify()`
121- func (c * Commit ) Verify (keyRings ... string ) (string , error ) {
122- fingerprint , err := verifySignature (c .Signature , c .Encoded , keyRings ... )
125+ func (c * Commit ) VerifyGPG (keyRings ... string ) (string , error ) {
126+ fingerprint , err := signatures . VerifyPGPSignature (c .Signature , c .Encoded , keyRings ... )
123127 if err != nil {
124128 return "" , fmt .Errorf ("unable to verify Git commit: %w" , err )
125129 }
126130 return fingerprint , nil
127131}
128132
133+ // VerifySSH verifies the SSH signature of the commit with the given authorized keys.
134+ // It returns the fingerprint of the key the signature was verified with, or an error.
135+ // It does not verify the signature of the referencing tag (if present). Users are
136+ // expected to explicitly verify the referencing tag's signature using `c.ReferencingTag.VerifySSH()`
137+ func (c * Commit ) VerifySSH (authorizedKeys ... string ) (string , error ) {
138+ // The Encoded field already contains the commit data without the signature
139+ // (it was encoded using EncodeWithoutSignature in BuildCommitWithRef)
140+ fingerprint , err := signatures .VerifySSHSignature (c .Signature , c .Encoded , authorizedKeys ... )
141+ if err != nil {
142+ return "" , fmt .Errorf ("unable to verify Git commit SSH signature: %w" , err )
143+ }
144+ return fingerprint , nil
145+ }
146+
129147// ShortMessage returns the first 50 characters of a commit subject.
130148func (c * Commit ) ShortMessage () string {
131149 subject := strings .Split (c .Message , "\n " )[0 ]
@@ -152,17 +170,34 @@ type Tag struct {
152170 Message string
153171}
154172
173+ // wrapper function to ensure backwards compatibility
174+ func (t * Tag ) Verify (keyRings ... string ) (string , error ) {
175+ return t .VerifyGPG (keyRings ... )
176+ }
177+
155178// Verify the Signature of the tag with the given key rings.
156179// It returns the fingerprint of the key the signature was verified
157180// with, or an error.
158- func (t * Tag ) Verify (keyRings ... string ) (string , error ) {
159- fingerprint , err := verifySignature (t .Signature , t .Encoded , keyRings ... )
181+ func (t * Tag ) VerifyGPG (keyRings ... string ) (string , error ) {
182+ fingerprint , err := signatures . VerifyPGPSignature (t .Signature , t .Encoded , keyRings ... )
160183 if err != nil {
161184 return "" , fmt .Errorf ("unable to verify Git tag: %w" , err )
162185 }
163186 return fingerprint , nil
164187}
165188
189+ // VerifySSH verifies the SSH signature of the tag with the given authorized keys.
190+ // It returns the fingerprint of the key the signature was verified with, or an error.
191+ func (t * Tag ) VerifySSH (authorizedKeys ... string ) (string , error ) {
192+ // The Encoded field already contains the tag data without the signature
193+ // (it was encoded using EncodeWithoutSignature in BuildCommitWithRef)
194+ fingerprint , err := signatures .VerifySSHSignature (t .Signature , t .Encoded , authorizedKeys ... )
195+ if err != nil {
196+ return "" , fmt .Errorf ("unable to verify Git tag SSH signature: %w" , err )
197+ }
198+ return fingerprint , nil
199+ }
200+
166201// String returns a short string representation of the tag in the format
167202// of <name@hash>, for eg: "1.0.0@a0c14dc8580a23f79bc654faa79c4f62b46c2c22"
168203// If the tag is lightweight, it won't have a hash, so it'll simply return
@@ -210,21 +245,36 @@ func IsSignedTag(t Tag) bool {
210245 return t .Signature != ""
211246}
212247
213- func verifySignature ( sig string , payload [] byte , keyRings ... string ) ( string , error ) {
214- if sig == "" {
215- return "" , fmt . Errorf ( "unable to verify payload as the provided signature is empty" )
216- }
248+ // IsPGPSigned returns true if the commit has a PGP signature.
249+ func ( c * Commit ) IsPGPSigned () bool {
250+ return signatures . IsPGPSignature ( c . Signature )
251+ }
217252
218- for _ , r := range keyRings {
219- reader := strings .NewReader (r )
220- keyring , err := openpgp .ReadArmoredKeyRing (reader )
221- if err != nil {
222- return "" , fmt .Errorf ("unable to read armored key ring: %w" , err )
223- }
224- signer , err := openpgp .CheckArmoredDetachedSignature (keyring , bytes .NewBuffer (payload ), bytes .NewBufferString (sig ), nil )
225- if err == nil {
226- return signer .PrimaryKey .KeyIdString (), nil
227- }
228- }
229- return "" , fmt .Errorf ("unable to verify payload with any of the given key rings" )
253+ // IsSSHSigned returns true if the commit has an SSH signature.
254+ func (c * Commit ) IsSSHSigned () bool {
255+ return signatures .IsSSHSignature (c .Signature )
256+ }
257+
258+ // SignatureType returns the type of the commit signature as a string.
259+ // It returns "pgp" for PGP signatures, "ssh" for SSH signatures,
260+ // and "unknown" for unrecognized or empty signatures.
261+ func (c * Commit ) SignatureType () string {
262+ return signatures .GetSignatureType (c .Signature )
263+ }
264+
265+ // IsPGPSigned returns true if the tag has a PGP signature.
266+ func (t * Tag ) IsPGPSigned () bool {
267+ return signatures .IsPGPSignature (t .Signature )
268+ }
269+
270+ // IsSSHSigned returns true if the tag has an SSH signature.
271+ func (t * Tag ) IsSSHSigned () bool {
272+ return signatures .IsSSHSignature (t .Signature )
273+ }
274+
275+ // SignatureType returns the type of the tag signature as a string.
276+ // It returns "pgp" for PGP signatures, "ssh" for SSH signatures,
277+ // and "unknown" for unrecognized or empty signatures.
278+ func (t * Tag ) SignatureType () string {
279+ return signatures .GetSignatureType (t .Signature )
230280}
0 commit comments