commit 0031d2b0adf077708210fe7ca84810b464f56e8e Author: Nick Mathewson nickm@torproject.org Date: Fri Oct 16 11:56:10 2020 -0400
Update makedesc.py script so that it works with python3. --- scripts/codegen/makedesc.py | 83 ++++++++++++++++++++------------ src/test/ed25519_exts_ref.py | 6 +-- src/test/failing_routerdescs.template | 91 +++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 34 deletions(-)
diff --git a/scripts/codegen/makedesc.py b/scripts/codegen/makedesc.py index 48d1d31a02..37ad4bd3bb 100644 --- a/scripts/codegen/makedesc.py +++ b/scripts/codegen/makedesc.py @@ -71,18 +71,18 @@ i2d_RSAPublicKey.restype = ctypes.c_int
def rsa_sign(msg, rsa): - buf = ctypes.create_string_buffer(1024) + buf = ctypes.create_string_buffer(2048) n = RSA_private_encrypt(len(msg), msg, buf, rsa, 1) if n <= 0: raise Exception() return buf.raw[:n]
-def b64(x): - x = base64.b64encode(x) +def b64(x1): + x = binascii.b2a_base64(x1) res = [] for i in xrange(0, len(x), 64): - res.append(x[i:i+64]+"\n") - return "".join(res) + res.append((x[i:i+64]).decode("ascii")) + return "\n".join(res)
def bio_extract(bio): buf = ctypes.c_char_p() @@ -100,18 +100,19 @@ def make_rsa_key(e=65537): n = crypt.i2d_RSAPublicKey(rsa, ctypes.byref(pBuf)) s = buf.raw[:n] digest = hashlib.sha1(s).digest() + pem = pem.decode("ascii") return (rsa,pem,digest)
def makeEdSigningKeyCert(sk_master, pk_master, pk_signing, date, includeSigning=False, certType=1): assert len(pk_signing) == len(pk_master) == 32 - expiration = struct.pack("!L", date//3600) + expiration = struct.pack(b"!L", date//3600) if includeSigning: - extensions = "\x01\x00\x20\x04\x00%s"%(pk_master) + extensions = b"\x01\x00\x20\x04\x00%s"%(pk_master) else: - extensions = "\x00" - signed = "\x01%s%s\x01%s%s" % ( - chr(certType), expiration, pk_signing, extensions) + extensions = b"\x00" + signed = b"\x01%s%s\x01%s%s" % ( + bytes([certType]), expiration, pk_signing, extensions) signature = ed25519_exts_ref.signatureWithESK(signed, sk_master, pk_master) assert len(signature) == 64 return signed+signature @@ -127,7 +128,7 @@ MAGIC2 = "<<<<<!#!#!#XYZZY#!#!#!>>>>>" class OnDemandKeys(object): def __init__(self, certDate=None): if certDate is None: - certDate = time.time() + 86400 + certDate = int(time.time()) + 86400 self.certDate = certDate self.rsa_id = None self.rsa_onion_key = None @@ -151,7 +152,7 @@ class OnDemandKeys(object):
@property def RSA_FINGERPRINT_NOSPACE(self): - return binascii.b2a_hex(self.RSA_ID_DIGEST).upper() + return binascii.b2a_hex(self.RSA_ID_DIGEST).upper().decode("ascii")
@property def RSA_ONION_KEY(self): @@ -162,7 +163,7 @@ class OnDemandKeys(object):
@property def RSA_FINGERPRINT(self): - hexdigest = self.RSA_FINGERPRINT_NOSPACEK + hexdigest = self.RSA_FINGERPRINT_NOSPACE return " ".join(hexdigest[i:i+4] for i in range(0,len(hexdigest),4))
@property @@ -178,7 +179,7 @@ class OnDemandKeys(object): if self.ntor_sk is None: self.ntor_sk = slownacl_curve25519.Private() self.ntor_pk = self.ntor_sk.get_public() - return base64.b64encode(self.ntor_pk.serialize()) + return base64.b64encode(self.ntor_pk.serialize()).decode("ascii")
@property def ED_CERT(self): @@ -191,6 +192,11 @@ class OnDemandKeys(object):
return objwrap('ED25519 CERT', b64(self.ed_cert))
+ @property + def ED_IDENTITY(self): + self.ED_CERT + return binascii.b2a_base64(self.ed_id_pk).strip().decode("ascii") + @property def NTOR_CROSSCERT(self): if self.ntor_crosscert is None: @@ -199,7 +205,7 @@ class OnDemandKeys(object):
ed_privkey = self.ntor_sk.serialize() + os.urandom(32) ed_pub0 = ed25519_exts_ref.publickeyFromESK(ed_privkey) - sign = (ord(ed_pub0[31]) & 255) >> 7 + sign = ((ed_pub0[31]) & 255) >> 7
self.ntor_crosscert = makeEdSigningKeyCert(self.ntor_sk.serialize() + os.urandom(32), ed_pub0, self.ed_id_pk, self.certDate, certType=10) self.ntor_crosscert_sign = sign @@ -234,18 +240,19 @@ class OnDemandKeys(object): self.ED_CERT signed_part = body[:idx+len("\nrouter-sig-ed25519 ")] signed_part = "Tor router descriptor signature v1" + signed_part - digest = hashlib.sha256(signed_part).digest() + digest = hashlib.sha256(signed_part.encode("utf-8")).digest() ed_sig = ed25519_exts_ref.signatureWithESK(digest, self.ed_signing_sk, self.ed_signing_pk)
- body = body.replace(MAGIC2, base64.b64encode(ed_sig).replace("=","")) + body = body.replace(MAGIC2, base64.b64encode(ed_sig).decode("ascii").replace("=",""))
+ self.RSA_IDENTITY 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() + digest = hashlib.sha1(signed_part.encode("utf-8")).digest() assert len(digest) == 20
rsasig = rsa_sign(digest, self.rsa_id) @@ -329,18 +336,30 @@ def emit_ei(name, body): print_c_string("EX_EI_%s_KEY"%name.upper(), info.RSA_IDENTITY)
def analyze(s): - fields = {} - while s.startswith(":::"): - first,s=s.split("\n", 1) - m = re.match(r'^:::(\w+)=(.*)',first) - if not m: - raise ValueError(first) - k,v = m.groups() - fields[k] = v - return fields, s - -def process_file(s): - fields, s = analyze(s) + while s: + fields = {} + s_pre = s + while s.startswith(":::"): + first,s=s.split("\n", 1) + m = re.match(r'^:::(\w+)=(.*)',first) + if not m: + raise ValueError(first) + k,v = m.groups() + fields[k] = v + if "name" not in fields: + print(repr(s_pre)) + + idx = s.find(":::") + if idx != -1: + body = s[:idx].rstrip() + s = s[idx:] + else: + body = s + s = "" + + yield (fields, body) + +def emit_entry(fields, s): try: name = fields['name'] tp = fields['type'] @@ -354,6 +373,10 @@ def process_file(s): else: raise ValueError("unrecognized type")
+def process_file(s): + for (fields, s) in analyze(s): + emit_entry(fields, s) + if __name__ == '__main__': import sys for fn in sys.argv[1:]: diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py index ae537ff15b..dcc0a7c25a 100644 --- a/src/test/ed25519_exts_ref.py +++ b/src/test/ed25519_exts_ref.py @@ -53,7 +53,7 @@ def blindPK(pk, param): def expandSK(sk): h = H(sk) a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) - k = ''.join([h[i] for i in range(b/8,b/4)]) + k = bytes(h[i] for i in range(b//8,b//4)) assert len(k) == 32 return encodeint(a)+k
@@ -64,7 +64,7 @@ def publickeyFromESK(h):
def signatureWithESK(m,h,pk): a = decodeint(h[:32]) - r = Hint(''.join([h[i] for i in range(b/8,b/4)]) + m) + r = Hint(bytes([h[i] for i in range(b//8,b//4)]) + m) R = scalarmult(B,r) S = (r + Hint(encodepoint(R) + pk + m) * a) % l return encodepoint(R) + encodeint(S) @@ -263,5 +263,3 @@ if __name__ == '__main__': unittest.main() else: makeTestVectors() - - diff --git a/src/test/failing_routerdescs.template b/src/test/failing_routerdescs.template new file mode 100644 index 0000000000..2c14330a2f --- /dev/null +++ b/src/test/failing_routerdescs.template @@ -0,0 +1,91 @@ +:::comment=this file is to be used with the makedescs.py utility +:::name=MINIMAL +:::type=ri +router fred 127.0.0.1 9001 0 9002 +identity-ed25519 +{d.ED_CERT} +signing-key +{d.RSA_IDENTITY} +master-key-ed25519 {d.ED_IDENTITY} +onion-key +{d.RSA_ONION_KEY} +ntor-onion-key {d.NTOR_ONION_KEY} +ntor-onion-key-crosscert {d.NTOR_CROSSCERT_SIGN} +{d.NTOR_CROSSCERT} +onion-key-crosscert +{d.RSA_CROSSCERT_ED} +published 2014-10-05 12:00:00 +bandwidth 1000 1000 1000 +proto Link=5 +reject *:* +router-sig-ed25519 {d.ED_SIGNATURE} +router-signature +{d.RSA_SIGNATURE} + + + +:::name=MAXIMAL +:::type=ri +router fred 127.0.0.1 9001 0 9002 +identity-ed25519 +{d.ED_CERT} +signing-key +{d.RSA_IDENTITY} +master-key-ed25519 {d.ED_IDENTITY} +onion-key +{d.RSA_ONION_KEY} +ntor-onion-key {d.NTOR_ONION_KEY} +ntor-onion-key-crosscert {d.NTOR_CROSSCERT_SIGN} +{d.NTOR_CROSSCERT} +onion-key-crosscert +{d.RSA_CROSSCERT_ED} +published 2014-10-05 12:00:00 +bandwidth 1000 1000 1000 +proto Link=5 +reject 127.0.0.1:* +accept *:80 +reject *:* +ipv6-policy accept 80,100,101 +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 {d.RSA_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-sig-ed25519 {d.ED_SIGNATURE} +router-signature +{d.RSA_SIGNATURE} + +:::comment=this file is to be used with the makedescs.py utility +:::name=MINIMAL +:::type=ri +router fred 127.0.0.1 9001 0 9002 +identity-ed25519 +{d.ED_CERT} +signing-key +{d.RSA_IDENTITY} +master-key-ed25519 {d.ED_IDENTITY} +onion-key +{d.RSA_ONION_KEY} +ntor-onion-key {d.NTOR_ONION_KEY} +ntor-onion-key-crosscert {d.NTOR_CROSSCERT_SIGN} +{d.NTOR_CROSSCERT} +onion-key-crosscert +{d.RSA_CROSSCERT_ED} +published 2014-10-05 12:00:00 +bandwidth 1000 1000 1000 +proto Link=5 +reject *:* +router-sig-ed25519 {d.ED_SIGNATURE} +router-signature +{d.RSA_SIGNATURE}