Browse Source

crypto: Add support for Paramiko 2.x

Only use PyCrypto/PyCryptodome work-around with Paramiko 1.x and use
straight-forward Paramiko interface with 2.x.

TODO: Revert this and PyCrypto/PyCryptodome work-around when Paramiko
is upgraded to 2.x (ie replace `generate_keys(bits)` call with
`paramiko.RSAKey.generate(bits)`).

Change If88beeb3983705621fe736995939ac20b2daf1f3 added a work-around
for the partially-PyCrypto-compatible PyCryptodome causing Paramiko,
which has a dependency on PyCrypto, to break.  This work-around
entails implementing Paramiko internals (ie how to generate a key) in
Nova in a way compatible with both PyCrypto and PyCryptodom.

This work-around is itself a source of failure with Paramiko 2 which
has replaced the PyCrypto requirement with the cryptography Python
package.  As Paramiko no longer depends on PyCrypto, Nova doesn't have
an explicit PyCrypto requirement, and there's no implicit dependency
on PyCrypto, when Nova tries to import PyCrypto it fails.  Even if
PyCrypto was installed, the work-around would still fail because the
Paramiko interface that Nova is using as part of the work-around
changed with the major version change (ie 1.x => 2.x).

Change-Id: I5d6543e690a3b4495476027fd8a4894ff8c42bf6
Related-Bug: #1483132
tags/14.0.0.0b1
Corey Wright 3 years ago
parent
commit
c05b338f16
1 changed files with 17 additions and 6 deletions
  1. 17
    6
      nova/crypto.py

+ 17
- 6
nova/crypto.py View File

@@ -26,7 +26,6 @@ import base64
26 26
 import binascii
27 27
 import os
28 28
 
29
-from Crypto.PublicKey import RSA
30 29
 from cryptography import exceptions
31 30
 from cryptography.hazmat import backends
32 31
 from cryptography.hazmat.primitives.asymmetric import padding
@@ -140,11 +139,23 @@ def generate_key(bits):
140 139
     # which version of pysaml2 is installed, Nova is likely to break. So we
141 140
     # call "RSA.generate(bits)" which works on both pycrypto and pycryptodome
142 141
     # and then wrap it into a paramiko.RSAKey
143
-    rsa = RSA.generate(bits)
144
-    key = paramiko.RSAKey(vals=(rsa.e, rsa.n))
145
-    key.d = rsa.d
146
-    key.p = rsa.p
147
-    key.q = rsa.q
142
+    #
143
+    # NOTE(coreywright): Paramiko 2 avoids this conundrum by migrating from
144
+    # PyCrypto/PyCryptodome to cryptography.
145
+    #
146
+    # TODO(coreywright): When Paramiko constraint is upgraded to 2.x, then
147
+    # remove this abstraction and replace the call to this function with a call
148
+    # to `paramiko.RSAKey.generate(bits)`.
149
+
150
+    if paramiko.__version_info__[0] == 2:
151
+        key = paramiko.RSAKey.generate(bits)
152
+    else:  # paramiko 1.x
153
+        from Crypto.PublicKey import RSA
154
+        rsa = RSA.generate(bits)
155
+        key = paramiko.RSAKey(vals=(rsa.e, rsa.n))
156
+        key.d = rsa.d
157
+        key.p = rsa.p
158
+        key.q = rsa.q
148 159
     return key
149 160
 
150 161
 

Loading…
Cancel
Save