From 00e30855010966085fdf68a1d147b7be4fbb5b20 Mon Sep 17 00:00:00 2001
From: Andrew Wason <rectalogic@rectalogic.com>
Date: Wed, 6 Feb 2019 10:56:53 -0500
Subject: [PATCH 1/3] Move to cryptography 2.5 and stop using deprecated APIs.

Fixes #1369
---
 paramiko/ecdsakey.py      |  4 ++--
 paramiko/kex_ecdh_nist.py | 37 +++++++++++++++++++++++++++++--------
 setup.py                  |  2 +-
 4 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/paramiko/ecdsakey.py b/paramiko/ecdsakey.py
index 92e01a75..c35b6cd7 100644
--- a/paramiko/ecdsakey.py
+++ b/paramiko/ecdsakey.py
@@ -150,9 +150,9 @@ class ECDSAKey(PKey):
 
             pointinfo = msg.get_binary()
             try:
-                numbers = ec.EllipticCurvePublicNumbers.from_encoded_point(
+                numbers = ec.EllipticCurvePublicKey.from_encoded_point(
                     self.ecdsa_curve.curve_class(), pointinfo
-                )
+                ).public_numbers()
             except ValueError:
                 raise SSHException("Invalid public key")
             self.verifying_key = numbers.public_key(backend=default_backend())
diff --git a/paramiko/kex_ecdh_nist.py b/paramiko/kex_ecdh_nist.py
index 4e8ff35d..51ef88b4 100644
--- a/paramiko/kex_ecdh_nist.py
+++ b/paramiko/kex_ecdh_nist.py
@@ -9,6 +9,7 @@ from paramiko.py3compat import byte_chr, long
 from paramiko.ssh_exception import SSHException
 from cryptography.hazmat.backends import default_backend
 from cryptography.hazmat.primitives.asymmetric import ec
+from cryptography.hazmat.primitives import serialization
 from binascii import hexlify
 
 _MSG_KEXECDH_INIT, _MSG_KEXECDH_REPLY = range(30, 32)
@@ -36,7 +37,12 @@ class KexNistp256():
         m = Message()
         m.add_byte(c_MSG_KEXECDH_INIT)
         # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
-        m.add_string(self.Q_C.public_numbers().encode_point())
+        m.add_string(
+            self.Q_C.public_bytes(
+                serialization.Encoding.X962,
+                serialization.PublicFormat.UncompressedPoint,
+            )
+        )
         self.transport._send_message(m)
         self.transport._expect_packet(_MSG_KEXECDH_REPLY)
 
@@ -58,9 +64,9 @@ class KexNistp256():
 
     def _parse_kexecdh_init(self, m):
         Q_C_bytes = m.get_string()
-        self.Q_C = ec.EllipticCurvePublicNumbers.from_encoded_point(
+        self.Q_C = ec.EllipticCurvePublicKey.from_encoded_point(
             self.curve, Q_C_bytes
-        )
+        ).public_numbers()
         K_S = self.transport.get_server_key().asbytes()
         K = self.P.exchange(ec.ECDH(), self.Q_C.public_key(default_backend()))
         K = long(hexlify(K), 16)
@@ -71,7 +77,12 @@ class KexNistp256():
         hm.add_string(K_S)
         hm.add_string(Q_C_bytes)
         # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
-        hm.add_string(self.Q_S.public_numbers().encode_point())
+        hm.add_string(
+            self.Q_S.public_bytes(
+                serialization.Encoding.X962,
+                serialization.PublicFormat.UncompressedPoint,
+            )
+        )
         hm.add_mpint(long(K))
         H = self.hash_algo(hm.asbytes()).digest()
         self.transport._set_K_H(K, H)
@@ -80,7 +91,12 @@ class KexNistp256():
         m = Message()
         m.add_byte(c_MSG_KEXECDH_REPLY)
         m.add_string(K_S)
-        m.add_string(self.Q_S.public_numbers().encode_point())
+        m.add_string(
+            self.Q_S.public_bytes(
+                serialization.Encoding.X962,
+                serialization.PublicFormat.UncompressedPoint,
+            )
+        )
         m.add_string(sig)
         self.transport._send_message(m)
         self.transport._activate_outbound()
@@ -88,9 +104,9 @@ class KexNistp256():
     def _parse_kexecdh_reply(self, m):
         K_S = m.get_string()
         Q_S_bytes = m.get_string()
-        self.Q_S = ec.EllipticCurvePublicNumbers.from_encoded_point(
+        self.Q_S = ec.EllipticCurvePublicKey.from_encoded_point(
             self.curve, Q_S_bytes
-        )
+        ).public_numbers()
         sig = m.get_binary()
         K = self.P.exchange(ec.ECDH(), self.Q_S.public_key(default_backend()))
         K = long(hexlify(K), 16)
@@ -100,7 +116,12 @@ class KexNistp256():
                self.transport.local_kex_init, self.transport.remote_kex_init)
         hm.add_string(K_S)
         # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
-        hm.add_string(self.Q_C.public_numbers().encode_point())
+        hm.add_string(
+            self.Q_C.public_bytes(
+                serialization.Encoding.X962,
+                serialization.PublicFormat.UncompressedPoint,
+            )
+        )
         hm.add_string(Q_S_bytes)
         hm.add_mpint(K)
         self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
diff --git a/setup.py b/setup.py
index 6e1f0e0e..5bd5f50b 100644
--- a/setup.py
+++ b/setup.py
@@ -73,7 +73,7 @@ setup(
     ],
     install_requires=[
         'bcrypt>=3.1.3',
-        'cryptography>=1.5',
+        'cryptography>=2.5',
         'pynacl>=1.0.1',
         'pyasn1>=0.1.7',
     ],
-- 
2.26.2


From ccae60a4fc8f8d62d519d44209507c7694206b93 Mon Sep 17 00:00:00 2001
From: Andrew Wason <rectalogic@rectalogic.com>
Date: Sat, 9 Feb 2019 11:23:39 -0500
Subject: [PATCH 2/3] Fix numbers vs key mixups

---
 paramiko/ecdsakey.py      | 5 ++---
 paramiko/kex_ecdh_nist.py | 8 ++++----
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/paramiko/ecdsakey.py b/paramiko/ecdsakey.py
index c35b6cd7..e16d6e97 100644
--- a/paramiko/ecdsakey.py
+++ b/paramiko/ecdsakey.py
@@ -150,12 +150,11 @@ class ECDSAKey(PKey):
 
             pointinfo = msg.get_binary()
             try:
-                numbers = ec.EllipticCurvePublicKey.from_encoded_point(
+                self.verifying_key = ec.EllipticCurvePublicKey.from_encoded_point(
                     self.ecdsa_curve.curve_class(), pointinfo
-                ).public_numbers()
+                )
             except ValueError:
                 raise SSHException("Invalid public key")
-            self.verifying_key = numbers.public_key(backend=default_backend())
 
     @classmethod
     def supported_key_format_identifiers(cls):
diff --git a/paramiko/kex_ecdh_nist.py b/paramiko/kex_ecdh_nist.py
index 51ef88b4..fe563585 100644
--- a/paramiko/kex_ecdh_nist.py
+++ b/paramiko/kex_ecdh_nist.py
@@ -66,9 +66,9 @@ class KexNistp256():
         Q_C_bytes = m.get_string()
         self.Q_C = ec.EllipticCurvePublicKey.from_encoded_point(
             self.curve, Q_C_bytes
-        ).public_numbers()
+        )
         K_S = self.transport.get_server_key().asbytes()
-        K = self.P.exchange(ec.ECDH(), self.Q_C.public_key(default_backend()))
+        K = self.P.exchange(ec.ECDH(), self.Q_C)
         K = long(hexlify(K), 16)
         # compute exchange hash
         hm = Message()
@@ -106,9 +106,9 @@ class KexNistp256():
         Q_S_bytes = m.get_string()
         self.Q_S = ec.EllipticCurvePublicKey.from_encoded_point(
             self.curve, Q_S_bytes
-        ).public_numbers()
+        )
         sig = m.get_binary()
-        K = self.P.exchange(ec.ECDH(), self.Q_S.public_key(default_backend()))
+        K = self.P.exchange(ec.ECDH(), self.Q_S)
         K = long(hexlify(K), 16)
         # compute exchange hash and verify signature
         hm = Message()
-- 
2.26.2


From 38086de5c949df96b142a63e16a7d06867190916 Mon Sep 17 00:00:00 2001
From: Andrew Wason <rectalogic@rectalogic.com>
Date: Sat, 9 Feb 2019 11:41:40 -0500
Subject: [PATCH 3/3] Fix line length

---
 paramiko/ecdsakey.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/paramiko/ecdsakey.py b/paramiko/ecdsakey.py
index e16d6e97..02361718 100644
--- a/paramiko/ecdsakey.py
+++ b/paramiko/ecdsakey.py
@@ -150,9 +150,10 @@ class ECDSAKey(PKey):
 
             pointinfo = msg.get_binary()
             try:
-                self.verifying_key = ec.EllipticCurvePublicKey.from_encoded_point(
+                key = ec.EllipticCurvePublicKey.from_encoded_point(
                     self.ecdsa_curve.curve_class(), pointinfo
                 )
+                self.verifying_key = key
             except ValueError:
                 raise SSHException("Invalid public key")
 
-- 
2.26.2

