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 for SSH key signing #15

Closed
dnaka91 opened this issue Oct 5, 2022 · 16 comments
Closed

Support for SSH key signing #15

dnaka91 opened this issue Oct 5, 2022 · 16 comments

Comments

@dnaka91
Copy link

dnaka91 commented Oct 5, 2022

I tried implementing the new commit signing of Git with the git2 and ssh-key crate. This crate was a great help and contained almost all the pieces I needed to create working signatures.

Took me a few hours of searching around and fiddling with the signature format, but got a working implementation of the signing part. Definitely needs tons of tests and more verification, but it's a start.

The main part that is missing, is this SSH signature scheme: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig

I was wondering if this is something that would make sense to include into ssh-key, or may it be out of scope? Would try to start integrating my current solution into the crate and open a PR, if there is interest.

@tarcieri
Copy link
Member

tarcieri commented Oct 5, 2022

@dnaka91 good suggestion! I'll see if I can get it into the next release

@dnaka91
Copy link
Author

dnaka91 commented Oct 6, 2022

Glad to hear!

Should I start working on this or do you prefer to implement it yourself?

Currently only have the sign variant, not the verify part yet, but there are definitely some details that are not obvious from the protocol docs. Took me a while, looking at the signature with a hex editor, to find out how it's actually structured.

@tarcieri
Copy link
Member

tarcieri commented Oct 6, 2022

I plan on doing a pass on ssh-key soon to cut another release after we release rsa v0.7.0.

If you want to push up a PR before that though, I can use that or work off of it.

@tarcieri
Copy link
Member

@dnaka91 what did you find difficult or ambiguous about that spec? It looks fairly straightforward to me.

FYI, there will be a part of this which is a bit tricky, namely how to abstract over all of the various algorithm-specific backends in a way that can accommodate both the existing support for OpenSSH certificate signing / CAs as well as "sshsig".

That will likely require some refactoring of the current implementation.

@dnaka91
Copy link
Author

dnaka91 commented Oct 14, 2022

I guess it was rather lack of knowledge about OpenSSH.

One, rather easy, pitfall was that I read string and assumed C-style strings with trailing \0 byte. But instead, they're an u32 length + content.

The other one was, what they meant by the encoding for publickey, which turned out to be the content of PublicKey::to_bytes.

So in the end not really something missing from the spec, but rather me not fully understanding some common things in OpenSSH 😅.

Sorry, have been distracted by another project, so didn't try to integrate my code into ssh-key yet. Maybe I just throw it in a gist and reference here, for the time being.

@tarcieri
Copy link
Member

Yeah, this crate already includes an implementation of SSH's serialization formats, including one-pass decoding/encoding to/from PEM, e.g.

https://github.com/RustCrypto/SSH/blob/master/ssh-key/src/decode.rs

I'll take a look at trying to implement support this weekend, and after that, this crate should be ready for the next release.

@kim
Copy link

kim commented Oct 20, 2022

How is this coming along? I'd be interested in taking over if it has stalled.

@tarcieri
Copy link
Member

I plan on having a PR up this weekend

@tarcieri
Copy link
Member

Draft PR here: #28

Would appreciate early feedback on the API prior to a final release.

@dnaka91
Copy link
Author

dnaka91 commented Oct 23, 2022

This looks awesome 🤩

Had a look at the PR changes and this is so clean, as you have access to the internal encoding APIs. Mine is much more hacky as I had to re-implement those parts.

Saw a few lines where allocations could maybe be avoided, but that's rather nitpicking and probably not an issue (also, would make the code less readable).

Will give it a try later today and see how it goes.

@tarcieri
Copy link
Member

tarcieri commented Oct 23, 2022

@dnaka91 curious what allocations you think could be avoided.

The main one that might at first look like it could be avoided is encoding SignedData. Naively it seems like you could just hash it as it impls Writer which is impl'd for Sha256 and Sha512, however while that works for DSA, ECDSA, and RSA, it doesn't work with Ed25519.

Even PROTOCOL.sshsig says the following:

The data is concatenated and passed to the SSH signing function.

@tarcieri
Copy link
Member

Also, the encoding APIs will soon be public: #29

@dnaka91
Copy link
Author

dnaka91 commented Oct 23, 2022

I should probably rephrase that. Not fully being avoided, but instead being delayed, so that in case of an error, it wouldn't allocate.

One was during sign, where the namespace.to_owned() could be done later, after the signing. But is that even possible to fail and instead rather fallible due to the API?

And the other one I thought of was during decoding, where the String::decode and Vec::decode could eventually be replaced with reference versions (so on &str and &[u8], if they even exist), and then use to_owned in the end, once all fields succeeded to decode.

So really just super subtle things and only in case of errors.

Probably not really worth changing 😔

@tarcieri
Copy link
Member

This has now been implemented. Closing.

@tarcieri
Copy link
Member

If anyone would like to try this out before a final release, it's included in ssh-key v0.5.0-rc.0

@dnaka91
Copy link
Author

dnaka91 commented Oct 24, 2022

Got to try it out today. Works like a charm 👍

baloo pushed a commit to baloo/SSH that referenced this issue Apr 16, 2024
Make error implement std::io::Error and remove associated Agent's Error type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants