Skip to content

Commit 84cf7fd

Browse files
committed
Use SHA256 for SSH signing
When using the SSH Agent signers we need to use a wrapper to actually allow signing with SHA256.
1 parent 5583674 commit 84cf7fd

File tree

4 files changed

+56
-17
lines changed

4 files changed

+56
-17
lines changed

algorithms.go

+43-6
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@ var hashToDef = map[crypto.Hash]struct {
6868
// http://www.iana.org/assignments/signature-algorithms
6969
//
7070
// Note that the forbidden hashes have an invalid 'new' function.
71-
crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
72-
crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
73-
// Temporarily enable SHA1 because of issue https://github.com/golang/go/issues/37278
71+
crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
72+
crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
7473
crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return sha1.New(), nil }},
7574
crypto.SHA224: {sha224String, func(key []byte) (hash.Hash, error) { return sha256.New224(), nil }},
7675
crypto.SHA256: {sha256String, func(key []byte) (hash.Hash, error) { return sha256.New(), nil }},
@@ -192,11 +191,49 @@ func (r *rsaAlgorithm) setSig(b []byte) error {
192191
return nil
193192
}
194193

194+
// Code from https://github.com/cloudtools/ssh-cert-authority/pull/49/files
195+
// This interface provides a way to reach the exported, but not accessible SignWithOpts() method
196+
// in x/crypto/ssh/agent. Access to this is needed to sign with more secure signing algorithms
197+
type agentKeyringSigner interface {
198+
SignWithOpts(rand io.Reader, data []byte, opts crypto.SignerOpts) (*ssh.Signature, error)
199+
}
200+
201+
// A struct to wrap an SSH Signer with one that will switch to SHA256 Signatures.
202+
// Replaces the call to Sign() with a call to SignWithOpts using HashFunc() algorithm.
203+
type Sha256Signer struct {
204+
ssh.Signer
205+
}
206+
207+
func (s Sha256Signer) HashFunc() crypto.Hash {
208+
return crypto.SHA256
209+
}
210+
211+
func (s Sha256Signer) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) {
212+
if aks, ok := s.Signer.(agentKeyringSigner); !ok {
213+
return nil, fmt.Errorf("ssh: can't wrap a non ssh agentKeyringSigner")
214+
} else {
215+
return aks.SignWithOpts(rand, data, s)
216+
}
217+
}
218+
195219
func (r *rsaAlgorithm) Sign(rand io.Reader, p crypto.PrivateKey, sig []byte) ([]byte, error) {
196220
if r.sshSigner != nil {
197-
sshsig, err := r.sshSigner.Sign(rand, sig)
198-
if err != nil {
199-
return nil, err
221+
var (
222+
sshsig *ssh.Signature
223+
err error
224+
)
225+
// are we using an SSH Agent
226+
if _, ok := r.sshSigner.(agentKeyringSigner); ok {
227+
signer := Sha256Signer{r.sshSigner}
228+
sshsig, err = signer.Sign(rand, sig)
229+
if err != nil {
230+
return nil, err
231+
}
232+
} else {
233+
sshsig, err = r.sshSigner.(ssh.AlgorithmSigner).SignWithAlgorithm(rand, sig, ssh.SigAlgoRSASHA2256)
234+
if err != nil {
235+
return nil, err
236+
}
200237
}
201238

202239
return sshsig.Blob, nil

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module github.com/go-fed/httpsig
22

3-
require golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
3+
require golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
44

55
go 1.13

go.sum

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
2-
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
3-
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
4-
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
5-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6-
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
7-
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
1+
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
2+
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
3+
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
4+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
7+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
8+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
9+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
10+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
11+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

httpsig.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func getSSHAlgorithm(pkType string) Algorithm {
234234
case strings.HasPrefix(pkType, sshPrefix+"-"+ed25519Prefix):
235235
return ED25519
236236
case strings.HasPrefix(pkType, sshPrefix+"-"+rsaPrefix):
237-
return RSA_SHA1
237+
return RSA_SHA256
238238
}
239239

240240
return ""
@@ -324,7 +324,6 @@ func newSSHSigner(sshSigner ssh.Signer, algo Algorithm, dAlgo DigestAlgorithm, h
324324
}
325325

326326
func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme SignatureScheme, expiresIn int64) (Signer, error) {
327-
328327
var expires, created int64 = 0, 0
329328
if expiresIn != 0 {
330329
created = time.Now().Unix()

0 commit comments

Comments
 (0)