> On Dec 2, 2016, at 12:37 AM, Glyph Lefkowitz <[email protected]> wrote:
>
>
>> On Dec 2, 2016, at 12:27 AM, Glyph Lefkowitz <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>>
>>> On Dec 2, 2016, at 12:19 AM, Glyph Lefkowitz <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>
>>>> On Dec 1, 2016, at 7:01 PM, Mark Williams <[email protected]
>>>> <mailto:[email protected]>> wrote:
>>>>
>>>> On Thu, Dec 01, 2016 at 05:11:37PM -0800, Craig Rodrigues wrote:
>>>>> Hi,
>>>>>
>>>>> I filed this bug:
>>>>> https://twistedmatrix.com/trac/ticket/8931
>>>>> <https://twistedmatrix.com/trac/ticket/8931>
>>>>>
>>>>> At least for me, conch fails to parse a host key created by OpenSSH
>>>>> in ~/.ssh/known_hosts
>>>>> which is of type ecdsa-sha2-nistp256.
>>>>>
>>>>> Anyone have an idea as to how to fix this?
>>>>>
>>>>
>>>> As usual you've found a fantastically interesting issue.
>>>>
>>>> This is conch, the client, right? I'm guessing so because
>>>> ~/.ssh/known_hosts contains the servers the ssh client trusts.
>>>> (Specifically, among other things it contains a hostname and that
>>>> host's sshd server's public key fingerprint).
>>>>
>>>> If it is conch, the-client, then deleting the offending entry from
>>>> ~/.ssh/known_hosts and getting a new one makes sense. That's because
>>>> sshd usually generates a couple of different keys in case clients
>>>> don't support the latest and greatest technology.
>>>>
>>>> I think deleting the entry in ~/.ssh/known_hosts allows conch to ask
>>>> the server for a different key that it *can* understand. You should
>>>> be able to find out which server key conch negotiated by doing thing
>>>> following after deleting the offending ~/.ssh/known_hosts entry:
>>>>
>>>> (<hostname is the problematic OS X server>)
>>>> $ ssh-keygen -H -F <hostname> | awk '{ print $NF }'
>>>> dGhpcyBpcyB2ZXJ5IHZlcnkgdmVyeSB2ZXJ5IHZlcnkgbG9uZyBob3N0IGtleQ==
>>>>
>>>> Then on the OS X server, grep for that in /etc/ssh/*.pub
>>>>
>>>> I bet the key negotiated by conch is not an ECDSA key but rather an
>>>> RSA key. If this is all the case, then I think you've found a key
>>>> that LibreSSL supports but your client's libssl (which conch calls
>>>> into via cryptography) does not. What version of libssl do you have?
>>>>
>>>> If any of this is helpful or relevant I'll ask more questions in the
>>>> ticket.
>>>
>>> I think there might be a regression in 16.6.0.
>>>
>>> For every version up to 16.6.0, I can do 'conch twistedmatrix.com
>>> <http://twistedmatrix.com/>' in a shell and it works fine.
>>>
>>> On 16.6.0, I get:
>>>
>>> Connection to twistedmatrix.com <http://twistedmatrix.com/> closed.
>>> conch: exiting with error [Failure instance: Traceback (failure with no
>>> frames): <class 'twisted.conch.error.ConchError'>: ('bad host key', 9)
>>> ]
>>>
>>> instead.
>>>
>>> Worth noting: the keys I have for twistedmatrix.com
>>> <http://twistedmatrix.com/> are RSA keys.
>>>
>>> What did we add recently that changes key parsing?
>>
>> The offending commit is 8164d89104a453947215b9296e8b406f15e63252. Clearly
>> something went wrong when introducing ECDSA parsing.
>
> The problem is not quite as bad as breaking RSA parsing, at least; the issue
> is that my known_hosts file includes an ecdsa-sha2-nistp256 entry that
> _precedes_ my ssh-rsa entry. So the problem is that parsing one of those
> entries raises an exception which propagates. From a superficial
> investigation, it would appear that _all_ ecdsa keys cause this failure,
> though.
Investigating further, I think I've figured it out. Here's a patch that fixes
the problem:
diff --git a/src/twisted/conch/ssh/keys.py b/src/twisted/conch/ssh/keys.py
index d47db7f..570f524 100644
--- a/src/twisted/conch/ssh/keys.py
+++ b/src/twisted/conch/ssh/keys.py
@@ -247,8 +247,10 @@ class Key(object):
).public_key(default_backend())
)
elif keyType in [b'ecdsa-sha2-' + curve for curve in
list(_curveTable.keys())]:
- x, y, rest = common.getMP(rest, 2)
- return cls._fromECComponents(x=x, y=y, curve=keyType)
+ return cls(load_ssh_public_key(
+ keyType + b' ' + base64.encodestring(blob),
+ default_backend())
+ )
else:
raise BadKeyError('unknown blob type: %s' % (keyType,))
I suspect, but do not fully understand, that the problem here is point
compression. Key._fromString_BLOB naively just does getMP(blob, 2) and expects
that the x,y will be the EC point. However, to quote
https://tools.ietf.org/html/rfc5656#section-3.1, "point compression MAY be
used". I don't know exactly how point compression works, but I do understand
that it means you do funky stuff with the Y value. I do not believe that
EllipticCurvePrivateNumbers understands said funky stuff.
A specific ECC integration test with ssh-keygen from OpenSSH and
twisted.conch.client.knownhosts.KnownHostsFile would have spotted this specific
manifestation of the issue. However, another underlying bug is that
KnownHostsFile _should_ ignore lines that it can't parse. And, there's another
potential manifestation of the issue where loading from an actual key blob
might not work; arguably the problem here is that KnownHostsFile made the
questionable decision to do its own base64-decoding and pass the blob straight
to the key rather than just pass the portion of the line after the hostname and
load it as an openssh-format key directly.
-glyph
_______________________________________________
Twisted-Python mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python