hiddeco / sshsig

Go implementation of the OpenSSH SSH Signature protocol. Sign and verify messages using SSH keys in Go.
Apache License 2.0
10 stars 1 forks source link

Can't parse current (version 3) ssh signatures #62

Closed tionis closed 1 month ago

tionis commented 1 month ago

Parsing of SSH signatures of version 3 seems to fail, here's a signature produced by openssh that doesnt work:

-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAAhcAAAAHc3NoLXJzYQAAAAMBAAEAAAIBANTV2XUsgEMVnlooAshQZ1
QcHvRW4GoYfb4Fsu+KhpRYGcMJIHyauvvkRjUWnLEMhbur8a9zjfCdzZste4bIsRjvyCbt
yEHNVxqMkJJPsOrxM2J7OniacFqBGLGt4wGTwzb2V32nonpoZ6NvKxzy8u1rfFediZEp9Z
5kprJ6C0ibf8pyIu8+4rj5SsyIo7R8LXvC6S6pS8NlWSUN4UEUtI7+V57ug+9Mjl/8oF5U
XSuzbVlIMpk37xDtU8iiEj/FWUK90TKoNMgI5QquhoA8ZrX/U2RJ3h97kXTYLmHtYKEdp3
xu1Y1K7ydM/zopQA4U5hrxRSmhoe3Ya5QJTzukeixDTy1OKMADHxsPKrYp2cmX2SBeH/Yt
pGe7f8MkNBcEmlXzbUbLO3yGWpcDRx2tvITrHXfIgD5NrVZeVHYiDNqLdQ5OQsvo84kEI7
Jw7h3F319LuXxY2JzpMhCZAOXZ5xQQKBJha8EfZMmKW0JRATLRXZHHwjbxG+27LOSYZtHh
PPmZCLAS6TR3LFEKhy3rP0KkL0VJlGJcfv6pQeVqV5ksQjoRioxYUyPRWdxDd12SUQTMQ4
/3B5Ra92AhbLzCgJC5n9i5biU1LZC3bmOoWC/1dV13OxMN1K3UYWx0OfIfKGudpJ/RtrJi
0Kjbzj0Yj9ApHd2+MaiCljP/mOynFlkRAAAABGZpbGUAAAAAAAAABnNoYTUxMgAAAhQAAA
AMcnNhLXNoYTItNTEyAAACAAO1VO9/faLFN/iUwaS0E9vpR9ZImmBra0gJ3m70Bwq7jPy7
WNBXFdqpBiG1T+TVjK/mt+jAUFkQkDI/dMGoPxD2bKQeGbtvOtLFRXjFvooBVGOpR7ziJ4
FhYW8TK4CDEpVISqPp4T6IG0q2tIyp3WtFJZ8ySTpnhj7tZkgZiilj89sg9A5l4ByshQR4
+R8rFcBJEnstCPWdU73FUsPrs6TSyn3mSyp4RroQ4d4RiNYELTF4tN8IXGe5jkkzMiKMmv
4RXB/hglavpalSxLK78GmUBdYetC8gW9GHxpvv6KZYyIxdbDZryX0eoYpDzNTaRXZN4FM6
9qUQJawVLl3MPGrdjf6nLHdaqbIpPlMNQuIBiNALn+ReNijboTtl/RquTngqGAeykkvbFR
Kle1hY42APojTPBTiZZPuhLNGoYdB+ZHiALWwQ0ChHvuDkklxOI9VIuwZTEtfQHHuseFEk
GNgxvuIH6SJPU3z+amApvKwa4ADw4rpJ+F++CcPwLhulmgCqKBjTRza21mahIU7pTr/fPx
3mz/G1cmIRHSWQAp56yHUgcqs3ANKsdeefDSMpct3Nuu7Kzkp04NjNM7Y4XxogxHa/oYHQ
1Z1xuac11j4xZCo7Fq0O2s9mxANO7kt3RgOFSeCHZj8bmVXzoilK2xORkPw3TbcVxOJyY/
cqfian
-----END SSH SIGNATURE-----

this is the data that was signed:

.idea
.vscode
patchwork
bins/
db.sqlite3
db.sqlite3-shm
db.sqlite3-wal
hiddeco commented 1 month ago

Can you provide more specific details about the precise SSH version used? In addition, would you be able to provide instructions to generate a key which produces a "faulty" key?

tionis commented 1 month ago

Sure, I'm on Arch Linux and used the following openssh version:

OpenSSH_9.8p1, OpenSSL 3.3.1 4 Jun 2024

Here's also a Dockerfile to produce a unparsable signature at /test_file.sig:

FROM debian:latest
RUN apt update
RUN apt install -y openssh-client
RUN ssh-keygen -N "" -f ~/key
RUN echo "test" > test_file
RUN ssh-keygen -Y sign -f ~/key -n file test_file

The code I've used to test it essentially just does

sig, err := sshsig.ParseSignature(sigBytes)

where sigBytes are the bytes in the signature file

hiddeco commented 1 month ago

Sorry for the delay!

The problem you are running into is that you are trying to parse the signature as PEM-encoded bytes using ParseSignature. However, this function expects the signature to be in SSH wire format, which is why you are encountering an issue.

Instead, you would probably like to use Unarmor, which does accept a PEM-encoded signature. See: https://go.dev/play/p/gjxZ6r1ly4Y

hiddeco commented 1 month ago

For future searchability: you are likely running into this issue if you are presented with an ssh: unmarshal error for field PublicKey of type blob error. In this case, double-check if you use the right function for your signature bytes.

tionis commented 1 month ago

I see, thank you for looking into it and the explanation. This really helped me!