Browse Source

test_onion.py: control generate/decode from command line

ppa-0.6.1
Anthony Towns 10 years ago
parent
commit
626be23180
  1. 98
      test/test_onion.py

98
test/test_onion.py

@ -1,6 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
import argparse
import sys import sys
import time
from hashlib import sha256 from hashlib import sha256
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
@ -139,6 +141,16 @@ def get_pos_y_for_x(pubkey_x, yneg=0):
if pub_key_x is not None: OpenSSL.BN_free(pub_key_x) if pub_key_x is not None: OpenSSL.BN_free(pub_key_x)
if pub_key_y is not None: OpenSSL.BN_free(pub_key_y) if pub_key_y is not None: OpenSSL.BN_free(pub_key_y)
def ec_decompress(pubkey, curve='secp256k1'):
if pubkey[0] == '\x02' or pubkey[0] == '\x03':
yneg = ord(pubkey[0]) & 1
pubkey = "\x04" + pubkey[1:] + get_pos_y_for_x(pubkey[1:], yneg=yneg)
elif pubkey[0] == '\x04':
pass
else:
raise Exception("Unrecognised pubkey format: %s" % (pubkey,))
return pubkey
class Onion(object): class Onion(object):
HMAC_LEN = 32 HMAC_LEN = 32
PKEY_LEN = 32 PKEY_LEN = 32
@ -282,48 +294,52 @@ class OnionEncrypt(Onion):
msgenc += hmac_sha256(hmacs[i], msgenc) msgenc += hmac_sha256(hmacs[i], msgenc)
self.onion = msgenc self.onion = msgenc
def decode_from_file(f): def generate(args):
keys = [] server_keys = []
msg = "" msgs = []
for ln in f.readlines(): for k in args.pubkeys:
if ln.startswith(" * Keypair "): k = unhexlify(k)
w = ln.strip().split() msgs.append("Message for %s..." % (hexlify(k[1:21]),))
idx = int(w[2].strip(":")) k = ec_decompress(k)
priv = unhexlify(w[3]) server_keys.append(k)
pub = unhexlify(w[4]) o = OnionEncrypt(msgs, server_keys)
assert idx == len(keys) sys.stdout.write(o.onion)
keys.append(ecc.ECC(privkey=priv, pubkey=pub, curve='secp256k1')) return
elif ln.startswith(" * Message:"):
msg = unhexlify(ln[11:].strip()) def decode(args):
elif ln.startswith("Decrypting"): msg = sys.stdin.read()
pass key = ecc.ECC(privkey=unhexlify(args.seckey),
else: pubkey=ec_decompress(unhexlify(args.pubkey)),
print ln curve='secp256k1')
assert ln.strip() == "" o = OnionDecrypt(msg, key)
assert msg != ""
for k in keys:
o = OnionDecrypt(msg, k)
o.decrypt() o.decrypt()
print o.msg #sys.stderr.write("Message: \"%s\"\n" % (o.msg,))
msg = o.fwd want_msg = "Message for %s..." % (args.pubkey[2:42])
print "done" if o.msg != want_msg + "\0"*(Onion.MSG_LEN - len(want_msg)):
raise Exception("Unexpected message: \"%s\" (wanted: %s)" % (o.msg, want_msg))
if __name__ == "__main__": sys.stdout.write(o.fwd)
if len(sys.argv) > 1 and sys.argv[1] == "generate":
if len(sys.argv) == 3:
n = int(sys.argv[2])
else:
n = 20
servers = [ecc.ECC(curve='secp256k1') for _ in range(n)]
server_pubs = [s.get_pubkey() for s in servers]
msgs = ["Howzit %d..." % (i,) for i in range(n)]
o = OnionEncrypt(msgs, server_pubs) def main(argv):
parser = argparse.ArgumentParser(description="Process some integers.")
sp = parser.add_subparsers()
p = sp.add_parser("generate")
p.add_argument("pubkeys", nargs='+', help="public keys of recipients")
p.set_defaults(func=generate)
p = sp.add_parser("decode")
p.add_argument("seckey", help="secret key for router")
p.add_argument("pubkey", help="public key for router")
p.set_defaults(func=decode)
args = parser.parse_args(argv)
return args.func(args)
if __name__ == "__main__":
main(sys.argv[1:])
sys.exit(0)
for i, s in enumerate(servers):
print " * Keypair %d: %s %s" % (
i, hexlify(s.privkey), hexlify(s.get_pubkey()))
print " * Message: %s" % (hexlify(o.onion))
else:
decode_from_file(sys.stdin)

Loading…
Cancel
Save