[tor-commits] [stem/master] Completely deprecate pycrypto

atagar at torproject.org atagar at torproject.org
Mon Feb 27 00:49:11 UTC 2017


commit 116787a0ee17e46cd587a3a4a40239a53890039e
Author: Patrick O'Doherty <p at trickod.com>
Date:   Sun Feb 26 15:32:02 2017 -0800

    Completely deprecate pycrypto
    
    Update the sign_descriptor_content in mocking.py to use cryptography.
    
    Remove pycrypto from the requirements.txt
---
 requirements.txt  |  1 -
 stem/prereq.py    |  9 +++++----
 test/mocking.py   | 42 ++++++++++++++----------------------------
 test/settings.cfg | 14 +++++++-------
 4 files changed, 26 insertions(+), 40 deletions(-)

diff --git a/requirements.txt b/requirements.txt
index 5fb3d12..6dc054c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,5 @@
 mock
 pyflakes
 pycodestyle
-pycrypto
 tox
 cryptography
diff --git a/stem/prereq.py b/stem/prereq.py
index 4574771..bf935b4 100644
--- a/stem/prereq.py
+++ b/stem/prereq.py
@@ -85,7 +85,7 @@ def is_python_3():
 @lru_cache()
 def is_crypto_available():
   """
-  Checks if the pycrypto functions we use are available. This is used for
+  Checks if the cryptography functions we use are available. This is used for
   verifying relay descriptor signatures.
 
   :returns: **True** if we can use pycrypto and **False** otherwise
@@ -94,9 +94,10 @@ def is_crypto_available():
   from stem.util import log
 
   try:
-    from Crypto.PublicKey import RSA
-    from Crypto.Util import asn1
-    from Crypto.Util.number import long_to_bytes
+    from cryptography.utils import int_from_bytes, int_to_bytes
+    from cryptography.hazmat.backends import default_backend
+    from cryptography.hazmat.primitives.serialization import load_der_public_key
+    from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
     return True
   except ImportError:
     log.log_once('stem.prereq.is_crypto_available', log.INFO, CRYPTO_UNAVAILABLE)
diff --git a/test/mocking.py b/test/mocking.py
index 0d9e6f0..8babe76 100644
--- a/test/mocking.py
+++ b/test/mocking.py
@@ -722,33 +722,19 @@ def sign_descriptor_content(desc_content):
   if not stem.prereq.is_crypto_available():
     return desc_content
   else:
-    from Crypto.PublicKey import RSA
-    from Crypto.Util import asn1
-    from Crypto.Util.number import long_to_bytes
-
-    # generate a key
-    private_key = RSA.generate(1024)
-
-    # get a string representation of the public key
-    seq = asn1.DerSequence()
-    seq.append(private_key.n)
-    seq.append(private_key.e)
-    seq_as_string = seq.encode()
-    public_key_string = base64.b64encode(seq_as_string)
-
-    # split public key into lines 64 characters long
-    public_key_string = b'\n'.join([
-      public_key_string[:64],
-      public_key_string[64:128],
-      public_key_string[128:],
-    ])
+    from cryptography.hazmat.backends import default_backend
+    from cryptography.hazmat.primitives import hashes
+    from cryptography.hazmat.primitives.asymmetric import rsa, padding
+    from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
+
+    private_key = rsa.generate_private_key(public_exponent=65537, key_size=1024, backend=default_backend())
+    public_key = private_key.public_key()
 
-    # generate the new signing key string
+    # Get a string representation of the public key
 
     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
+    new_sk = signing_key_token + public_key.public_bytes(encoding=Encoding.PEM, format=PublicFormat.PKCS1)
 
     # update the descriptor string with the new signing key
 
@@ -758,6 +744,7 @@ def sign_descriptor_content(desc_content):
 
     # generate the new fingerprint string
 
+    seq_as_string = public_key.public_bytes(encoding=Encoding.DER, format=PublicFormat.PKCS1)
     key_hash = stem.util.str_tools._to_bytes(hashlib.sha1(seq_as_string).hexdigest().upper())
     grouped_fingerprint = b''
 
@@ -799,16 +786,15 @@ def sign_descriptor_content(desc_content):
     #  2 bytes for the type info
     #  1 byte for the separator
 
-    padding = b''
+    digest_padding = b''
 
     for x in range(125 - len(new_digest)):
-      padding += b'\xFF'
-      digestBuffer = b'\x00\x01' + padding + b'\x00' + new_digest
+      digest_padding += b'\xFF'
+      digest_buffer = b'\x00\x01' + digest_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_as_bytes = private_key.sign(digest_buffer, padding.PKCS1v15(), hashes.SHA1())
     signature_base64 = base64.b64encode(signature_as_bytes)
 
     signature_base64 = b'b'.join([
diff --git a/test/settings.cfg b/test/settings.cfg
index 4913202..f9c6c62 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -144,14 +144,14 @@ pyflakes.ignore stem/__init__.py => undefined name 'long'
 pyflakes.ignore stem/__init__.py => undefined name 'unicode'
 pyflakes.ignore stem/control.py => undefined name 'controller'
 pyflakes.ignore stem/manual.py => undefined name 'unichr'
-pyflakes.ignore stem/prereq.py => 'Crypto.PublicKey.RSA' imported but unused
-pyflakes.ignore stem/prereq.py => 'Crypto.Util.asn1' imported but unused
-pyflakes.ignore stem/prereq.py => 'Crypto.Util.number.long_to_bytes' imported but unused
-pyflakes.ignore stem/prereq.py => 'RSA' imported but unused
-pyflakes.ignore stem/prereq.py => 'asn1' imported but unused
-pyflakes.ignore stem/prereq.py => 'unittest' imported but unused
+pyflakes.ignore stem/prereq.py => 'cryptography.utils.int_to_bytes' imported but unused
+pyflakes.ignore stem/prereq.py => 'cryptography.utils.int_from_bytes' imported but unused
+pyflakes.ignore stem/prereq.py => 'cryptography.hazmat.backends.default_backend' imported but unused
+pyflakes.ignore stem/prereq.py => 'cryptography.hazmat.primitives.serialization.load_der_public_key' imported but unused
+pyflakes.ignore stem/prereq.py => 'cryptography.hazmat.primitives.ciphers.modes' imported but unused
+pyflakes.ignore stem/prereq.py => 'cryptography.hazmat.primitives.ciphers.Cipher' imported but unused
+pyflakes.ignore stem/prereq.py => 'cryptography.hazmat.primitives.ciphers.algorithms' imported but unused
 pyflakes.ignore stem/prereq.py => 'unittest.mock' imported but unused
-pyflakes.ignore stem/prereq.py => 'long_to_bytes' imported but unused
 pyflakes.ignore stem/interpreter/__init__.py => undefined name 'raw_input'
 pyflakes.ignore stem/util/conf.py => undefined name 'unicode'
 pyflakes.ignore stem/util/test_tools.py => 'pyflakes' imported but unused





More information about the tor-commits mailing list