Skip to content

Commit

Permalink
PoC: Add new command for signing a file
Browse files Browse the repository at this point in the history
It has the following syntax:
solo key sign-file <cred_id> <filename>

It computes SHA256 hash of the specified file and then signs the hash
with the key that corresponds to the given credentialId. The result is
DER encoded ECDSA signature which is saved to "<filename>.sig".
  • Loading branch information
rgerganov committed Mar 23, 2020
1 parent fa65330 commit cd7829b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
29 changes: 29 additions & 0 deletions solo/cli/key.py
Expand Up @@ -7,7 +7,9 @@
# http://opensource.org/licenses/MIT>, at your option. This file may not be
# copied, modified, or distributed except according to those terms.

import base64
import getpass
import hashlib
import os
import sys
import time
Expand Down Expand Up @@ -464,6 +466,32 @@ def disable_updates(serial):
print("Failed to disable the firmware update.")


@click.command()
@click.option("--pin", help="PIN for to access key")
@click.option("-s", "--serial", help="Serial number of Solo to use")
@click.argument("credential-id")
@click.argument("filename")
def sign_file(pin, serial, credential_id, filename):
"""Sign the specified file using the given credential-id"""

dev = solo.client.find(serial)
dgst = hashlib.sha256()
with open(filename, "rb") as f:
while True:
data = f.read(64*1024)
if not data:
break
dgst.update(data)
print("{0} {1}".format(dgst.hexdigest(), filename))
print("Please press the button on your Solo key")
ret = dev.sign_hash(base64.b64decode(credential_id), dgst.digest(), pin)
sig = ret[1]
sig_file = filename + ".sig"
print("Saving signature to " + sig_file)
with open(sig_file, 'wb') as f:
f.write(sig)


key.add_command(rng)
rng.add_command(hexbytes)
rng.add_command(raw)
Expand All @@ -482,3 +510,4 @@ def disable_updates(serial):
key.add_command(wink)
key.add_command(disable_updates)
key.add_command(ping)
key.add_command(sign_file)
9 changes: 9 additions & 0 deletions solo/client.py
Expand Up @@ -22,6 +22,7 @@
from fido2.ctap1 import CTAP1
from fido2.ctap2 import CTAP2
from fido2.hid import CTAPHID, CtapHidDevice
from fido2.utils import hmac_sha256
from fido2.webauthn import PublicKeyCredentialCreationOptions
from intelhex import IntelHex

Expand Down Expand Up @@ -316,6 +317,14 @@ def disable_solo_bootloader(self,):
self.exchange(SoloBootloader.reboot)
return True

def sign_hash(self, credential_id, dgst, pin):
if pin:
pin_token = self.client.pin_protocol.get_pin_token(pin)
pin_auth = hmac_sha256(pin_token, dgst)[:16]
return self.ctap2.send_cbor(0x50, {1: dgst, 2: {"id": credential_id, "type": "public-key"}, 3: pin_auth})
else:
return self.ctap2.send_cbor(0x50, {1: dgst, 2: {"id": credential_id, "type": "public-key"}})

def program_file(self, name):
def parseField(f):
return base64.b64decode(helpers.from_websafe(f).encode())
Expand Down

0 comments on commit cd7829b

Please sign in to comment.