mirror of
https://github.com/romanz/amodem.git
synced 2026-04-21 05:36:42 +08:00
gpg: initial support for ElGamal and DSA
Doesn't verify anything (yet).
This commit is contained in:
@@ -83,6 +83,8 @@ def _parse_ecdsa_sig(args):
|
|||||||
return (util.bytes2num(sig_r),
|
return (util.bytes2num(sig_r),
|
||||||
util.bytes2num(sig_s))
|
util.bytes2num(sig_s))
|
||||||
|
|
||||||
|
_parse_dsa_sig = _parse_ecdsa_sig
|
||||||
|
|
||||||
|
|
||||||
def _parse_rsa_sig(args):
|
def _parse_rsa_sig(args):
|
||||||
(s, sig_s), = args
|
(s, sig_s), = args
|
||||||
@@ -94,7 +96,9 @@ def _parse_sig(sig):
|
|||||||
label, sig = sig
|
label, sig = sig
|
||||||
assert label == 'sig-val'
|
assert label == 'sig-val'
|
||||||
algo_name = sig[0]
|
algo_name = sig[0]
|
||||||
parser = {'rsa': _parse_rsa_sig, 'ecdsa': _parse_ecdsa_sig}[algo_name]
|
parser = {'rsa': _parse_rsa_sig,
|
||||||
|
'ecdsa': _parse_ecdsa_sig,
|
||||||
|
'dsa': _parse_dsa_sig}[algo_name]
|
||||||
return parser(args=sig[1:])
|
return parser(args=sig[1:])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ def parse_mpi(s):
|
|||||||
return sum(v << (8 * i) for i, v in enumerate(reversed(blob)))
|
return sum(v << (8 * i) for i, v in enumerate(reversed(blob)))
|
||||||
|
|
||||||
|
|
||||||
|
def parse_mpis(s, n):
|
||||||
|
"""Parse multiple MPIs from stream."""
|
||||||
|
return [parse_mpi(s) for _ in range(n)]
|
||||||
|
|
||||||
|
|
||||||
def _parse_nist256p1_verifier(mpi):
|
def _parse_nist256p1_verifier(mpi):
|
||||||
prefix, x, y = util.split_bits(mpi, 4, 256, 256)
|
prefix, x, y = util.split_bits(mpi, 4, 256, 256)
|
||||||
assert prefix == 4
|
assert prefix == 4
|
||||||
@@ -90,6 +95,9 @@ SUPPORTED_CURVES = {
|
|||||||
b'\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01': _parse_ed25519_verifier,
|
b'\x2B\x06\x01\x04\x01\xDA\x47\x0F\x01': _parse_ed25519_verifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RSA_ALGO_IDS = {1, 2, 3}
|
||||||
|
ELGAMAL_ALGO_ID = 16
|
||||||
|
DSA_ALGO_ID = 17
|
||||||
ECDSA_ALGO_IDS = {18, 19, 22} # {ecdsa, nist256, ed25519}
|
ECDSA_ALGO_IDS = {18, 19, 22} # {ecdsa, nist256, ed25519}
|
||||||
|
|
||||||
|
|
||||||
@@ -142,8 +150,12 @@ def _parse_signature(stream):
|
|||||||
p['hash_prefix'] = stream.readfmt('2s')
|
p['hash_prefix'] = stream.readfmt('2s')
|
||||||
if p['pubkey_alg'] in ECDSA_ALGO_IDS:
|
if p['pubkey_alg'] in ECDSA_ALGO_IDS:
|
||||||
p['sig'] = (parse_mpi(stream), parse_mpi(stream))
|
p['sig'] = (parse_mpi(stream), parse_mpi(stream))
|
||||||
else: # RSA
|
elif p['pubkey_alg'] in RSA_ALGO_IDS: # RSA
|
||||||
p['sig'] = (parse_mpi(stream),)
|
p['sig'] = (parse_mpi(stream),)
|
||||||
|
elif p['pubkey_alg'] == DSA_ALGO_ID:
|
||||||
|
p['sig'] = (parse_mpi(stream), parse_mpi(stream))
|
||||||
|
else:
|
||||||
|
log.error('unsupported public key algo: %d', p['pubkey_alg'])
|
||||||
|
|
||||||
assert not stream.read()
|
assert not stream.read()
|
||||||
return p
|
return p
|
||||||
@@ -176,12 +188,15 @@ def _parse_pubkey(stream, packet_type='pubkey'):
|
|||||||
size, = util.readfmt(leftover, 'B')
|
size, = util.readfmt(leftover, 'B')
|
||||||
p['kdf'] = leftover.read(size)
|
p['kdf'] = leftover.read(size)
|
||||||
assert not leftover.read()
|
assert not leftover.read()
|
||||||
else: # RSA
|
elif p['algo'] == DSA_ALGO_ID:
|
||||||
|
log.warning('DSA signatures are not verified')
|
||||||
|
parse_mpis(stream, n=4)
|
||||||
|
elif p['algo'] == ELGAMAL_ALGO_ID:
|
||||||
|
log.warning('ElGamal signatures are not verified')
|
||||||
|
parse_mpis(stream, n=3)
|
||||||
|
else: # assume RSA
|
||||||
log.debug('parsing RSA key')
|
log.debug('parsing RSA key')
|
||||||
n = parse_mpi(stream)
|
n, e = parse_mpis(stream, n=2)
|
||||||
e = parse_mpi(stream)
|
|
||||||
log.debug('n: %x (%d bits)', n, n.bit_length())
|
|
||||||
log.debug('e: %x (%d bits)', e, e.bit_length())
|
|
||||||
p['verifier'] = _create_rsa_verifier(n, e)
|
p['verifier'] = _create_rsa_verifier(n, e)
|
||||||
assert not stream.read()
|
assert not stream.read()
|
||||||
|
|
||||||
@@ -266,8 +281,11 @@ def load_public_key(stream, use_custom=False):
|
|||||||
digest = digest_packets([pubkey, userid, signature])
|
digest = digest_packets([pubkey, userid, signature])
|
||||||
assert signature['hash_prefix'] == digest[:2]
|
assert signature['hash_prefix'] == digest[:2]
|
||||||
log.debug('loaded public key "%s"', userid['value'])
|
log.debug('loaded public key "%s"', userid['value'])
|
||||||
verify_digest(pubkey=pubkey, digest=digest,
|
if pubkey.get('verifier'):
|
||||||
signature=signature['sig'], label='GPG public key')
|
verify_digest(pubkey=pubkey, digest=digest,
|
||||||
|
signature=signature['sig'], label='GPG public key')
|
||||||
|
else:
|
||||||
|
log.warning('public key %s cannot be verified!', util.hexlify(pubkey['key_id']))
|
||||||
|
|
||||||
packet = pubkey
|
packet = pubkey
|
||||||
while use_custom:
|
while use_custom:
|
||||||
|
|||||||
Reference in New Issue
Block a user