Ticket #29134: x25519-gen.py

File x25519-gen.py, 1.8 KB (added by pastly, 4 months ago)
Line 
1#!/usr/bin/env python3
2import base64
3import os
4import sys
5try:
6    import nacl.public
7except ImportError:
8    print('PyNaCl is required: "pip install pynacl" or similar')
9    exit(1)
10
11
12def fname_gen(prefix, extension, length):
13    n = 0
14    while True:
15        format_str = '{0:0%s}' % length
16        fname = format_str.format(n) + extension
17        s = os.path.join(prefix, fname)
18        yield s
19        n += 1
20
21def server_client_fname_pair(server_prefix, client_prefix, length):
22    s_gen = fname_gen(server_prefix, '.auth', length)
23    c_gen = fname_gen(client_prefix, '.auth_private', length)
24    while True:
25        yield next(s_gen), next(c_gen)
26
27
28def key_str(key):
29    # bytes to base 32
30    key_bytes = bytes(key)
31    key_b32 = base64.b32encode(key_bytes)
32    # strip trailing ====
33    assert key_b32[-4:] == b'===='
34    key_b32 = key_b32[:-4]
35    # change from b'ASDF' to ASDF
36    s = key_b32.decode('utf-8')
37    return s
38
39
40def server_auth_string(key_str):
41    return 'descriptor:x25519:%s' % key_str
42
43
44def client_auth_string(onion_str, key_str):
45    return '%s:descriptor:x25519:%s' % (onion_str, key_str)
46
47
48def main(onion_str, num_clients, server_prefix, client_prefix):
49    fname_pairs = server_client_fname_pair(
50        server_prefix, client_prefix, len(str(num_clients)))
51    for _ in range(num_clients):
52        priv_key = nacl.public.PrivateKey.generate()
53        pub_key = priv_key.public_key
54        s_fname, c_fname = next(fname_pairs)
55        with open(s_fname, 'wt') as fd:
56            fd.write(server_auth_string(key_str(pub_key)))
57        with open(c_fname, 'wt') as fd:
58            fd.write(client_auth_string(onion_str, key_str(pub_key)))
59    print('Done')
60
61
62if __name__ == '__main__':
63    onion = sys.argv[1]
64    num_clients = int(sys.argv[2])
65    s_prefix = sys.argv[3]
66    c_prefix = sys.argv[4]
67    main(onion, num_clients, s_prefix, c_prefix)