FAQ
Hi all,

I'm implementing an ssh client using the ssh package;
my program checks the server's public key using ClientConfig.HostKeyCallback
( https://godoc.org/golang.org/x/crypto/ssh#ClientConfig ).

Unfortunately, it fails login to some servers if the server has multiple
keys
(e.g., ssh_host_ecdsa_key, ssh_host_rsa_key, and ssh_host_dsa_key)
and the client has a public key other than ECDSA.

SSH client in Google Go always lists the host key algorithms in the
SSH_MSG_KEXINIT message
in this order:
* ECDSA256
* ECDSA384
* ECDSA521
* RSA
* DSA

See the source code:
https://github.com/golang/crypto/blob/c10c31b5e94b6f7a0283272dc2bb27163dcea24b/ssh/common.go#L42
https://github.com/golang/crypto/blob/c10c31b5e94b6f7a0283272dc2bb27163dcea24b/ssh/handshake.go#L237

If the server has both ECDSA and RSA keys, and the client knows only the
RSA public key,
the implementation in Google Go will always use ECDSA, so the SSH handshake
will fail.
Only the ECDSA public key will be passed to ClientConfig.HostKeyCallback,
then the SSH handshake will fail.


I studied the source code of the original ssh tool
(http://www.openssh.com/).

In order_hostkeyalgs function (file sshconnect2.c), they find all public
keys in known_hosts
for this host and place the corresponding algorithms at the beginning of
the list of host key
algorithms in SSH_MSG_KEXINIT. For example, if the client has an RSA key
for this host,
the list of algorithms passed to the server will be:

* ssh-rsa (we have a key for it in known_hosts)
* ECDSA
* ... (other algorithms supported by the client)



RFC 4253, chapter 7.1 says:
   "The first algorithm on the client's name-list that satisfies the
requirements and
    is also supported by the server MUST be chosen. If there is no such
algorithm, both
    sides MUST disconnect."


So, the implementation in Google Go seems to be incorrect.

What do you think about it? How do you check server's public key when using
the ssh package?

Thanks.
Peter.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Matt Harden at Jul 14, 2015 at 2:19 pm
    It looks like an omission to me. A client should be able to override the
    list of host key algorithms. Better yet, or in addition, it would be nice
    to have ClientConfig.AddHostKey(key PublicKey) to mirror
    ServerConfig.AddHostKey(key Signer).
    On Tue, Jul 14, 2015 at 8:52 AM wrote:

    Hi all,

    I'm implementing an ssh client using the ssh package;
    my program checks the server's public key using
    ClientConfig.HostKeyCallback
    ( https://godoc.org/golang.org/x/crypto/ssh#ClientConfig ).

    Unfortunately, it fails login to some servers if the server has multiple
    keys
    (e.g., ssh_host_ecdsa_key, ssh_host_rsa_key, and ssh_host_dsa_key)
    and the client has a public key other than ECDSA.

    SSH client in Google Go always lists the host key algorithms in the
    SSH_MSG_KEXINIT message
    in this order:
    * ECDSA256
    * ECDSA384
    * ECDSA521
    * RSA
    * DSA

    See the source code:

    https://github.com/golang/crypto/blob/c10c31b5e94b6f7a0283272dc2bb27163dcea24b/ssh/common.go#L42

    https://github.com/golang/crypto/blob/c10c31b5e94b6f7a0283272dc2bb27163dcea24b/ssh/handshake.go#L237

    If the server has both ECDSA and RSA keys, and the client knows only the
    RSA public key,
    the implementation in Google Go will always use ECDSA, so the SSH
    handshake will fail.
    Only the ECDSA public key will be passed to ClientConfig.HostKeyCallback,
    then the SSH handshake will fail.


    I studied the source code of the original ssh tool (
    http://www.openssh.com/).

    In order_hostkeyalgs function (file sshconnect2.c), they find all public
    keys in known_hosts
    for this host and place the corresponding algorithms at the beginning of
    the list of host key
    algorithms in SSH_MSG_KEXINIT. For example, if the client has an RSA key
    for this host,
    the list of algorithms passed to the server will be:

    * ssh-rsa (we have a key for it in known_hosts)
    * ECDSA
    * ... (other algorithms supported by the client)



    RFC 4253, chapter 7.1 says:
    "The first algorithm on the client's name-list that satisfies the
    requirements and
    is also supported by the server MUST be chosen. If there is no such
    algorithm, both
    sides MUST disconnect."


    So, the implementation in Google Go seems to be incorrect.

    What do you think about it? How do you check server's public key when
    using the ssh package?

    Thanks.
    Peter.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJul 14, '15 at 1:52p
activeJul 14, '15 at 2:19p
posts2
users2
websitegolang.org

2 users in discussion

Matt Harden: 1 post Kankowski: 1 post

People

Translate

site design / logo © 2022 Grokbase