Skip to content

Commit 1c17e20

Browse files
drakkangopherbot
authored andcommitted
ssh: fix certificate authentication with OpenSSH 7.2-7.7
OpenSSH 7.2-7.7 advertises support for rsa-sha2-256 and rsa-sha2-512 in the "server-sig-algs" extension but doesn't support these algorithms for certificate authentication, so if the server rejects the key try to use the obtained algorithm as if "server-sig-algs" had not been implemented. Fixes golang/go#58371 Change-Id: Id49960d3dedd32a21e2c6c2689b1696e05398286 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/510155 Reviewed-by: Filippo Valsorda <[email protected]> Run-TryBot: Nicola Murino <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> TryBot-Result: Gopher Robot <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Nicola Murino <[email protected]>
1 parent 270bf25 commit 1c17e20

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

ssh/client_auth.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,10 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
307307
}
308308
var methods []string
309309
var errSigAlgo error
310-
for _, signer := range signers {
310+
311+
origSignersLen := len(signers)
312+
for idx := 0; idx < len(signers); idx++ {
313+
signer := signers[idx]
311314
pub := signer.PublicKey()
312315
as, algo, err := pickSignatureAlgorithm(signer, extensions)
313316
if err != nil && errSigAlgo == nil {
@@ -321,6 +324,21 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
321324
if err != nil {
322325
return authFailure, nil, err
323326
}
327+
// OpenSSH 7.2-7.7 advertises support for rsa-sha2-256 and rsa-sha2-512
328+
// in the "server-sig-algs" extension but doesn't support these
329+
// algorithms for certificate authentication, so if the server rejects
330+
// the key try to use the obtained algorithm as if "server-sig-algs" had
331+
// not been implemented if supported from the algorithm signer.
332+
if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 {
333+
if contains(as.Algorithms(), KeyAlgoRSA) {
334+
// We retry using the compat algorithm after all signers have
335+
// been tried normally.
336+
signers = append(signers, &multiAlgorithmSigner{
337+
AlgorithmSigner: as,
338+
supportedAlgorithms: []string{KeyAlgoRSA},
339+
})
340+
}
341+
}
324342
if !ok {
325343
continue
326344
}

ssh/common.go

+8
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ func isRSA(algo string) bool {
127127
return contains(algos, underlyingAlgo(algo))
128128
}
129129

130+
func isRSACert(algo string) bool {
131+
_, ok := certKeyAlgoNames[algo]
132+
if !ok {
133+
return false
134+
}
135+
return isRSA(algo)
136+
}
137+
130138
// supportedPubKeyAuthAlgos specifies the supported client public key
131139
// authentication algorithms. Note that this doesn't include certificate types
132140
// since those use the underlying algorithm. This list is sent to the client if

0 commit comments

Comments
 (0)