[tor-commits] [tor/master] Commit the script I used to generate signed ri and ei documents

nickm at torproject.org nickm at torproject.org
Mon Oct 13 18:33:50 UTC 2014


commit b42d811718ec9661cf930ee64ce353624faf2be0
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Oct 7 12:36:45 2014 -0400

    Commit the script I used to generate signed ri and ei documents
---
 scripts/codegen/makedesc.py |  218 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 218 insertions(+)

diff --git a/scripts/codegen/makedesc.py b/scripts/codegen/makedesc.py
new file mode 100644
index 0000000..e0b2aed
--- /dev/null
+++ b/scripts/codegen/makedesc.py
@@ -0,0 +1,218 @@
+#!/usr/bin/python
+# Copyright 2014, The Tor Project, Inc.
+# See LICENSE for license information
+
+# This is a kludgey python script that uses ctypes and openssl to sign
+# router descriptors and extrainfo documents and put all the keys in
+# the right places.  There are examples at the end of the file.
+
+# I've used this to make inputs for unit tests.  I wouldn't suggest
+# using it for anything else.
+
+import base64
+import binascii
+import ctypes
+import ctypes.util
+import hashlib
+
+crypt = ctypes.CDLL(ctypes.util.find_library('crypto'))
+BIO_s_mem = crypt.BIO_s_mem
+BIO_s_mem.argtypes = []
+BIO_s_mem.restype = ctypes.c_void_p
+
+BIO_new = crypt.BIO_new
+BIO_new.argtypes = [ctypes.c_void_p]
+BIO_new.restype = ctypes.c_void_p
+
+RSA_generate_key = crypt.RSA_generate_key
+RSA_generate_key.argtypes = [ctypes.c_int, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
+RSA_generate_key.restype = ctypes.c_void_p
+
+RSA_private_encrypt = crypt.RSA_private_encrypt
+RSA_private_encrypt.argtypes = [
+    ctypes.c_int, ctypes.c_char_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int ]
+RSA_private_encrypt.restype = ctypes.c_int
+
+i2d_RSAPublicKey = crypt.i2d_RSAPublicKey
+i2d_RSAPublicKey.argtypes = [
+    ctypes.c_void_p, ctypes.POINTER(ctypes.c_char_p)
+]
+i2d_RSAPublicKey.restype = ctypes.c_int
+
+def b64(x):
+    x = base64.b64encode(x)
+    res = []
+    for i in xrange(0, len(x), 64):
+        res.append(x[i:i+64]+"\n")
+    return "".join(res)
+
+def bio_extract(bio):
+    buf = ctypes.c_char_p()
+    length = crypt.BIO_ctrl(bio, 3, 0, ctypes.byref(buf))
+    return ctypes.string_at(buf, length)
+
+def make_key(e=65537):
+    rsa = crypt.RSA_generate_key(1024, e, None, None)
+    bio = BIO_new(BIO_s_mem())
+    crypt.PEM_write_bio_RSAPublicKey(bio, rsa)
+    pem = bio_extract(bio).rstrip()
+    crypt.BIO_free(bio)
+
+    buf = ctypes.create_string_buffer(1024)
+    pBuf = ctypes.c_char_p(ctypes.addressof(buf))
+    n = crypt.i2d_RSAPublicKey(rsa, ctypes.byref(pBuf))
+    s = buf.raw[:n]
+    digest = hashlib.sha1(s).digest()
+
+    return (rsa,pem,digest)
+
+def signdesc(body, args_out=None):
+    rsa, ident_pem, id_digest = make_key()
+    _, onion_pem, _ = make_key()
+
+    hexdigest = binascii.b2a_hex(id_digest).upper()
+    fingerprint = " ".join(hexdigest[i:i+4] for i in range(0,len(hexdigest),4))
+
+    MAGIC = "<<<<<<MAGIC>>>>>>"
+    args = {
+        "RSA-IDENTITY" : ident_pem,
+        "ONION-KEY" : onion_pem,
+        "FINGERPRINT" : fingerprint,
+        "FINGERPRINT-NOSPACE" : hexdigest,
+        "RSA-SIGNATURE" : MAGIC
+    }
+    if args_out:
+        args_out.update(args)
+    body = body.format(**args)
+
+    idx = body.rindex("\nrouter-signature")
+    end_of_sig = body.index("\n", idx+1)
+
+    signed_part = body[:end_of_sig+1]
+
+    digest = hashlib.sha1(signed_part).digest()
+    assert len(digest) == 20
+
+    buf = ctypes.create_string_buffer(1024)
+    n = RSA_private_encrypt(20, digest, buf, rsa, 1)
+    sig = buf.raw[:n]
+
+    sig = """-----BEGIN SIGNATURE-----
+%s
+-----END SIGNATURE-----""" % b64(sig).rstrip()
+    body = body.replace(MAGIC, sig)
+
+    return body.rstrip()
+
+def emit_ri(name, body, args_out=None):
+    print "const char %s[] ="%name
+    body = "\n".join(line.rstrip() for line in body.split("\n"))+"\n"
+    b = signdesc(body, args_out)
+    for line in b.split("\n"):
+        print '  "%s\\n"'%line
+    print "  ;"
+
+def emit_ei(name, body):
+    args = { 'NAME' : name }
+    emit_ri(name, body, args)
+    args['key'] = "\n".join(
+        '  "%s\\n"'%line for line in args['RSA-IDENTITY'].split("\n"))
+    print """
+const char {NAME}_fp[] = "{FINGERPRINT-NOSPACE}";
+const char {NAME}_key[] =
+{key};""".format(**args)
+
+if 0:
+    emit_ri("minimal",
+     """\
+router fred 127.0.0.1 9001 0 9002
+signing-key
+{RSA-IDENTITY}
+onion-key
+{ONION-KEY}
+published 2014-10-05 12:00:00
+bandwidth 1000 1000 1000
+reject *:*
+router-signature
+{RSA-SIGNATURE}
+""")
+
+if 0:
+    emit_ri("maximal",
+     """\
+router fred 127.0.0.1 9001 0 9002
+signing-key
+{RSA-IDENTITY}
+onion-key
+{ONION-KEY}
+published 2014-10-05 12:00:00
+bandwidth 1000 1000 1000
+reject 127.0.0.1:*
+accept *:80
+reject *:*
+ipv6-policy accept 80,100,101
+ntor-onion-key s7rSohmz9SXn8WWh1EefTHIsWePthsEntQi0WL+ScVw
+uptime 1000
+hibernating 0
+unrecognized-keywords are just dandy in this format
+platform Tor 0.2.4.23 on a Banana PC Jr 6000 Series
+contact O.W.Jones
+fingerprint {FINGERPRINT}
+read-history 900 1,2,3,4
+write-history 900 1,2,3,4
+extra-info-digest AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+hidden-service-dir
+allow-single-hop-exits
+family $AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA $BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+caches-extra-info
+or-address [::1:2:3:4]:9999
+or-address 127.0.0.99:10000
+opt fred is a fine router
+router-signature
+{RSA-SIGNATURE}
+""")
+
+if 0:
+    emit_ei("maximal",
+"""\
+extra-info bob {FINGERPRINT-NOSPACE}
+published 2014-10-05 20:07:00
+opt foobarbaz
+read-history 900 1,2,3
+write-history 900 1,2,3
+dirreq-v2-ips 1
+dirreq-v3-ips 100
+dirreq-v3-reqs blahblah
+dirreq-v2-share blahblah
+dirreq-v3-share blahblah
+dirreq-v2-resp djfkdj
+dirreq-v3-resp djfkdj
+dirreq-v2-direct-dl djfkdj
+dirreq-v3-direct-dl djfkdj
+dirreq-v2-tunneled-dl djfkdj
+dirreq-v3-tunneled-dl djfkdj
+dirreq-stats-end foobar
+entry-ips jfsdfds
+entry-stats-end ksdflkjfdkf
+cell-stats-end FOO
+cell-processed-cells FOO
+cell-queued-cells FOO
+cell-time-in-queue FOO
+cell-circuits-per-decile FOO
+exit-stats-end FOO
+exit-kibibytes-written FOO
+exit-kibibytes-read FOO
+exit-streams-opened FOO
+router-signature
+{RSA-SIGNATURE}
+""")
+
+if 0:
+    emit_ei("minimal",
+"""\
+extra-info bob {FINGERPRINT-NOSPACE}
+published 2014-10-05 20:07:00
+router-signature
+{RSA-SIGNATURE}
+""")
+





More information about the tor-commits mailing list