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 · 7 comments
Open

Vendor command for signing SHA256 hash #395

rgerganov opened this issue Mar 13, 2020 · 7 comments

Comments

@rgerganov
Copy link
Contributor

@rgerganov rgerganov commented Mar 13, 2020

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

This comment has been minimized.

Copy link
Member

@nickray 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

This comment has been minimized.

Copy link
Contributor Author

@rgerganov rgerganov 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).

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

This comment has been minimized.

Copy link
Member

@nickray 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 added 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

This comment has been minimized.

Copy link
Contributor Author

@rgerganov rgerganov commented Mar 19, 2020

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 added 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

This comment has been minimized.

Copy link
Contributor

@conorpp 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

This comment has been minimized.

Copy link
Contributor Author

@rgerganov rgerganov commented Mar 24, 2020

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

@My1

This comment has been minimized.

Copy link
Contributor

@My1 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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.