@@ -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/signature "
2726)
2827
2928const (
@@ -81,7 +80,7 @@ type Commit struct {
8180 // Committer is the one performing the commit, might be different from
8281 // Author.
8382 Committer Signature
84- // Signature is the PGP signature of the commit.
83+ // Signature is the cryptographic signature of the commit (PGP or SSH) .
8584 Signature string
8685 // Encoded is the encoded commit, without any signature.
8786 Encoded []byte
@@ -113,16 +112,47 @@ func (c *Commit) AbsoluteReference() string {
113112 return c .Hash .Digest ()
114113}
115114
116- // Verify the Signature of the commit with the given key rings.
117- // It returns the fingerprint of the key the signature was verified
118- // with, or an error. It does not verify the signature of the referencing
119- // tag (if present). Users are expected to explicitly verify the referencing
120- // tag's signature using `c.ReferencingTag.Verify()`
115+ // Verify the PGP signature of the commit with the given key rings. It
116+ // returns the key ID of the openPGP key the signature was verified with,
117+ // or an error. It does not verify the signature of the referencing tag
118+ // (if present); users are expected to explicitly verify the referencing
119+ // tag's signature using c.ReferencingTag.VerifyPGP.
120+ //
121+ // Verify only handles PGP signatures. If the commit is SSH-signed, the
122+ // call will fail with a signature.ErrSignatureFormat error wrapped in
123+ // the returned chain; callers should use [Commit.VerifySSH] for SSH
124+ // signatures.
125+ //
126+ // Deprecated: use [Commit.VerifyPGP] for PGP signatures, or
127+ // [Commit.VerifySSH] for SSH signatures.
121128func (c * Commit ) Verify (keyRings ... string ) (string , error ) {
122- fingerprint , err := verifySignature (c .Signature , c .Encoded , keyRings ... )
129+ return c .VerifyPGP (keyRings ... )
130+ }
131+
132+ // VerifyPGP verifies the PGP signature of the commit with the given key
133+ // rings. It returns the key ID of the openPGP key the signature was
134+ // verified with, or an error. It does not verify the signature of the
135+ // referencing tag (if present); users are expected to explicitly verify
136+ // the referencing tag's signature using c.ReferencingTag.VerifyPGP.
137+ func (c * Commit ) VerifyPGP (keyRings ... string ) (string , error ) {
138+ keyID , err := signature .VerifyPGPSignature (c .Signature , c .Encoded , keyRings ... )
123139 if err != nil {
124140 return "" , fmt .Errorf ("unable to verify Git commit: %w" , err )
125141 }
142+ return keyID , nil
143+ }
144+
145+ // VerifySSH verifies the SSH signature of the commit with the given
146+ // authorized keys. It returns the SHA256 fingerprint of the SSH key the
147+ // signature was verified with, or an error. It does not verify the
148+ // signature of the referencing tag (if present); users are expected to
149+ // explicitly verify the referencing tag's signature using
150+ // c.ReferencingTag.VerifySSH.
151+ func (c * Commit ) VerifySSH (authorizedKeys ... string ) (string , error ) {
152+ fingerprint , err := signature .VerifySSHSignature (c .Signature , c .Encoded , authorizedKeys ... )
153+ if err != nil {
154+ return "" , fmt .Errorf ("unable to verify Git commit SSH signature: %w" , err )
155+ }
126156 return fingerprint , nil
127157}
128158
@@ -144,22 +174,47 @@ type Tag struct {
144174 Name string
145175 // Author is the original author of the tag.
146176 Author Signature
147- // Signature is the PGP signature of the tag.
177+ // Signature is the cryptographic signature of the tag (PGP or SSH) .
148178 Signature string
149179 // Encoded is the encoded tag, without any signature.
150180 Encoded []byte
151181 // Message is the tag message, containing arbitrary text.
152182 Message string
153183}
154184
155- // Verify the Signature of the tag with the given key rings.
156- // It returns the fingerprint of the key the signature was verified
157- // with, or an error.
185+ // Verify the PGP signature of the tag with the given key rings. It
186+ // returns the key ID of the openPGP key the signature was verified with,
187+ // or an error.
188+ //
189+ // Verify only handles PGP signatures. If the tag is SSH-signed, the call
190+ // will fail with a signature.ErrSignatureFormat error wrapped in the
191+ // returned chain; callers should use [Tag.VerifySSH] for SSH signatures.
192+ //
193+ // Deprecated: use [Tag.VerifyPGP] for PGP signatures, or [Tag.VerifySSH]
194+ // for SSH signatures.
158195func (t * Tag ) Verify (keyRings ... string ) (string , error ) {
159- fingerprint , err := verifySignature (t .Signature , t .Encoded , keyRings ... )
196+ return t .VerifyPGP (keyRings ... )
197+ }
198+
199+ // VerifyPGP verifies the PGP signature of the tag with the given key
200+ // rings. It returns the key ID of the openPGP key the signature was
201+ // verified with, or an error.
202+ func (t * Tag ) VerifyPGP (keyRings ... string ) (string , error ) {
203+ keyID , err := signature .VerifyPGPSignature (t .Signature , t .Encoded , keyRings ... )
160204 if err != nil {
161205 return "" , fmt .Errorf ("unable to verify Git tag: %w" , err )
162206 }
207+ return keyID , nil
208+ }
209+
210+ // VerifySSH verifies the SSH signature of the tag with the given
211+ // authorized keys. It returns the SHA256 fingerprint of the SSH key the
212+ // signature was verified with, or an error.
213+ func (t * Tag ) VerifySSH (authorizedKeys ... string ) (string , error ) {
214+ fingerprint , err := signature .VerifySSHSignature (t .Signature , t .Encoded , authorizedKeys ... )
215+ if err != nil {
216+ return "" , fmt .Errorf ("unable to verify Git tag SSH signature: %w" , err )
217+ }
163218 return fingerprint , nil
164219}
165220
@@ -210,21 +265,38 @@ func IsSignedTag(t Tag) bool {
210265 return t .Signature != ""
211266}
212267
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- }
268+ // IsPGPSigned returns true if the commit has a PGP signature.
269+ func ( c * Commit ) IsPGPSigned () bool {
270+ return signature . IsPGPSignature ( c . Signature )
271+ }
217272
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" )
273+ // IsSSHSigned returns true if the commit has an SSH signature.
274+ func (c * Commit ) IsSSHSigned () bool {
275+ return signature .IsSSHSignature (c .Signature )
276+ }
277+
278+ // SignatureType returns the type of the commit signature as a string:
279+ // "openpgp" for PGP signatures, "ssh" for SSH signatures, "x509" for
280+ // S/MIME signatures, "empty" for an absent signature, and "unknown"
281+ // for an unrecognised one.
282+ func (c * Commit ) SignatureType () string {
283+ return signature .GetSignatureType (c .Signature )
284+ }
285+
286+ // IsPGPSigned returns true if the tag has a PGP signature.
287+ func (t * Tag ) IsPGPSigned () bool {
288+ return signature .IsPGPSignature (t .Signature )
289+ }
290+
291+ // IsSSHSigned returns true if the tag has an SSH signature.
292+ func (t * Tag ) IsSSHSigned () bool {
293+ return signature .IsSSHSignature (t .Signature )
294+ }
295+
296+ // SignatureType returns the type of the tag signature as a string:
297+ // "openpgp" for PGP signatures, "ssh" for SSH signatures, "x509" for
298+ // S/MIME signatures, "empty" for an absent signature, and "unknown"
299+ // for an unrecognised one.
300+ func (t * Tag ) SignatureType () string {
301+ return signature .GetSignatureType (t .Signature )
230302}
0 commit comments