ssh: support RSA SHA-2 (RFC8332) signatures

This change adds support for RSA SHA-2 based signatures for host keys and certificates. It also switches the default certificate signature algorithm for RSA to use SHA-512. This is implemented by treating ssh.Signer specially when the key type is `ssh-rsa` by also allowing SHA-256 and SHA-512 signatures.

Fixes golang/go#37278

Change-Id: I2ee1ac4ae4c9c1de441a2d6cf1e806357ef18910
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/220037
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
Hans Nielsen
2021-11-15 23:45:14 +00:00
committed by Jason A. Donenfeld
parent ceb1ce70b4
commit b4de73f9ec
12 changed files with 213 additions and 69 deletions
+25 -4
View File
@@ -457,8 +457,15 @@ func (t *handshakeTransport) sendKexInit() error {
if len(t.hostKeys) > 0 {
for _, k := range t.hostKeys {
msg.ServerHostKeyAlgos = append(
msg.ServerHostKeyAlgos, k.PublicKey().Type())
algo := k.PublicKey().Type()
switch algo {
case KeyAlgoRSA:
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, []string{SigAlgoRSASHA2512, SigAlgoRSASHA2256, SigAlgoRSA}...)
case CertAlgoRSAv01:
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, []string{CertSigAlgoRSASHA2512v01, CertSigAlgoRSASHA2256v01, CertSigAlgoRSAv01}...)
default:
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
}
}
} else {
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
@@ -614,8 +621,22 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
var hostKey Signer
for _, k := range t.hostKeys {
if algs.hostKey == k.PublicKey().Type() {
kt := k.PublicKey().Type()
if kt == algs.hostKey {
hostKey = k
} else if signer, ok := k.(AlgorithmSigner); ok {
// Some signature algorithms don't show up as key types
// so we have to manually check for a compatible host key.
switch kt {
case KeyAlgoRSA:
if algs.hostKey == SigAlgoRSASHA2256 || algs.hostKey == SigAlgoRSASHA2512 {
hostKey = &rsaSigner{signer, algs.hostKey}
}
case CertAlgoRSAv01:
if algs.hostKey == CertSigAlgoRSASHA2256v01 || algs.hostKey == CertSigAlgoRSASHA2512v01 {
hostKey = &rsaSigner{signer, certToPrivAlgo(algs.hostKey)}
}
}
}
}
@@ -634,7 +655,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *
return nil, err
}
if err := verifyHostKeySignature(hostKey, result); err != nil {
if err := verifyHostKeySignature(hostKey, algs.hostKey, result); err != nil {
return nil, err
}