Skip to content

Commit

Permalink
Use SHA256 for SSH signing
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
42wim committed Dec 25, 2021
1 parent 5583674 commit a368707
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
52 changes: 44 additions & 8 deletions algorithms.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"crypto/ecdsa"
"crypto/hmac"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/subtle" // Use should trigger great care
Expand Down Expand Up @@ -68,10 +67,9 @@ var hashToDef = map[crypto.Hash]struct {
// http://www.iana.org/assignments/signature-algorithms
//
// Note that the forbidden hashes have an invalid 'new' function.
crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
// Temporarily enable SHA1 because of issue https://github.com/golang/go/issues/37278
crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return sha1.New(), nil }},
crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.SHA224: {sha224String, func(key []byte) (hash.Hash, error) { return sha256.New224(), nil }},
crypto.SHA256: {sha256String, func(key []byte) (hash.Hash, error) { return sha256.New(), nil }},
crypto.SHA384: {sha384String, func(key []byte) (hash.Hash, error) { return sha512.New384(), nil }},
Expand Down Expand Up @@ -192,11 +190,49 @@ func (r *rsaAlgorithm) setSig(b []byte) error {
return nil
}

// Code from https://github.com/cloudtools/ssh-cert-authority/pull/49/files
// This interface provides a way to reach the exported, but not accessible SignWithOpts() method
// in x/crypto/ssh/agent. Access to this is needed to sign with more secure signing algorithms
type agentKeyringSigner interface {
SignWithOpts(rand io.Reader, data []byte, opts crypto.SignerOpts) (*ssh.Signature, error)
}

// A struct to wrap an SSH Signer with one that will switch to SHA256 Signatures.
// Replaces the call to Sign() with a call to SignWithOpts using HashFunc() algorithm.
type Sha256Signer struct {
ssh.Signer
}

func (s Sha256Signer) HashFunc() crypto.Hash {
return crypto.SHA256
}

func (s Sha256Signer) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) {
if aks, ok := s.Signer.(agentKeyringSigner); !ok {
return nil, fmt.Errorf("ssh: can't wrap a non ssh agentKeyringSigner")
} else {
return aks.SignWithOpts(rand, data, s)
}
}

func (r *rsaAlgorithm) Sign(rand io.Reader, p crypto.PrivateKey, sig []byte) ([]byte, error) {
if r.sshSigner != nil {
sshsig, err := r.sshSigner.Sign(rand, sig)
if err != nil {
return nil, err
var (
sshsig *ssh.Signature
err error
)
// are we using an SSH Agent
if _, ok := r.sshSigner.(agentKeyringSigner); ok {
signer := Sha256Signer{r.sshSigner}
sshsig, err = signer.Sign(rand, sig)
if err != nil {
return nil, err
}
} else {
sshsig, err = r.sshSigner.(ssh.AlgorithmSigner).SignWithAlgorithm(rand, sig, ssh.SigAlgoRSASHA2256)
if err != nil {
return nil, err
}
}

return sshsig.Blob, nil
Expand Down
4 changes: 1 addition & 3 deletions httpsig.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const (
BLAKE2B_384 Algorithm = blake2b_384String
BLAKE2B_512 Algorithm = blake2b_512String
// RSA-based algorithms.
RSA_SHA1 Algorithm = rsaPrefix + "-" + sha1String
RSA_SHA224 Algorithm = rsaPrefix + "-" + sha224String
// RSA_SHA256 is the default algorithm.
RSA_SHA256 Algorithm = rsaPrefix + "-" + sha256String
Expand Down Expand Up @@ -234,7 +233,7 @@ func getSSHAlgorithm(pkType string) Algorithm {
case strings.HasPrefix(pkType, sshPrefix+"-"+ed25519Prefix):
return ED25519
case strings.HasPrefix(pkType, sshPrefix+"-"+rsaPrefix):
return RSA_SHA1
return RSA_SHA256
}

return ""
Expand Down Expand Up @@ -324,7 +323,6 @@ func newSSHSigner(sshSigner ssh.Signer, algo Algorithm, dAlgo DigestAlgorithm, h
}

func newSigner(algo Algorithm, dAlgo DigestAlgorithm, headers []string, scheme SignatureScheme, expiresIn int64) (Signer, error) {

var expires, created int64 = 0, 0
if expiresIn != 0 {
created = time.Now().Unix()
Expand Down

0 comments on commit a368707

Please sign in to comment.