ssh: support rsa-sha2-256/512 for client authentication
CL 220037 had implemented support for host authentication using rsa-sha2-256/512, but not client public key authentication. OpenSSH disabled the SHA-1 based ssh-rsa by default in version 8.8 (after pre-announcing it in versions 8.2, 8.3, 8.4, 8.5, 8.6, and 8.7) although some distributions re-enable it. GitHub will start rejecting ssh-rsa for keys uploaded before November 2, 2021 on March 15, 2022. https://github.blog/2021-09-01-improving-git-protocol-security-github/ The server side already worked, as long as the client selected one of the SHA-2 algorithms, because the signature flowed freely to Verify. There was however nothing verifying that the signature algorithm matched the advertised one. The comment suggested the check was being performed, but it got lost back in CL 86190043. Not a security issue because the signature had to pass the callback's Verify method regardless, and both values were checked to be acceptable. Tested with OpenSSH 8.8 configured with "PubkeyAcceptedKeyTypes -ssh-rsa" and no application-side changes. The Signers returned by ssh/agent (when backed by an agent client) didn't actually implement AlgorithmSigner but ParameterizedSigner, an interface defined in an earlier version of CL 123955. Updates golang/go#49269 Fixes golang/go#39885 For golang/go#49952 Change-Id: I13b41db8041f1112a70f106c55f077b904b12cb8 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/392394 Trust: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
+53
-1
@@ -105,11 +105,63 @@ func tryAuthBothSides(t *testing.T, config *ClientConfig, gssAPIWithMICConfig *G
|
||||
return err, serverAuthErrors
|
||||
}
|
||||
|
||||
type loggingAlgorithmSigner struct {
|
||||
used []string
|
||||
AlgorithmSigner
|
||||
}
|
||||
|
||||
func (l *loggingAlgorithmSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
||||
l.used = append(l.used, "[Sign]")
|
||||
return l.AlgorithmSigner.Sign(rand, data)
|
||||
}
|
||||
|
||||
func (l *loggingAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
l.used = append(l.used, algorithm)
|
||||
return l.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)
|
||||
}
|
||||
|
||||
func TestClientAuthPublicKey(t *testing.T) {
|
||||
signer := &loggingAlgorithmSigner{AlgorithmSigner: testSigners["rsa"].(AlgorithmSigner)}
|
||||
config := &ClientConfig{
|
||||
User: "testuser",
|
||||
Auth: []AuthMethod{
|
||||
PublicKeys(testSigners["rsa"]),
|
||||
PublicKeys(signer),
|
||||
},
|
||||
HostKeyCallback: InsecureIgnoreHostKey(),
|
||||
}
|
||||
if err := tryAuth(t, config); err != nil {
|
||||
t.Fatalf("unable to dial remote side: %s", err)
|
||||
}
|
||||
// Once the server implements the server-sig-algs extension, this will turn
|
||||
// into KeyAlgoRSASHA256.
|
||||
if len(signer.used) != 1 || signer.used[0] != KeyAlgoRSA {
|
||||
t.Errorf("unexpected Sign/SignWithAlgorithm calls: %q", signer.used)
|
||||
}
|
||||
}
|
||||
|
||||
// TestClientAuthNoSHA2 tests a ssh-rsa Signer that doesn't implement AlgorithmSigner.
|
||||
func TestClientAuthNoSHA2(t *testing.T) {
|
||||
config := &ClientConfig{
|
||||
User: "testuser",
|
||||
Auth: []AuthMethod{
|
||||
PublicKeys(&legacyRSASigner{testSigners["rsa"]}),
|
||||
},
|
||||
HostKeyCallback: InsecureIgnoreHostKey(),
|
||||
}
|
||||
if err := tryAuth(t, config); err != nil {
|
||||
t.Fatalf("unable to dial remote side: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestClientAuthThirdKey checks that the third configured can succeed. If we
|
||||
// were to do three attempts for each key (rsa-sha2-256, rsa-sha2-512, ssh-rsa),
|
||||
// we'd hit the six maximum attempts before reaching it.
|
||||
func TestClientAuthThirdKey(t *testing.T) {
|
||||
config := &ClientConfig{
|
||||
User: "testuser",
|
||||
Auth: []AuthMethod{
|
||||
PublicKeys(testSigners["rsa-openssh-format"],
|
||||
testSigners["rsa-openssh-format"], testSigners["rsa"]),
|
||||
},
|
||||
HostKeyCallback: InsecureIgnoreHostKey(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user