Skip to content

Commit 40074d6

Browse files
authored
Merge pull request #996 from wlynch/signer-config
Add crypto.Signer option to CommitOptions.
2 parents 7c44bdd + e1bb0e2 commit 40074d6

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

options.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package git
22

33
import (
4+
"crypto"
45
"errors"
56
"fmt"
67
"regexp"
@@ -507,6 +508,10 @@ type CommitOptions struct {
507508
// commit will not be signed. The private key must be present and already
508509
// decrypted.
509510
SignKey *openpgp.Entity
511+
// Signer denotes a cryptographic signer to sign the commit with.
512+
// A nil value here means the commit will not be signed.
513+
// Takes precedence over SignKey.
514+
Signer crypto.Signer
510515
// Amend will create a new commit object and replace the commit that HEAD currently
511516
// points to. Cannot be used with All nor Parents.
512517
Amend bool

worktree_commit.go

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package git
22

33
import (
44
"bytes"
5+
"crypto"
6+
"crypto/rand"
57
"errors"
8+
"io"
69
"path"
710
"sort"
811
"strings"
@@ -14,6 +17,7 @@ import (
1417
"github.com/go-git/go-git/v5/storage"
1518

1619
"github.com/ProtonMail/go-crypto/openpgp"
20+
"github.com/ProtonMail/go-crypto/openpgp/packet"
1721
"github.com/go-git/go-billy/v5"
1822
)
1923

@@ -125,12 +129,17 @@ func (w *Worktree) buildCommitObject(msg string, opts *CommitOptions, tree plumb
125129
ParentHashes: opts.Parents,
126130
}
127131

128-
if opts.SignKey != nil {
129-
sig, err := w.buildCommitSignature(commit, opts.SignKey)
132+
// Convert SignKey into a Signer if set. Existing Signer should take priority.
133+
signer := opts.Signer
134+
if signer == nil && opts.SignKey != nil {
135+
signer = &gpgSigner{key: opts.SignKey}
136+
}
137+
if signer != nil {
138+
sig, err := w.buildCommitSignature(commit, signer)
130139
if err != nil {
131140
return plumbing.ZeroHash, err
132141
}
133-
commit.PGPSignature = sig
142+
commit.PGPSignature = string(sig)
134143
}
135144

136145
obj := w.r.Storer.NewEncodedObject()
@@ -140,20 +149,44 @@ func (w *Worktree) buildCommitObject(msg string, opts *CommitOptions, tree plumb
140149
return w.r.Storer.SetEncodedObject(obj)
141150
}
142151

143-
func (w *Worktree) buildCommitSignature(commit *object.Commit, signKey *openpgp.Entity) (string, error) {
152+
type gpgSigner struct {
153+
key *openpgp.Entity
154+
}
155+
156+
func (s *gpgSigner) Public() crypto.PublicKey {
157+
return s.key.PrimaryKey
158+
}
159+
160+
func (s *gpgSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
161+
var cfg *packet.Config
162+
if opts != nil {
163+
cfg = &packet.Config{
164+
DefaultHash: opts.HashFunc(),
165+
}
166+
}
167+
168+
var b bytes.Buffer
169+
if err := openpgp.ArmoredDetachSign(&b, s.key, bytes.NewReader(digest), cfg); err != nil {
170+
return nil, err
171+
}
172+
return b.Bytes(), nil
173+
}
174+
175+
func (w *Worktree) buildCommitSignature(commit *object.Commit, signer crypto.Signer) ([]byte, error) {
144176
encoded := &plumbing.MemoryObject{}
145177
if err := commit.Encode(encoded); err != nil {
146-
return "", err
178+
return nil, err
147179
}
148180
r, err := encoded.Reader()
149181
if err != nil {
150-
return "", err
182+
return nil, err
151183
}
152-
var b bytes.Buffer
153-
if err := openpgp.ArmoredDetachSign(&b, signKey, r, nil); err != nil {
154-
return "", err
184+
b, err := io.ReadAll(r)
185+
if err != nil {
186+
return nil, err
155187
}
156-
return b.String(), nil
188+
189+
return signer.Sign(rand.Reader, b, nil)
157190
}
158191

159192
// buildTreeHelper converts a given index.Index file into multiple git objects

worktree_commit_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ func (s *WorktreeSuite) TestCommitAmend(c *C) {
131131
_, err = w.Commit("foo\n", &CommitOptions{Author: defaultSignature()})
132132
c.Assert(err, IsNil)
133133

134-
135134
amendedHash, err := w.Commit("bar\n", &CommitOptions{Amend: true})
136135
c.Assert(err, IsNil)
137136

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy