mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alon Bar-Lev <alon.bar...@gmail.com>
Subject Re: Selecting a specific KEX signature at client for server key
Date Fri, 18 Dec 2015 20:10:41 GMT
On 18 December 2015 at 21:07, Alon Bar-Lev <alon.barlev@gmail.com> wrote:
> On 18 December 2015 at 19:56, Lyor Goldstein <lgoldstein@vmware.com> wrote:
>> I don't think what yo described is possible tor standard SSH. The KEX must use a
key type that is available for both the server and the flient. If you look at the KEX INIT
command you 2ill notice that there is only ONE FIELD tor key signatures,  unlike ciphers.
MACs and compression wher each side can choose what to use.  Bottom line, you cannot force
the server to present a weaker key than the client. However,  all is not lost - OpenSSH servers
do support a non-standard extension where they send ALL their keys. I only recently added
support for this - look for the OpenSSHHostKeys global request handler
>
> Thanks for the reference, I have saw this when looking at the recent
> changes, but did not make the connection between the two.
>
> This happens after user authentication, so in case of password
> authentication server already has the password, which is kinda
> strange, I will send a question to openssh devs.
>
> As far as I see at sshd-core, there is no support for the
> hostkeys-prove-00@openssh.com at client, am I right? What is the
> sequence of usage at client side?
> I guess setGlobalRequestHandlers with my own instance inherited from
> OpenSshHostKeysHandler to accept keys, then I should ask for prove for
> selected keys, how can I do that?

I am far from being an expert in ssh protocol, but while trying to
phrase a question to openssh devs, I read rfc4253, and it made me
wonder.

At rfc4253 "Algorithm Negotiation" we have:

      name-list    kex_algorithms
      name-list    server_host_key_algorithms

It means that we can force a specific key algorithm for host while
offering a large set of algorithms.

Then at rfc4252 we have "Public Key Authentication Method:
"publickey"" in which:
"Public key algorithms are defined in the transport layer specification"

So as far as I understand if we set kex algorithms of rsa and nistp256
and force host key algorithms of rsa, we should be able to force
server to use weaker algorithm while client can use any of rsa and
nistp256.

To prove that I hacked the AbstractSession with:

     protected byte[] sendKexInit() throws IOException {
-        String resolvedAlgorithms = resolveAvailableSignaturesProposal();
+        //String resolvedAlgorithms = resolveAvailableSignaturesProposal();
+        //String resolvedAlgorithms = "ssh-rsa";
+        String resolvedAlgorithms = "ecdsa-sha2-nistp256";

If I force ssh-rsa I receive ssh-rsa sever key as expected.
If I force ecdsa-sha2-nistp256 I receive ecdsa-sha2-nistp256 server
key as expected while can authenticate using client ssh-rsa key, this
means that server and client are indeed detached.

I will open a bug for us to work on enforcing server key type.

The openssh "connection: hostkey update and rotation" may be handy
later so we can switch into a new key, but first we need to be able to
force the server key type to enable to connect.

>> From: Alon Bar-Lev [alon.barlev@gmail.com]
>> Sent: Thursday, December 17, 2015 6:19 PM
>> To: dev@mina.apache.org; Lyor Goldstein
>> Subject: Selecting a specific KEX signature at client for server key
>>
>> Hello,
>>
>> I have a challenge...
>>
>> Let's assume I need to securely reconnect to a server, for that purpose I store its
public key. Every time I connect to this server I compare the public key accepted by ServerKeyVerifier
with the public key that is approved.
>>
>> This works perfectly and securely, well, until server adds a stronger algorithm/public
key, for example, a server with ssh-rsa key adds ecdsa-sha2-nistp256 one.
>>
>> In this case KEX selects the stronger one, causing client to reject the server as
 public key differs.
>>
>> I found a solution to this problem is to limit the signature algorithms based on
the public key type. We know the public key, so we can limit the KEX to use only this type
of signature, for example, assuming the approved key is ssh-rsa we can:
>>
>>     client.setSignatureFactories(Collections.singletonList(BuiltinSignatures.rsa))
>>
>> Now, even if the server has ecdsa-sha2-nistp256 key, the client will only receive
the ssh-rsa key.
>>
>> This works find as long as password authentication is used.
>>
>> However, as the signature factory is common to both client and server KEX, this will
not work in all cases for public key authentication, as the factory must contain the union
of both, for example:
>>
>>  server has both ssh-rsa and ecdsa-sha2-nistp256 keys.
>>  client caches the ssh-rsa.
>>  client key is ecdsa-sha2-nistp256.
>>  client must enable both rsa and nistp256 signatures for KEX to succeed.
>>  server key will be ecdsa-sha2-nistp256 as it is the strongest among ssh-rsa and
ecdsa-sha2-nistp256.
>>
>> Keep in mind that my understanding of the code is limited, I reviewed the session
callbacks, but from what I do understand there is no way to separate KEX algorithms of server
from these of client, as both are in the same base class KexFactoryManager.
>>
>> If I understand correctly, a solution could be implemented by having two signature
factories, one for client side and one for server side, or have a filter for client and server,
to enable forcing a specific set of algorithm for each side.
>>
>> Maybe I mis-read the code and there is an option of forcing server to use a specific
key differently.
>>
>> Any clue?
>>
>> Thanks,
>> Alon Bar-Lev.

Mime
View raw message