mirror of
https://github.com/romanz/amodem.git
synced 2026-04-23 06:46:27 +08:00
signer: refactor a bit
This commit is contained in:
@@ -9,8 +9,6 @@ import struct
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import ecdsa
|
|
||||||
|
|
||||||
import decode
|
import decode
|
||||||
import trezor_agent.client
|
import trezor_agent.client
|
||||||
import trezor_agent.formats
|
import trezor_agent.formats
|
||||||
@@ -75,18 +73,18 @@ def hexlify(blob):
|
|||||||
|
|
||||||
class Signer(object):
|
class Signer(object):
|
||||||
|
|
||||||
curve = ecdsa.NIST256p
|
|
||||||
ecdsa_curve_name = trezor_agent.formats.CURVE_NIST256
|
ecdsa_curve_name = trezor_agent.formats.CURVE_NIST256
|
||||||
|
|
||||||
def __init__(self, user_id, created):
|
def __init__(self, user_id, created):
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self.client_wrapper = trezor_agent.factory.load()
|
self.client_wrapper = trezor_agent.factory.load()
|
||||||
|
|
||||||
# This requires the following patch to trezor-mcu to work:
|
# This requires the following patch to trezor-mcu in order to work:
|
||||||
# https://gist.github.com/romanz/b66f5df1ca8ef15641df8ea5bb09fd47
|
# https://gist.github.com/romanz/b66f5df1ca8ef15641df8ea5bb09fd47
|
||||||
self.identity = self.client_wrapper.identity_type()
|
self.identity = self.client_wrapper.identity_type()
|
||||||
self.identity.proto = 'gpg'
|
self.identity.proto = 'gpg'
|
||||||
self.identity.host = user_id
|
self.identity.host = user_id
|
||||||
|
|
||||||
addr = trezor_agent.client.get_address(self.identity)
|
addr = trezor_agent.client.get_address(self.identity)
|
||||||
public_node = self.client_wrapper.connection.get_public_node(
|
public_node = self.client_wrapper.connection.get_public_node(
|
||||||
n=addr, ecdsa_curve_name=self.ecdsa_curve_name)
|
n=addr, ecdsa_curve_name=self.ecdsa_curve_name)
|
||||||
@@ -96,36 +94,41 @@ class Signer(object):
|
|||||||
curve_name=self.ecdsa_curve_name)
|
curve_name=self.ecdsa_curve_name)
|
||||||
|
|
||||||
self.created = int(created)
|
self.created = int(created)
|
||||||
|
self.pubkey_point = verifying_key.pubkey.point
|
||||||
|
log.info('key %s created at %s',
|
||||||
|
hexlify(self._fingerprint()[-4:]), time_format(self.created))
|
||||||
|
|
||||||
|
def _pubkey_data(self):
|
||||||
header = struct.pack('>BLB',
|
header = struct.pack('>BLB',
|
||||||
4, # version
|
4, # version
|
||||||
self.created, # creation
|
self.created, # creation
|
||||||
19) # ECDSA
|
19) # ECDSA
|
||||||
|
|
||||||
# https://tools.ietf.org/html/rfc6637#section-11 (NIST P-256 OID)
|
# https://tools.ietf.org/html/rfc6637#section-11 (NIST P-256 OID)
|
||||||
oid = prefix_len('>B', b'\x2A\x86\x48\xCE\x3D\x03\x01\x07')
|
oid = prefix_len('>B', b'\x2A\x86\x48\xCE\x3D\x03\x01\x07')
|
||||||
|
return header + oid + mpi((4 << 512) |
|
||||||
|
(self.pubkey_point.x() << 256) |
|
||||||
|
(self.pubkey_point.y()))
|
||||||
|
|
||||||
self._point = verifying_key.pubkey.point
|
def _pubkey_data_to_hash(self):
|
||||||
self.pubkey_data = header + oid + mpi((4 << 512) |
|
return b'\x99' + prefix_len('>H', self._pubkey_data())
|
||||||
(self._point.x() << 256) |
|
|
||||||
(self._point.y()))
|
|
||||||
|
|
||||||
self.data_to_hash = b'\x99' + prefix_len('>H', self.pubkey_data)
|
def _fingerprint(self):
|
||||||
fingerprint = hashlib.sha1(self.data_to_hash).digest()
|
return hashlib.sha1(self._pubkey_data_to_hash()).digest()
|
||||||
self.key_id = fingerprint[-8:]
|
|
||||||
log.info('key %s created at %s',
|
def key_id(self):
|
||||||
hexlify(fingerprint[-4:]), time_format(self.created))
|
return self._fingerprint()[-8:]
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.client_wrapper.connection.clear_session()
|
self.client_wrapper.connection.clear_session()
|
||||||
self.client_wrapper.connection.close()
|
self.client_wrapper.connection.close()
|
||||||
|
|
||||||
def export(self):
|
def export(self):
|
||||||
pubkey_packet = packet(tag=6, blob=self.pubkey_data)
|
pubkey_packet = packet(tag=6, blob=self._pubkey_data())
|
||||||
user_id_packet = packet(tag=13, blob=self.user_id)
|
user_id_packet = packet(tag=13, blob=self.user_id)
|
||||||
|
|
||||||
user_id_to_hash = user_id_packet[:1] + prefix_len('>L', self.user_id)
|
user_id_to_hash = user_id_packet[:1] + prefix_len('>L', self.user_id)
|
||||||
data_to_sign = self.data_to_hash + user_id_to_hash
|
data_to_sign = self._pubkey_data_to_hash() + user_id_to_hash
|
||||||
key_id = hexlify(self.key_id[-4:])
|
key_id = hexlify(self.key_id()[-4:])
|
||||||
log.info('signing public key "%s": %s', self.user_id, key_id)
|
log.info('signing public key "%s": %s', self.user_id, key_id)
|
||||||
hashed_subpackets = [
|
hashed_subpackets = [
|
||||||
subpacket_time(self.created), # signature creaion time
|
subpacket_time(self.created), # signature creaion time
|
||||||
@@ -148,7 +151,7 @@ class Signer(object):
|
|||||||
log.info('signing message %r at %s', msg,
|
log.info('signing message %r at %s', msg,
|
||||||
time_format(sign_time))
|
time_format(sign_time))
|
||||||
hashed_subpackets = [subpacket_time(sign_time)]
|
hashed_subpackets = [subpacket_time(sign_time)]
|
||||||
key_id = hexlify(self.key_id[-4:])
|
key_id = hexlify(self.key_id()[-4:])
|
||||||
blob = self._make_signature(
|
blob = self._make_signature(
|
||||||
visual=key_id,
|
visual=key_id,
|
||||||
data_to_sign=msg, hashed_subpackets=hashed_subpackets)
|
data_to_sign=msg, hashed_subpackets=hashed_subpackets)
|
||||||
@@ -163,7 +166,7 @@ class Signer(object):
|
|||||||
8) # hash_alg (SHA256)
|
8) # hash_alg (SHA256)
|
||||||
hashed = subpackets(*hashed_subpackets)
|
hashed = subpackets(*hashed_subpackets)
|
||||||
unhashed = subpackets(
|
unhashed = subpackets(
|
||||||
subpacket(16, self.key_id) # issuer key id
|
subpacket(16, self.key_id()) # issuer key id
|
||||||
)
|
)
|
||||||
tail = b'\x04\xff' + struct.pack('>L', len(header) + len(hashed))
|
tail = b'\x04\xff' + struct.pack('>L', len(header) + len(hashed))
|
||||||
data_to_hash = data_to_sign + header + hashed + tail
|
data_to_hash = data_to_sign + header + hashed + tail
|
||||||
@@ -180,7 +183,8 @@ class Signer(object):
|
|||||||
sig = result.signature[1:]
|
sig = result.signature[1:]
|
||||||
sig = [trezor_agent.util.bytes2num(sig[:32]),
|
sig = [trezor_agent.util.bytes2num(sig[:32]),
|
||||||
trezor_agent.util.bytes2num(sig[32:])]
|
trezor_agent.util.bytes2num(sig[32:])]
|
||||||
decode.verify_digest(pubkey={'point': (self._point.x(), self._point.y())},
|
decode.verify_digest(pubkey={'point': (self.pubkey_point.x(),
|
||||||
|
self.pubkey_point.y())},
|
||||||
digest=digest,
|
digest=digest,
|
||||||
signature=sig, label='GPG signature')
|
signature=sig, label='GPG signature')
|
||||||
|
|
||||||
@@ -233,7 +237,7 @@ def main():
|
|||||||
else:
|
else:
|
||||||
pubkey = load_from_gpg(args.user_id)
|
pubkey = load_from_gpg(args.user_id)
|
||||||
s = Signer(user_id=user_id, created=pubkey['created'])
|
s = Signer(user_id=user_id, created=pubkey['created'])
|
||||||
assert s.key_id == pubkey['key_id']
|
assert s.key_id() == pubkey['key_id']
|
||||||
|
|
||||||
data = open(args.filename, 'rb').read()
|
data = open(args.filename, 'rb').read()
|
||||||
sig, ext = s.sign(data), '.sig'
|
sig, ext = s.sign(data), '.sig'
|
||||||
|
|||||||
Reference in New Issue
Block a user