From e4883330ef6f3f337621d0e6e5704acea870d192 Mon Sep 17 00:00:00 2001 From: Chris Elledge Date: Wed, 11 Aug 2021 16:36:27 -0400 Subject: [PATCH] ssh: Upgrade CA Signatures to RSA-SHA2-256 Create a wrapper for SSH Agent Signing to allow using more secure signing algorithms. The default RSA-SHA1 is obsolete and will no longer work with OpenSSH 8.2. --- util/ssh.go | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/util/ssh.go b/util/ssh.go index e7c41c0..e73f2ce 100644 --- a/util/ssh.go +++ b/util/ssh.go @@ -1,6 +1,7 @@ package ssh_ca_util import ( + "crypto" "fmt" "github.com/cloudtools/ssh-cert-authority/signer" "golang.org/x/crypto/ssh" @@ -12,6 +13,30 @@ import ( var md5Fingerprint = regexp.MustCompile("([0-9a-fA-F]{2}:){15}[0-9a-fA-F]{2}") +//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 GetSignerForFingerprintOrUrl(fingerprint string, conn io.ReadWriter) (ssh.Signer, error) { isFingerprint := md5Fingerprint.MatchString(fingerprint) if isFingerprint { @@ -39,7 +64,7 @@ func GetSignerForFingerprint(fingerprint string, conn io.ReadWriter) (ssh.Signer for i := range signers { signerFingerprint := MakeFingerprint(signers[i].PublicKey().Marshal()) if signerFingerprint == fingerprint { - return signers[i], nil + return Sha256Signer{signers[i]}, nil } } return nil, fmt.Errorf("Unable to find your SSH key (%s) in agent. Consider ssh-add", fingerprint)