Allow unicode in identity string for SSH and GPG
This commit is contained in:
@@ -6,6 +6,8 @@ import logging
|
||||
import re
|
||||
import struct
|
||||
|
||||
import unidecode
|
||||
|
||||
from .. import formats, util
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -67,7 +69,13 @@ class Identity(object):
|
||||
|
||||
def items(self):
|
||||
"""Return a copy of identity_dict items."""
|
||||
return self.identity_dict.items()
|
||||
return [(k, unidecode.unidecode(v))
|
||||
for k, v in self.identity_dict.items()]
|
||||
|
||||
def to_bytes(self):
|
||||
"""Transliterate Unicode into ASCII."""
|
||||
s = identity_to_string(self.identity_dict)
|
||||
return unidecode.unidecode(s).encode('ascii')
|
||||
|
||||
def __str__(self):
|
||||
"""Return identity serialized to string."""
|
||||
@@ -76,7 +84,7 @@ class Identity(object):
|
||||
def get_bip32_address(self, ecdh=False):
|
||||
"""Compute BIP32 derivation address according to SLIP-0013/0017."""
|
||||
index = struct.pack('<L', self.identity_dict.get('index', 0))
|
||||
addr = index + identity_to_string(self.identity_dict).encode('ascii')
|
||||
addr = index + self.to_bytes()
|
||||
log.debug('bip32 address string: %r', addr)
|
||||
digest = hashlib.sha256(addr).digest()
|
||||
s = io.BytesIO(bytearray(digest))
|
||||
|
||||
@@ -193,7 +193,7 @@ def import_public_key(line):
|
||||
file_type, base64blob, name = line.split()
|
||||
blob = base64.b64decode(base64blob)
|
||||
result = parse_pubkey(blob)
|
||||
result['name'] = name.encode('ascii')
|
||||
result['name'] = name.encode('utf-8')
|
||||
assert result['type'] == file_type.encode('ascii')
|
||||
log.debug('loaded %s public key: %s', file_type, result['fingerprint'])
|
||||
return result
|
||||
|
||||
@@ -112,7 +112,7 @@ class Handler(object):
|
||||
pubkey_dict, user_ids = decode.load_by_keygrip(
|
||||
pubkey_bytes=self.pubkey_bytes, keygrip=keygrip_bytes)
|
||||
# We assume the first user ID is used to generate TREZOR-based GPG keys.
|
||||
user_id = user_ids[0]['value'].decode('ascii')
|
||||
user_id = user_ids[0]['value'].decode('utf-8')
|
||||
curve_name = protocol.get_curve_name_by_oid(pubkey_dict['curve_oid'])
|
||||
ecdh = (pubkey_dict['algo'] == protocol.ECDH_ALGO_ID)
|
||||
|
||||
|
||||
@@ -12,12 +12,10 @@ def create_primary(user_id, pubkey, signer_func, secret_bytes=b''):
|
||||
"""Export new primary GPG public key, ready for "gpg2 --import"."""
|
||||
pubkey_packet = protocol.packet(tag=(5 if secret_bytes else 6),
|
||||
blob=(pubkey.data() + secret_bytes))
|
||||
user_id_packet = protocol.packet(tag=13,
|
||||
blob=user_id.encode('ascii'))
|
||||
|
||||
data_to_sign = (pubkey.data_to_hash() +
|
||||
user_id_packet[:1] +
|
||||
util.prefix_len('>L', user_id.encode('ascii')))
|
||||
user_id_bytes = user_id.encode('utf-8')
|
||||
user_id_packet = protocol.packet(tag=13, blob=user_id_bytes)
|
||||
data_to_sign = (pubkey.data_to_hash() + user_id_packet[:1] +
|
||||
util.prefix_len('>L', user_id_bytes))
|
||||
hashed_subpackets = [
|
||||
protocol.subpacket_time(pubkey.created), # signature time
|
||||
# https://tools.ietf.org/html/rfc4880#section-5.2.3.7
|
||||
|
||||
@@ -188,7 +188,7 @@ def main(device_type):
|
||||
public_keys = None
|
||||
if args.identity.startswith('/'):
|
||||
filename = args.identity
|
||||
contents = open(filename, 'rb').read().decode('ascii')
|
||||
contents = open(filename, 'rb').read().decode('utf-8')
|
||||
# Allow loading previously exported SSH public keys
|
||||
if filename.endswith('.pub'):
|
||||
public_keys = list(import_public_keys(contents))
|
||||
|
||||
@@ -138,7 +138,7 @@ class Handler(object):
|
||||
else:
|
||||
raise KeyError('key not found')
|
||||
|
||||
label = key['name'].decode('ascii') # label should be a string
|
||||
label = key['name'].decode('utf-8')
|
||||
log.debug('signing %d-byte blob with "%s" key', len(blob), label)
|
||||
try:
|
||||
signature = self.conn.sign(blob=blob, identity=key['identity'])
|
||||
|
||||
7
libagent/tests/test_interface.py
Normal file
7
libagent/tests/test_interface.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from ..device import interface
|
||||
|
||||
|
||||
def test_unicode():
|
||||
i = interface.Identity(u'ko\u017eu\u0161\u010dek@host', 'ed25519')
|
||||
assert i.to_bytes() == b'kozuscek@host'
|
||||
assert sorted(i.items()) == [('host', 'host'), ('user', 'kozuscek')]
|
||||
Reference in New Issue
Block a user