Skip to content

Commit e5a9092

Browse files
committed
support ssh on OS with disabled ssh-rsa algorithm
OpenSSH deprecated the ssh-rsa signature algorithm. Instead one should use one of the sha2 variantes (rsa-sha2-256 and rsa-sha2-512). Fedora was one of the first to disabled the ssh-rsa algorithm by default. That made a Fedora VM inaccessible from virter since golang.org/x/crypto/ssh still defaults to using ssh-rsa. This commit adds support for the newer replacement algorithms while keeping compatibility for older OSes.
1 parent d438ba5 commit e5a9092

File tree

4 files changed

+56
-7
lines changed

4 files changed

+56
-7
lines changed

go.mod

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ require (
2626
github.com/stretchr/testify v1.7.0
2727
github.com/vbauerster/mpb/v7 v7.0.2
2828
github.com/vektra/mockery v1.1.2
29-
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
29+
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
3030
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
31-
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
3231
golang.org/x/term v0.0.0-20210503060354-a79de5458b56
3332
)

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
626626
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
627627
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
628628
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
629-
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
630-
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
629+
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
630+
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
631631
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
632632
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
633633
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -773,8 +773,8 @@ golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7w
773773
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
774774
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
775775
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
776-
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 h1:C+AwYEtBp/VQwoLntUmQ/yx3MS9vmZaKNdw5eOpoQe8=
777-
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
776+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
777+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
778778
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
779779
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
780780
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=

pkg/sshkeys/hostkey.go

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ func (k *knownHosts) AsHostKeyConfig() (ssh.HostKeyCallback, []string) {
9191
return fmt.Errorf("ssh: host key mismatch")
9292
}, []string{
9393
ssh.KeyAlgoRSA,
94+
ssh.SigAlgoRSASHA2256,
95+
ssh.SigAlgoRSASHA2512,
9496
}
9597
}
9698

pkg/sshkeys/keystore.go

+49-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import (
66
"crypto/x509"
77
"encoding/pem"
88
"fmt"
9-
"golang.org/x/crypto/ssh"
9+
"io"
1010
"io/ioutil"
1111
"os"
12+
13+
"golang.org/x/crypto/ssh"
1214
)
1315

1416
// A KeyStore stores a single private key and the matching public key. It provides various methods to access
@@ -53,11 +55,57 @@ func NewKeyStore(privateKeyPath string, publicKeyPath string) (KeyStore, error)
5355
}
5456

5557
func (store *keyStore) Auth() []ssh.AuthMethod {
58+
algo, ok := store.privateKey.(ssh.AlgorithmSigner)
59+
if ok && algo.PublicKey().Type() == ssh.KeyAlgoRSA {
60+
return []ssh.AuthMethod{
61+
ssh.PublicKeys(
62+
&algoSigner{signer: algo, ty: ssh.SigAlgoRSASHA2512},
63+
&algoSigner{signer: algo, ty: ssh.SigAlgoRSASHA2256},
64+
&algoSigner{signer: algo},
65+
),
66+
}
67+
}
68+
5669
return []ssh.AuthMethod{
5770
ssh.PublicKeys(store.privateKey),
5871
}
5972
}
6073

74+
// algoSigner adds support for non-default signature algorithms when authenticating.
75+
type algoSigner struct {
76+
signer ssh.AlgorithmSigner
77+
ty string
78+
}
79+
80+
func (w *algoSigner) PublicKey() ssh.PublicKey {
81+
return &algoPublicKey{key: w.signer.PublicKey(), ty: w.ty}
82+
}
83+
84+
func (w *algoSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature, error) {
85+
return w.signer.SignWithAlgorithm(rand, data, w.ty)
86+
}
87+
88+
type algoPublicKey struct {
89+
key ssh.PublicKey
90+
ty string
91+
}
92+
93+
func (s *algoPublicKey) Type() string {
94+
if s.ty == "" {
95+
return s.key.Type()
96+
}
97+
98+
return s.ty
99+
}
100+
101+
func (s *algoPublicKey) Marshal() []byte {
102+
return s.key.Marshal()
103+
}
104+
105+
func (s *algoPublicKey) Verify(data []byte, sig *ssh.Signature) error {
106+
return s.key.Verify(data, sig)
107+
}
108+
61109
func (store *keyStore) KeyBytes() []byte {
62110
return store.privateKeyBytes
63111
}

0 commit comments

Comments
 (0)