gpg: support Curve25519 for creating encryption subkeys

nistp521
Roman Zeyde 8 years ago
parent 5047805385
commit 8f19690943

@ -11,11 +11,15 @@ from . import util
log = logging.getLogger(__name__)
# Supported ECDSA curves
# Supported ECDSA curves (for SSH and GPG)
CURVE_NIST256 = 'nist256p1'
CURVE_ED25519 = 'ed25519'
SUPPORTED_CURVES = {CURVE_NIST256, CURVE_ED25519}
# Supported ECDH curves (for GPG)
ECDH_NIST256 = 'nist256p1'
ECDH_CURVE25519 = 'curve25519'
# SSH key types
SSH_NIST256_DER_OCTET = b'\x04'
SSH_NIST256_KEY_PREFIX = b'ecdsa-sha2-'
@ -134,7 +138,8 @@ def decompress_pubkey(pubkey, curve_name):
if len(pubkey) == 33:
decompress = {
CURVE_NIST256: _decompress_nist256,
CURVE_ED25519: _decompress_ed25519
CURVE_ED25519: _decompress_ed25519,
ECDH_CURVE25519: _decompress_ed25519,
}[curve_name]
vk = decompress(pubkey)
@ -192,3 +197,11 @@ def import_public_key(line):
assert result['type'] == file_type.encode('ascii')
log.debug('loaded %s public key: %s', file_type, result['fingerprint'])
return result
def get_ecdh_curve_name(signature_curve_name):
"""Return appropriate curve for ECDH for specified signing curve."""
return {
CURVE_NIST256: ECDH_NIST256,
CURVE_ED25519: ECDH_CURVE25519,
}[signature_curve_name]

@ -8,7 +8,7 @@ import sys
import time
from . import agent, device, encode, keyring, protocol
from .. import server
from .. import formats, server
log = logging.getLogger(__name__)
@ -32,8 +32,8 @@ def run_create(args):
verifying_key=verifying_key, ecdh=False)
# subkey for encryption
encryption_key = protocol.PublicKey(
curve_name=args.ecdsa_curve, created=args.time,
verifying_key=decryption_key, ecdh=True)
curve_name=formats.get_ecdh_curve_name(args.ecdsa_curve),
created=args.time, verifying_key=decryption_key, ecdh=True)
result = encode.create_subkey(primary_bytes=primary_bytes,
pubkey=signing_key,
signer_func=conn.sign)
@ -47,8 +47,8 @@ def run_create(args):
verifying_key=verifying_key, ecdh=False)
# subkey for encryption
subkey = protocol.PublicKey(
curve_name=args.ecdsa_curve, created=args.time,
verifying_key=decryption_key, ecdh=True)
curve_name=formats.get_ecdh_curve_name(args.ecdsa_curve),
created=args.time, verifying_key=decryption_key, ecdh=True)
result = encode.create_primary(user_id=user_id,
pubkey=primary,

@ -17,12 +17,16 @@ class HardwareSigner(object):
def pubkey(self, ecdh=False):
"""Return public key as VerifyingKey object."""
addr = util.get_bip32_address(identity=self.identity, ecdh=ecdh)
if ecdh:
curve_name = formats.get_ecdh_curve_name(self.curve_name)
else:
curve_name = self.curve_name
public_node = self.client_wrapper.connection.get_public_node(
n=addr, ecdsa_curve_name=self.curve_name)
n=addr, ecdsa_curve_name=curve_name)
return formats.decompress_pubkey(
pubkey=public_node.node.public_key,
curve_name=self.curve_name)
curve_name=curve_name)
def sign(self, digest):
"""Sign the digest and return a serialized signature."""
@ -40,7 +44,7 @@ class HardwareSigner(object):
result = self.client_wrapper.connection.get_ecdh_session_key(
identity=self.identity,
peer_public_key=pubkey,
ecdsa_curve_name=self.curve_name)
ecdsa_curve_name=formats.get_ecdh_curve_name(self.curve_name))
assert len(result.session_key) == 65
assert result.session_key[:1] == b'\x04'
return result.session_key

@ -141,7 +141,13 @@ SUPPORTED_CURVES = {
'algo_id': 22,
'serialize': _serialize_ed25519,
'keygrip': _keygrip_ed25519,
}
},
formats.ECDH_CURVE25519: {
'oid': b'\x2B\x06\x01\x04\x01\x97\x55\x01\x05\x01',
'algo_id': 18,
'serialize': _serialize_ed25519,
'keygrip': _keygrip_ed25519,
},
}
ECDH_ALGO_ID = 18

Loading…
Cancel
Save