commit a41767c7363b2164cad7d666a927ff8eead75799 Author: Damian Johnson atagar@torproject.org Date: Tue Jun 20 08:54:57 2017 -0700
Exclude hash constant from signatures
Holy crap that was a pita. Oh well, got it. Python's cryptography module appends a constant indicating the hashing algorithm it uses whereas tor doesn't. This caused validation of descriptor signatures we add to fail with...
====================================================================== ERROR: test_descriptor_signing ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/atagar/Desktop/stem/test/require.py", line 58, in wrapped return func(self, *args, **kwargs) File "/home/atagar/Desktop/stem/test/unit/descriptor/server_descriptor.py", line 260, in test_descriptor_signing RelayDescriptor.create(sign = True) File "/home/atagar/Desktop/stem/stem/descriptor/server_descriptor.py", line 860, in create return cls(cls.content(attr, exclude, sign, private_signing_key), validate = validate, skip_crypto_validation = not sign) File "/home/atagar/Desktop/stem/stem/descriptor/server_descriptor.py", line 808, in __init__ raise ValueError('Decrypted digest does not match local digest (calculated: %s, local: %s)' % (signed_digest, self.digest())) ValueError: Decrypted digest does not match local digest (calculated: 3021300906052B0E03021A05000414FDE1A32B71718BFEBD610E76B6340EB4795A554A, local: FDE1A32B71718BFEBD610E76B6340EB4795A554A)
----------------------------------------------------------------------
Note that they *do* actually match. Only trouble is that the former is prefixed by the following constant...
3021300906052B0E03021A05000414
Took a full day of head scratching but finally got a hint about what this is thanks to...
https://crypto.stackexchange.com/questions/8780/verify-signature-failed
Cryptography embeds a constant indicating the hash algorithm used (in this case sha1). Unfortunately this is baked pretty deep so the only way to exclude this is mocking out part of its internals. I'll shoot upstream a request in a bit to allow this to be toggled. --- stem/descriptor/server_descriptor.py | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py index 3ad019a..499b53e 100644 --- a/stem/descriptor/server_descriptor.py +++ b/stem/descriptor/server_descriptor.py @@ -840,6 +840,17 @@ class RelayDescriptor(ServerDescriptor): backend = default_backend(), )
+ # When signing the cryptography module includes a constant indicating + # the hash algorithm used. Tor doesn't. This causes signature + # validation failures and unfortunately cryptography have no nice way + # of excluding these so we need to mock out part of their internals... + # ewww. + + no_op = lambda *args, **kwargs: None + + private_signing_key._backend._lib.EVP_PKEY_CTX_set_signature_md = no_op + private_signing_key._backend.openssl_assert = no_op + # create descriptor content without the router-signature, then # appending the content signature
tor-commits@lists.torproject.org