Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support loading Ed448 public keys in OpenSSH format #11249

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

dlenskiSB
Copy link
Contributor

@dlenskiSB dlenskiSB commented Jul 10, 2024

The 'ssh-ed448' key type is documented along with 'ssh-ed25519' in [1], but has never been supported by any as-yet-released version of OpenSSH.

However, LANcom router devices (which appear to be primarily used in Germany, see [2] for examples on the public Internet) appear to support these keys, so this library can and should support loading them.

Ed448 private keys are not yet implemented here, because OpenSSH itself does not yet support them, and it is the de facto authority for private key formats. However, PuTTY has already implemented support for generating and
using Ed448 keys, and the PuTTY developers note in [3] that the OpenSSH developers are in agreement with them as to the correct Ed448 private key format:

I checked with them [OpenSSH developers], and they agreed that there's an obviously right format for Ed448 keys, which is to do them exactly like Ed25519 except that you have a 57-byte string everywhere Ed25519 had a 32-byte string. So I've done that.

See also [4] in which I extended ssh-audit to allow it to scan and discover host keys of type 'ssh-ed488'.

[1] https://datatracker.ietf.org/doc/html/rfc8709#name-public-key-format
[2] https://www.shodan.io/search?query=ssh+%22ed448%22
[3] github/putty@a085acb
[4] jtesta/ssh-audit#277

@dlenskiSB dlenskiSB force-pushed the support_loading_Ed448_public_keys_in_SSH_format branch 3 times, most recently from fcc5557 to e2a26a0 Compare July 10, 2024 23:51
Comment on lines +635 to +639
def encode_private(
self, private_key: ed448.Ed448PrivateKey, f_priv: _FragList
) -> None:
"""Write Ed448 private key"""
raise UnsupportedAlgorithm(
"Serializing Ed448 SSH private keys is unsupported"
)
Copy link
Contributor Author

@dlenskiSB dlenskiSB Jul 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's quite likely that Ed448 private keys for OpenSSH would (will?) have a format very similar to Ed25519 private keys (e.g.

sk = b"x" * 32
pk1 = b"y" * 32
pk2 = b"z" * 32
data = self.make_file(
pub_type=b"ssh-ed25519",
pub_fields=(pk1,),
priv_fields=(
pk1,
sk + pk2,
),
)
), but since I haven't seen any real-world examples of private keys in OpenSSH format, and since the Ed25519 format is weirdly redundant in terms of its repetition of private and public key parts… I'm reluctant to make any assumptions about it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, from github/putty@a085acb

since the OpenSSH agent protocol is the de facto
standard … OpenSSH themselves get to
say what the format for a key should or shouldn't be. So if they don't
support a particular key method, what do you do?

I checked with them, and they agreed that there's an obviously right
format for Ed448 keys, which is to do them exactly like Ed25519 except
that you have a 57-byte string everywhere Ed25519 had a 32-byte
string
. So I've done that.

So we could follow suit and support an OpenSSH-like Ed448 private key format just as Putty does.

@alex
Copy link
Member

alex commented Jul 11, 2024

Are ed448 keys documented by OpenSSH? ssh-keygen -ted448 doesn't appear to work.

@dlenskiSB
Copy link
Contributor Author

dlenskiSB commented Jul 11, 2024

Are ed448 keys documented by OpenSSH? ssh-keygen -ted448 doesn't appear to work.

@alex, they are not supported by OpenSSH, as I write in the commit message: The 'ssh-ed448' key type … has never been supported by any as-yet-released version of OpenSSH.

But their public key format is documented in RFC8709, alongside the very similar format for ssh-ed25519 keys which OpenSSH does support.

Although OpenSSH doesn't support Ed448 keys, other SSHv2-compatible software apparently does. (Including the widely-used Putty client, v0.75+)

@dlenskiSB dlenskiSB marked this pull request as ready for review July 11, 2024 04:01
@dlenskiSB dlenskiSB force-pushed the support_loading_Ed448_public_keys_in_SSH_format branch from e2a26a0 to 55e2d3f Compare July 16, 2024 05:35
@dlenskiSB
Copy link
Contributor Author

dlenskiSB commented Jul 16, 2024

The flake8 failure here seems to be due to it objecting to the preexisting sort order of an import block. 🤷🏻‍♂️

@reaperhulk
Copy link
Member

Are you sure you don’t just need to put ed448 before ed25519 in the imports?

@dlenskiSB
Copy link
Contributor Author

Are you sure you don’t just need to put ed448 before ed25519 in the imports?

Apparently so. I had no idea that numeric substrings in module names get sorted like this, woah 😵
PyCQA/isort#1732 (comment)

@dlenskiSB dlenskiSB force-pushed the support_loading_Ed448_public_keys_in_SSH_format branch 3 times, most recently from 06817d4 to 9fd4897 Compare July 16, 2024 15:31
@dlenskiSB dlenskiSB force-pushed the support_loading_Ed448_public_keys_in_SSH_format branch from 9fd4897 to 0ac431c Compare July 17, 2024 21:04
@dlenskiSB dlenskiSB requested a review from alex July 18, 2024 01:39
reaperhulk
reaperhulk previously approved these changes Jul 18, 2024
@reaperhulk
Copy link
Member

I'm comfortable with merging public key parsing support (let's wait on private until we see user demand or it lands in a prominent server implementation). At the moment there are some missing lines of coverage though. You can see a visual report by downloading the html-report from the artifacts here: https://github.com/pyca/cryptography/actions/runs/9981453975?pr=11249

@dlenskiSB dlenskiSB force-pushed the support_loading_Ed448_public_keys_in_SSH_format branch 5 times, most recently from f2d8f73 to f9504d1 Compare July 18, 2024 22:10
The 'ssh-ed448' key type is documented along with 'ssh-ed25519' in [1], but
has never been supported by any as-yet-released version of OpenSSH.

However, LANcom router devices (which appear to be primarily used in
Germany, see [2] for examples on the public Internet) appear to support
these keys, so this library can and should support loading them.

Ed448 private keys are not yet implemented here, because OpenSSH itself does
not yet support them, and it is the de facto authority for private key
formats.  However, PuTTY has already implemented support for generating and
using Ed448 keys, and the PuTTY developers note in [3] that the OpenSSH
developers are in agreement with them as to the correct Ed448 private key
format:

> I checked with them [OpenSSH developers], and they agreed that there's an
> obviously right format for Ed448 keys, which is to do them exactly like
> Ed25519 except that you have a 57-byte string everywhere Ed25519 had a
> 32-byte string.  So I've done that.

See also [4] in which I extended `ssh-audit` to allow it to scan and
discover host keys of type 'ssh-ed488'.

[1] https://datatracker.ietf.org/doc/html/rfc8709#name-public-key-format
[2] https://www.shodan.io/search?query=ssh+%22ed448%22
[3] github/putty@a085acb
[4] jtesta/ssh-audit#277
@dlenskiSB dlenskiSB force-pushed the support_loading_Ed448_public_keys_in_SSH_format branch from f9504d1 to 9aedcec Compare July 18, 2024 22:18
@fochoao1986

This comment was marked as spam.

@alex
Copy link
Member

alex commented Aug 30, 2024

Were you interested in continuing to work on this? We're happy to review once tests are passing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants