Skip to content

Commit 1c17e20

Browse files
drakkangopherbot
authored andcommittedNov 23, 2023
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 <filippo@golang.org> Run-TryBot: Nicola Murino <nicola.murino@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
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)
Please sign in to comment.