diff --git a/libagent/gpg/decode.py b/libagent/gpg/decode.py index f3b620f..20005fd 100644 --- a/libagent/gpg/decode.py +++ b/libagent/gpg/decode.py @@ -63,6 +63,17 @@ def _parse_nist256p1_pubkey(mpi): hashfunc=hashlib.sha256) +def _parse_nist521p1_pubkey(mpi): + prefix, x, y = util.split_bits(mpi, 4, 528, 528) + if prefix != 4: + raise ValueError('Invalid MPI prefix: {}'.format(prefix)) + point = ecdsa.ellipticcurve.Point(curve=ecdsa.NIST521p.curve, + x=x, y=y) + return ecdsa.VerifyingKey.from_public_point( + point=point, curve=ecdsa.curves.NIST521p, + hashfunc=hashlib.sha512) + + def _parse_ed25519_pubkey(mpi): prefix, value = util.split_bits(mpi, 8, 256) if prefix != 0x40: @@ -73,6 +84,8 @@ def _parse_ed25519_pubkey(mpi): SUPPORTED_CURVES = { b'\x2A\x86\x48\xCE\x3D\x03\x01\x07': (_parse_nist256p1_pubkey, protocol.keygrip_nist256), + b'\x2B\x81\x04\x00\x23': + (_parse_nist521p1_pubkey, protocol.keygrip_nist521), b'\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01': (_parse_ed25519_pubkey, protocol.keygrip_ed25519), b'\x2B\x06\x01\x04\x01\x97\x55\x01\x05\x01': diff --git a/libagent/gpg/protocol.py b/libagent/gpg/protocol.py index 68bb7f8..1786973 100644 --- a/libagent/gpg/protocol.py +++ b/libagent/gpg/protocol.py @@ -101,6 +101,7 @@ def _compute_keygrip(params): exp = '{}:{}{}:'.format(len(name), name, len(value)) parts.append(b'(' + exp.encode('ascii') + value + b')') + log.debug('keygrip parts: %s', parts) return hashlib.sha1(b''.join(parts)).digest() @@ -122,6 +123,23 @@ def keygrip_nist256(vk): ]) +def keygrip_nist521(vk): + """Compute keygrip for NIST521 curve public keys.""" + curve = vk.curve.curve + gen = vk.curve.generator + g = (4 << 1200) | (gen.x() << 600) | gen.y() + point = vk.pubkey.point + q = (4 << 1200) | (point.x() << 600) | point.y() + return _compute_keygrip([ + ['p', util.num2bytes(curve.p(), size=66)], + ['a', util.num2bytes(curve.a() % curve.p(), size=66)], + ['b', util.num2bytes(curve.b() % curve.p(), size=66)], + ['g', util.num2bytes(g, size=160)], + ['n', util.num2bytes(vk.curve.order, size=66)], + ['q', util.num2bytes(q, size=160)], + ]) + + def keygrip_ed25519(vk): """Compute keygrip for Ed25519 public keys.""" # pylint: disable=line-too-long