A pure-Haskell SSH server library
#5Support more secure, non-deprecated key-exchange system
diffie-hellman-group1-sha1
has been deprecated since OpenSSH 7.0 so currently this needs to be added to .ssh/config
to use darcsden:
Host hub.darcs.net
KexAlgorithms diffie-hellman-group1-sha1
diffie-hellman-group-exchange-sha256
is not deprecated and seems to be the closest to diffie-hellman-group1-sha1
so it would likely be the easiest key exchange system to implement and replace diffie-hellman-group1-sha1
on darcsden.
http://irclog.perlgeek.de/darcs/2015-09-16#i_11224700
https://www.ietf.org/rfc/rfc4419.txt
- summary changed to "Support more secure, non-deprecated key-exchange system"
It's come to my attention that
curve25519-sha256
is more secure thandiffie-hellman-group-exchange-sha256
and already has Haskell implementations:https://github.com/thoughtpolice/hs-nacl/blob/master/tests/Curve25519.hs
- added tag kex
Another wrapper for curve25519 : https://hackage.haskell.org/package/curve25519
"The key exchange procedure is similar to the ECDH method described in chapter 4 of [RFC5656], though with a different wire encoding used for public values and the final shared secret. Public ephemeral keys are encoded for transmission as standard SSH strings.
The protocol flow, the SSH_MSG_KEX_ECDH_INIT and SSH_MSG_KEX_ECDH_REPLY messages, and the structure of the exchange hash are identical to chapter 4 of [RFC5656]."
https://tools.ietf.org/html/draft-josefsson-ssh-curves-04#section-2
https://tools.ietf.org/html/rfc5656#section-4
For curve25519-sha256@libssh.org the conversation should look like:
The client sends:
byte SSH_MSG_KEX_ECDH_INIT string Q_C, client's ephemeral public key octet string
The server responds with:
byte SSH_MSG_KEX_ECDH_REPLY string K_S, server's public host key string Q_S, server's ephemeral public key octet string string the signature on the exchange hash
The exchange hash H is computed as the hash of the concatenation of the following.
string V_C, client's identification string (CR and LF excluded) string V_S, server's identification string (CR and LF excluded) string I_C, payload of the client's SSH_MSG_KEXINIT string I_S, payload of the server's SSH_MSG_KEXINIT string K_S, server's public host key string Q_C, client's ephemeral public key octet string string Q_S, server's ephemeral public key octet string mpint K, shared secret
For diffie-hellman-group1-sha1 it looks like this:
First, the client sends the following:
byte SSH_MSG_KEXDH_INIT mpint e
The server then responds with the following:
byte SSH_MSG_KEXDH_REPLY string server public host key and certificates (K_S) mpint f string signature of H
The (exchange) hash H is computed as the HASH hash of the concatenation of the following:
string V_C, the client's identification string (CR and LF excluded) string V_S, the server's identification string (CR and LF excluded) string I_C, the payload of the client's SSH_MSG_KEXINIT string I_S, the payload of the server's SSH_MSG_KEXINIT string K_S, the host key mpint e, exchange value sent by the client mpint f, exchange value sent by the server mpint K, the shared secret
For those who missed it on irc yesterday, ssh with the
curve25519-sha256@libssh.org
kex now works (most of the time). When it is not working, it may have to do with a key or signature not being padded with zeros to 32 bytes or something. It could also have to do with when the ssh client decides to rekey, but I think this is less likely. I will dig into this more, checking the size of each component of the exchange hash and all the keys.http://hub.darcs.net/pointfree/ssh-curve25519-sha256
Next steps:
- clean up the code
- look into switching over to cryptonite for everything. (right now I'm using [@gh's recommendation](http://hub.darcs.net/ganesh/ssh/issue/5#comment-20160203T120609) but cryptonite supports curve25519 as well)
- integrate @fr33domlover's work on ssh: http://hub.darcs.net/fr33domlover/ssh/compare/ganesh/ssh
@simon and myself both seem to think diffie-hellman-group1-sha1 support should just be dropped because it is not very secure anymore, adds sloc, and OpenSSH 7.0 has disabled it by default. Does anyone need it?
By the way,
cabal test
will still not work because it depends on libssh2-hs which depends on libssh2 which apparently does not offer the curve25519-sha256 kex. libssh does support curve25519-sha256@libssh.org but I can't find libssh (client) haskell bindings.https://www.libssh2.org/libssh2-vs-libssh.html
Although, there are bindings to the server part of libssh here. They could be adapted.
Random kex failures bug has been fixed:
http://hub.darcs.net/pointfree/ssh-curve25519-sha256/patch/6766d5f322701d4a00598ad007d564c22a279b74
With the following patches, darcsden will now work the curve25519-sha256@libssh.org kex!
http://hub.darcs.net/ganesh/ssh/compare/pointfree/ssh-curve25519-sha256
What's the status of this ? Could it be merged and released as 0.4 (or it might be a good time to go to 1.0, since there seems to be quite a few changes ?)
For future reference as to why these changes haven't been merged yet.
- fr33domlover's refactorings diverged quite a lot from the pointfree/ssh-curve25519-sha256 fork.
- libssh2 doesn't support curve25519-sha256 so the tests won't work (libssh supports that kex, libssh2 doesn't).
- The darcsden ssh server would have to be updated to support fr33domlover's changes.
- fr33domlover's changes got merged into ganesh/ssh first.
- There was some talk of using ssh-hans instead of this, or at least using pieces from ssh-hans. https://github.com/glguy/ssh-hans ssh-hans has a both a client and server ssh implementation and support for many kex's etc.
- The darcsden ssh server would have to be updated to use ssh-hans.
- ssh-hans only supports the OpenSSH key format, generated with the
-o
option tossh-keygen
. I don't think existing darcsden/darcshub keys are in that format.
One short term option would be to deploy pointfree/ssh-curve25519-sha256 just to hub.darcs.net until the above issues get resolved, for the sake of user experience and security.
@pointfree: do you have tests passing in your branch ? After building it with lts-8.4, I get:
~/src/ssh_curve25519$ stack test ssh-0.3.2: test (suite: ssh-test) Tests With server Single key auth tests Check auth with id_dsa Works: FAIL Exception: KEX_FALIURE Fails with broken private key: FAIL Exception: KEX_FALIURE Check auth with id_rsa_1024 Works: FAIL Exception: KEX_FALIURE Fails with broken private key: FAIL Exception: KEX_FALIURE Check auth with id_rsa_2048 Works: FAIL Exception: KEX_FALIURE Fails with broken private key: FAIL Exception: KEX_FALIURE Check auth with id_rsa_4096 Works: FAIL Exception: KEX_FALIURE Fails with broken private key: FAIL Exception: KEX_FALIURE Check auth with id_rsa_test Works: FAIL Exception: KEX_FALIURE Fails with broken private key: FAIL Exception: KEX_FALIURE Check auth with id_rsa_test2 Works: FAIL Exception: KEX_FALIURE Fails with broken private key: FAIL Exception: KEX_FALIURE Check auth failure with wrong key: FAIL Exception: KEX_FALIURE Signatures signatures from sign work with verify: OK (1.35s) +++ OK, passed 100 tests. mutated signatures from sign fail with verify: OK (1.42s) +++ OK, passed 100 tests. random signatures fail with verify: OK (0.04s) +++ OK, passed 100 tests. 13 out of 16 tests failed (2.88s) Test suite failure for package ssh-0.3.2 ssh-test: exited with: ExitFailure 1 Logs printed to console
Doh, you mentioned that, disregard.
darcs hub is now running the pointfree/ssh-curve25519-sha256 branch, to make life easier for darcs hub users. I hope it will be merged upstream soon, and tests made to not fail. Thanks!
We should also note that SHA1 has been publicly broken this year, https://en.wikipedia.org/wiki/SHA-1