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

Vendor command for signing SHA256 hash #395

Open
rgerganov opened this issue Mar 13, 2020 · 16 comments
Open

Vendor command for signing SHA256 hash #395

rgerganov opened this issue Mar 13, 2020 · 16 comments

Comments

@rgerganov
Copy link

I wonder what others think about having a vendor command for signing an arbitrary SHA256 hash. The use case for this would be using a Solo key for file signing. The hash of the file will be computed on the host and then it will be passed to the key for signing. This is how it would look like from user perspective:

# generate a new key pair, the output is cred_id and public.pem
$ solo key make-credential

# sign "file.dat" and store the signature in "file.dat.sig"
$ solo key sign cred_id -in file.dat -out file.dat.sig

# verify the signature with openssl
$ openssl dgst -verify public.pem -keyform pem -sha256 -signature file.dat.sig file.dat

We cannot do that with the standard command for getting assertion but we can easily implement a new custom command.
Thoughts?

@nickray
Copy link
Member

nickray commented Mar 13, 2020

I like it! I made an experiment in this direction a long time ago (see CTAPHID_PROBE command, we'd want to pick a different one).

Perhaps you can open an "RFC issue" with a sketch of a plan? E.g., we'd definitely need to follow analogous "PIN rules" as elsewhere.

Additional input: I'm a big fan of OpenBSD's signify, the ultimate ideal for me would be to support being a backend for that. Directly doing so would lead to supporting Ed25519 though (for which we have https://github.com/ycrypto/salty/blob/main/c-api/salty.h, but there are complications surrounding multiple key types as raised elsewhere). So I think it would be fine to start with just P256 signatures.

(Just a nit, I'd ask that solo CLI tool use "normal" argument/option syntax, not copy openssl's weirdness).

@rgerganov
Copy link
Author

I like it! I made an experiment in this direction a long time ago (see CTAPHID_PROBE command, we'd want to pick a different one).

Interesting. I see that you choose to implement a new CTAPHID command. I was thinking of using CTAPHID_CBOR with a new vendor command. Not sure what are the pros and cons.

Perhaps you can open an "RFC issue" with a sketch of a plan? E.g., we'd definitely need to follow analogous "PIN rules" as elsewhere.

I could do that but I prefer to create a PoC first.

Additional input: I'm a big fan of OpenBSD's signify, the ultimate ideal for me would be to support being a backend for that. Directly doing so would lead to supporting Ed25519 though (for which we have https://github.com/ycrypto/salty/blob/main/c-api/salty.h, but there are complications surrounding multiple key types as raised elsewhere). So I think it would be fine to start with just P256 signatures.

Yeah, P256 is the low-hanging fruit here but I am also interested into Ed25519

@nickray
Copy link
Member

nickray commented Mar 17, 2020

Regarding CTAPHID vs. CTAPHID_CBOR vendor command: I think I was just using the easiest way I saw back then (with little understanding). Probably if you are doing something that expects a CBOR map of arguments, it makes most sense to do it with CTAPHID_CBOR (and re-use the infrastructure).

rgerganov pushed a commit to rgerganov/solo that referenced this issue Mar 19, 2020
This patch adds new CTAP2 vendor command with command value 0x50. The
command arguments are credentialId and user specified SHA256 hash. It
returns a DER encoded signature of the given hash, using the key
which corresponds to the specified credentialId.

Example request:
{1: <sha256_hash>, 2: {"id": <credential_id>, "type": "public-key"}}

Example response:
{1: <der_signature>}

Issue: solokeys#395
@rgerganov
Copy link
Author

I have the first PoC ready. You need to patch both solo and solo-python if you want to give it a try. I am also using the fido2-cred tool from libfido2.
This is how it works:

# Create a new credential and save the id and the public key  of the credential in "cred"
$ echo credential challenge | openssl sha256 -binary | base64 > cred_param
$ echo relying party >> cred_param
$ echo user name >> cred_param
$ dd if=/dev/urandom bs=1 count=32 | base64 >> cred_param
$ fido2-cred -M -i cred_param /dev/hidraw6 | fido2-cred -V -o cred
$ cat cred
8BNpSl5onmiOYJNb68ZroWJtJvveCLXyC7l/gVFG0uF/kq6wOISXyMPTdcFX7nIGmKx4eL6HCtjxqpk3L6xdtFtUGgAAAA==
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2T3KDkdhtOqVODP+4YH5k/yMzeAq
atKglLqflwzZTdHBvs6S1V9qsTC1l65DJCPZIn8MQYgsVvgwbalcgRp5Cw==
-----END PUBLIC KEY-----

# extract the public key into public.pem
$ tail -4 cred > public.pem

# generate a random file for signing
$ head -c 1M < /dev/urandom > file.dat

# sign the file with Solo
$ solo key sign-file 8BNpSl5onmiOYJNb68ZroWJtJvveCLXyC7l/gVFG0uF/kq6wOISXyMPTdcFX7nIGmKx4eL6HCtjxqpk3L6xdtFtUGgAAAA== file.dat
810743111f7f70cb64b5ef07b4930c2d2b298de743286609905b6f7873738a76  file.dat
Please press the button on your Solo key
Saving signature to file.dat.sig

# verify the signature with openssl
$ openssl dgst -verify public.pem -sha256 -signature file.dat.sig file.dat
Verified OK

rgerganov pushed a commit to rgerganov/solo that referenced this issue Mar 23, 2020
This patch adds new CTAP2 vendor command with command value 0x50. The
command arguments are credentialId and user specified SHA256 hash. It
returns a DER encoded signature of the given hash, using the key
which corresponds to the specified credentialId.

Example request:
{1: <sha256_hash>,
 2: {"id": <credential_id>, "type": "public-key"},
 3: [pinAuth]}

Example response:
{1: <der_signature>}

Issue: solokeys#395
@conorpp
Copy link
Member

conorpp commented Mar 24, 2020

I think this would be okay but I think it would have to enforce pinAuth if a PIN is set, otherwise this could be used to bypass PIN restrictions on normal FIDO2 transactions.

@rgerganov
Copy link
Author

Correct, I have added support for pinAuth in the last version of the PR. The solo key sign-file also accepts --pin now.

@My1
Copy link
Contributor

My1 commented Mar 25, 2020

The solo key sign-file also accepts --pin now.

btw might it not be nicer to have a hidden live prompt for the pin instead of giving it in the command itself (especially as most linux things I used so far keep a log of used commands which may end a bit well fun)

rgerganov pushed a commit to rgerganov/solo that referenced this issue Apr 8, 2020
This patch adds new CTAP2 vendor command with command value 0x50. The
command arguments are credentialId and user specified SHA256 hash. It
returns a DER encoded signature of the given hash, using the key
which corresponds to the specified credentialId.

Example request:
{1: <sha256_hash>,
 2: {"id": <credential_id>, "type": "public-key"},
 3: [pinAuth]}

Example response:
{1: <der_signature>}

Issue: solokeys#395
@rgerganov
Copy link
Author

I have implemented PGP signing with Solo and now I can sign git commits with my Solo Hacker! 🎉
You can find the project here: https://github.com/rgerganov/solo-pgp
The last two commits are signed with Solo :)

@conorpp @nickray if you decide to go with this vendor command, I can work on adding the PGP stuff to solo-pyton. Even though PGP is a huge clusterfuck we can implement the git signing with ~200 lines of Python code as you can see from my project.

@nickray
Copy link
Member

nickray commented Apr 10, 2020

You're awesome! Will dig in soon.

@My1
Copy link
Contributor

My1 commented Apr 10, 2020

totally sounds fun

@nickray
Copy link
Member

nickray commented Apr 11, 2020

Had a good look now @rgerganov. This is exactly how I imagined this should work :)

If you have the time/energy, would be great to add your two scripts to solo-python.

Regarding API, I'd suggest the following:

@My1
Copy link
Contributor

My1 commented Apr 11, 2020

also when running PGP why not also add something to decrypt as well? so you can have some fun with encrypted PGP mails and stuff

@nickray
Copy link
Member

nickray commented Apr 11, 2020

@My1, different topic. This is a vendor command to sign.

@rgerganov
Copy link
Author

Had a good look now @rgerganov. This is exactly how I imagined this should work :)

If you have the time/energy, would be great to add your two scripts to solo-python.

Sure, will start working on this soon.

@BrunoP-dev
Copy link

Hey 1) is their a support for that product or a forum? if not can we create one?
2) here my experimentation with that sign-file feature. Anything wrong ?
thanks
log.log

@stevenwdv
Copy link

This was referred to in #575 and I noticed it is not merged yet and hasn't seen much activity lately. Are the reasons for this similar to those mentioned in #575 (e.g. reusing authentication keys for signing etc.)?

rgerganov pushed a commit to rgerganov/solo that referenced this issue Oct 18, 2021
This patch adds new CTAP2 vendor command with command value 0x50. The
command arguments are credentialId and user specified SHA256 hash. It
returns a DER encoded signature of the given hash, using the key
which corresponds to the specified credentialId.

Example request:
{1: <sha256_hash>,
 2: {"id": <credential_id>, "type": "public-key"},
 3: [pinAuth]}

Example response:
{1: <der_signature>}

Issue: solokeys#395
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

6 participants