aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2022-05-06 11:14:00 -0400
committerGopher Robot <gobot@golang.org>2022-05-13 21:02:58 +0000
commit46612604a0f90acbdd4722d44b8fd66ab69ed2a4 (patch)
tree4ad8995fb3f29318beebb729d1ccc0db03cafd21
parentc6db032c6c884ccc62755e1abf1214e99b8cea5f (diff)
downloadgo-x-crypto-46612604a0f90acbdd4722d44b8fd66ab69ed2a4.tar.xz
ssh/agent: fix non-RSA certificates
The type of ssh.PublicKey.Type can be a certificate type, while the algorithm passed to SignWithAlgorithm is going to be an underlying algorithm. Fixes golang/go#52185 Change-Id: I0f7c46defa83d1fd64a3c1e861734650b20cca21 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/404614 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Roland Shoemaker <roland@golang.org> Auto-Submit: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org>
-rw-r--r--ssh/agent/client.go29
-rw-r--r--ssh/certs.go2
2 files changed, 30 insertions, 1 deletions
diff --git a/ssh/agent/client.go b/ssh/agent/client.go
index dbc79d5..3c4d18a 100644
--- a/ssh/agent/client.go
+++ b/ssh/agent/client.go
@@ -772,7 +772,7 @@ func (s *agentKeyringSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature,
}
func (s *agentKeyringSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*ssh.Signature, error) {
- if algorithm == "" || algorithm == s.pub.Type() {
+ if algorithm == "" || algorithm == underlyingAlgo(s.pub.Type()) {
return s.Sign(rand, data)
}
@@ -791,6 +791,33 @@ func (s *agentKeyringSigner) SignWithAlgorithm(rand io.Reader, data []byte, algo
var _ ssh.AlgorithmSigner = &agentKeyringSigner{}
+// certKeyAlgoNames is a mapping from known certificate algorithm names to the
+// corresponding public key signature algorithm.
+//
+// This map must be kept in sync with the one in certs.go.
+var certKeyAlgoNames = map[string]string{
+ ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA,
+ ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256,
+ ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512,
+ ssh.CertAlgoDSAv01: ssh.KeyAlgoDSA,
+ ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256,
+ ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384,
+ ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521,
+ ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256,
+ ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519,
+ ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519,
+}
+
+// underlyingAlgo returns the signature algorithm associated with algo (which is
+// an advertised or negotiated public key or host key algorithm). These are
+// usually the same, except for certificate algorithms.
+func underlyingAlgo(algo string) string {
+ if a, ok := certKeyAlgoNames[algo]; ok {
+ return a
+ }
+ return algo
+}
+
// Calls an extension method. It is up to the agent implementation as to whether or not
// any particular extension is supported and may always return an error. Because the
// type of the response is up to the implementation, this returns the bytes of the
diff --git a/ssh/certs.go b/ssh/certs.go
index a69e224..4600c20 100644
--- a/ssh/certs.go
+++ b/ssh/certs.go
@@ -460,6 +460,8 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
// certKeyAlgoNames is a mapping from known certificate algorithm names to the
// corresponding public key signature algorithm.
+//
+// This map must be kept in sync with the one in agent/client.go.
var certKeyAlgoNames = map[string]string{
CertAlgoRSAv01: KeyAlgoRSA,
CertAlgoRSASHA256v01: KeyAlgoRSASHA256,