Skip to content

Commit a368707

Browse files
committed
Use SHA256 for SSH signing
This also removes (again) support for SHA1. When using the SSH Agent signers we need to use a wrapper to actually allow signing with SHA256.
1 parent 5583674 commit a368707

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

algorithms.go

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"crypto/ecdsa"
66
"crypto/hmac"
77
"crypto/rsa"
8-
"crypto/sha1"
98
"crypto/sha256"
109
"crypto/sha512"
1110
"crypto/subtle" // Use should trigger great care
@@ -68,10 +67,9 @@ var hashToDef = map[crypto.Hash]struct {
6867
// http://www.iana.org/assignments/signature-algorithms
6968
//
7069
// 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
74-
crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return sha1.New(), nil }},
70+
crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
71+
crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
72+
crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return nil, nil }},
7573
crypto.SHA224: {sha224String, func(key []byte) (hash.Hash, error) { return sha256.New224(), nil }},
7674
crypto.SHA256: {sha256String, func(key []byte) (hash.Hash, error) { return sha256.New(), nil }},
7775
crypto.SHA384: {sha384String, func(key []byte) (hash.Hash, error) { return sha512.New384(), nil }},
@@ -192,11 +190,49 @@ func (r *rsaAlgorithm) setSig(b []byte) error {
192190
return nil
193191
}
194192

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

202238
return sshsig.Blob, nil

httpsig.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ const (
4343
BLAKE2B_384 Algorithm = blake2b_384String
4444
BLAKE2B_512 Algorithm = blake2b_512String
4545
// RSA-based algorithms.
46-
RSA_SHA1 Algorithm = rsaPrefix + "-" + sha1String
4746
RSA_SHA224 Algorithm = rsaPrefix + "-" + sha224String
4847
// RSA_SHA256 is the default algorithm.
4948
RSA_SHA256 Algorithm = rsaPrefix + "-" + sha256String
@@ -234,7 +233,7 @@ func getSSHAlgorithm(pkType string) Algorithm {
234233
case strings.HasPrefix(pkType, sshPrefix+"-"+ed25519Prefix):
235234
return ED25519
236235
case strings.HasPrefix(pkType, sshPrefix+"-"+rsaPrefix):
237-
return RSA_SHA1
236+
return RSA_SHA256
238237
}
239238

240239
return ""
@@ -324,7 +323,6 @@ func newSSHSigner(sshSigner ssh.Signer, algo Algorithm, dAlgo DigestAlgorithm, h
324323
}
325324

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

0 commit comments

Comments
 (0)