commit ba50df27f2b69e05ce3470c4c1127974420a93bc Author: Damian Johnson atagar@torproject.org Date: Sun May 19 14:11:39 2013 -0700
Mocking's sign_descriptor_content() incompatible with python 3.x
I didn't have a python 3.x copy of pycrypto installed, so there were some code paths I didn't previously encounter. Unit tests failed due to sign_descriptor_content() not explicitly using bytes at several points.
====================================================================== ERROR: test_mirror_mirror_on_the_wall_4 ---------------------------------------------------------------------- Traceback: File "/home/atagar/Desktop/stem/test/data/python3/test/unit/tutorial.py", line 169, in test_mirror_mirror_on_the_wall_4 exit_descriptor = mocking.sign_descriptor_content(exit_descriptor) File "/home/atagar/Desktop/stem/test/data/python3/test/mocking.py", line 984, in sign_descriptor_content public_key_string = public_key_string[:64] + "\n" + public_key_string[64:128] + "\n" + public_key_string[128:] TypeError: can't concat bytes to str
---------------------------------------------------------------------- --- stem/control.py | 5 +++++ test/mocking.py | 63 +++++++++++++++++++++++++++++++++---------------------- 2 files changed, 43 insertions(+), 25 deletions(-)
diff --git a/stem/control.py b/stem/control.py index 08ce196..a4dde55 100644 --- a/stem/control.py +++ b/stem/control.py @@ -1166,6 +1166,11 @@ class Controller(BaseController): An exception is only raised if we weren't provided a default response. """
+ # TODO: It would be great to add support for v3 router status entries. This + # is pending... + # + # https://trac.torproject.org/7953 + try: if stem.util.tor_tools.is_valid_fingerprint(relay): query = "ns/id/%s" % relay diff --git a/test/mocking.py b/test/mocking.py index 340a625..50a0f0e 100644 --- a/test/mocking.py +++ b/test/mocking.py @@ -954,13 +954,14 @@ def get_network_status_document_v3(attr = None, exclude = (), authorities = None def sign_descriptor_content(desc_content): """ Add a valid signature to the supplied descriptor string. - If the python-crypto library is available the function will generate a key - pair, and use it to sign the descriptor string. Any existing fingerprint, - signing-key or router-signature data will be overwritten. - If crypto is unavailable the code will return the unaltered descriptor - string. - :param string desc_content: the descriptor string to sign - :returns: a descriptor string, signed if crypto available, unaltered otherwise + + If pycrypto is available the function will generate a key pair, and use it to + sign the descriptor string. Any existing fingerprint, signing-key or + router-signature data will be overwritten. If the library's unavailable the + code will return the unaltered descriptor. + + :param str desc_content: the descriptor string to sign + :returns: a descriptor string, signed if crypto available and unaltered otherwise """
if not stem.prereq.is_crypto_available(): @@ -981,13 +982,17 @@ def sign_descriptor_content(desc_content): public_key_string = base64.b64encode(seq_as_string)
# split public key into lines 64 characters long - public_key_string = public_key_string[:64] + "\n" + public_key_string[64:128] + "\n" + public_key_string[128:] + public_key_string = b'\n'.join([ + public_key_string[:64], + public_key_string[64:128], + public_key_string[128:], + ])
# generate the new signing key string
- signing_key_token = "\nsigning-key\n" # note the trailing '\n' is important here so as not to match the string elsewhere - signing_key_token_start = "-----BEGIN RSA PUBLIC KEY-----\n" - signing_key_token_end = "\n-----END RSA PUBLIC KEY-----\n" + signing_key_token = b"\nsigning-key\n" # note the trailing '\n' is important here so as not to match the string elsewhere + signing_key_token_start = b"-----BEGIN RSA PUBLIC KEY-----\n" + signing_key_token_end = b"\n-----END RSA PUBLIC KEY-----\n" new_sk = signing_key_token + signing_key_token_start + public_key_string + signing_key_token_end
# update the descriptor string with the new signing key @@ -998,25 +1003,25 @@ def sign_descriptor_content(desc_content):
# generate the new fingerprint string
- key_hash = hashlib.sha1(seq_as_string).hexdigest().upper() - grouped_fingerprint = "" + key_hash = stem.util.str_tools._to_bytes(hashlib.sha1(seq_as_string).hexdigest().upper()) + grouped_fingerprint = b""
for x in range(0, len(key_hash), 4): - grouped_fingerprint += " " + key_hash[x:x + 4] - fingerprint_token = "\nfingerprint" + grouped_fingerprint += b" " + key_hash[x:x + 4] + fingerprint_token = b"\nfingerprint" new_fp = fingerprint_token + grouped_fingerprint
# update the descriptor string with the new fingerprint
ft_start = desc_content.find(fingerprint_token) if ft_start < 0: - fingerprint_token = "\nopt fingerprint" + fingerprint_token = b"\nopt fingerprint" ft_start = desc_content.find(fingerprint_token)
# if the descriptor does not already contain a fingerprint do not add one
if ft_start >= 0: - ft_end = desc_content.find("\n", ft_start + 1) + ft_end = desc_content.find(b"\n", ft_start + 1) desc_content = desc_content[:ft_start] + new_fp + desc_content[ft_end:]
# create a temporary object to use to calculate the digest @@ -1029,31 +1034,39 @@ def sign_descriptor_content(desc_content):
# remove the hex encoding
- new_digest = new_digest_hex.decode('hex') + if stem.prereq.is_python_3(): + new_digest = bytes.fromhex(new_digest_hex) + else: + new_digest = new_digest_hex.decode('hex_codec')
# Generate the digest buffer. # block is 128 bytes in size # 2 bytes for the type info # 1 byte for the separator
- padding = "" + padding = b""
for x in range(125 - len(new_digest)): - padding += '\xFF' - digestBuffer = '\x00\x01' + padding + '\x00' + new_digest + padding += b'\xFF' + digestBuffer = b'\x00\x01' + padding + b'\x00' + new_digest
# generate a new signature by signing the digest buffer with the private key
(signature, ) = private_key.sign(digestBuffer, None) signature_as_bytes = long_to_bytes(signature, 128) signature_base64 = base64.b64encode(signature_as_bytes) - signature_base64 = signature_base64[:64] + "\n" + signature_base64[64:128] + "\n" + signature_base64[128:] + + signature_base64 = b'b'.join([ + signature_base64[:64], + signature_base64[64:128], + signature_base64[128:], + ])
# update the descriptor string with the new signature
- router_signature_token = "\nrouter-signature\n" - router_signature_start = "-----BEGIN SIGNATURE-----\n" - router_signature_end = "\n-----END SIGNATURE-----\n" + router_signature_token = b"\nrouter-signature\n" + router_signature_start = b"-----BEGIN SIGNATURE-----\n" + router_signature_end = b"\n-----END SIGNATURE-----\n" rst_start = desc_content.find(router_signature_token) desc_content = desc_content[:rst_start] + router_signature_token + router_signature_start + signature_base64 + router_signature_end
tor-commits@lists.torproject.org