summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.travis.yml19
-rw-r--r--paramiko/ecdsakey.py4
-rw-r--r--paramiko/hostkeys.py6
-rw-r--r--paramiko/kex_ecdh_nist.py37
-rw-r--r--setup.py2
-rw-r--r--sites/www/changelog.rst25
-rw-r--r--tests/test_kex.py12
7 files changed, 79 insertions, 26 deletions
diff --git a/.travis.yml b/.travis.yml
index a2820666..41c074bb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,4 @@
+dist: xenial
language: python
sudo: false
cache:
@@ -8,26 +9,28 @@ python:
- "3.4"
- "3.5"
- "3.6"
- - "3.7-dev"
- - "pypy-5.6.0"
+ - "3.7"
+ - "3.8-dev"
+ - "pypy"
+ - "pypy3"
matrix:
allow_failures:
- - python: "3.7-dev"
+ - python: "3.8-dev"
# Explicitly test against our oldest supported cryptography.io, in addition
# to whatever the latest default is.
include:
- python: 2.7
- env: "CRYPTO_BEFORE=2.6"
- - python: 3.6
- env: "CRYPTO_BEFORE=2.6"
+ env: "OLDEST_CRYPTO=2.5"
+ - python: 3.7
+ env: "OLDEST_CRYPTO=2.5"
install:
# Ensure modern pip/etc to avoid some issues w/ older worker environs
- pip install pip==9.0.1 setuptools==36.6.0
# Grab a specific version of Cryptography if desired. Doing this before other
# installations ensures we don't have to do any downgrading/overriding.
- |
- if [[ -n "$CRYPTO_BEFORE" ]]; then
- pip install "cryptography<${CRYPTO_BEFORE}"
+ if [[ -n "$OLDEST_CRYPTO" ]]; then
+ pip install "cryptography==${OLDEST_CRYPTO}"
fi
# Self-install for setup.py-driven deps
- pip install -e .
diff --git a/paramiko/ecdsakey.py b/paramiko/ecdsakey.py
index b73a969e..353c5f9e 100644
--- a/paramiko/ecdsakey.py
+++ b/paramiko/ecdsakey.py
@@ -160,12 +160,12 @@ class ECDSAKey(PKey):
pointinfo = msg.get_binary()
try:
- numbers = ec.EllipticCurvePublicNumbers.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")
- self.verifying_key = numbers.public_key(backend=default_backend())
@classmethod
def supported_key_format_identifiers(cls):
diff --git a/paramiko/hostkeys.py b/paramiko/hostkeys.py
index f31b8819..d0660cc8 100644
--- a/paramiko/hostkeys.py
+++ b/paramiko/hostkeys.py
@@ -19,8 +19,12 @@
import binascii
import os
+import sys
-from collections import MutableMapping
+if sys.version_info[:2] >= (3, 3):
+ from collections.abc import MutableMapping
+else:
+ from collections import MutableMapping
from hashlib import sha1
from hmac import HMAC
diff --git a/paramiko/kex_ecdh_nist.py b/paramiko/kex_ecdh_nist.py
index 1d87442a..ad5c9c79 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,11 +64,11 @@ 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
)
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()
@@ -75,7 +81,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)
@@ -84,7 +95,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()
@@ -92,11 +108,11 @@ 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
)
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()
@@ -108,7 +124,12 @@ class KexNistp256:
)
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 6c366ce1..e6c4a077 100644
--- a/setup.py
+++ b/setup.py
@@ -70,6 +70,8 @@ setup(
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
],
install_requires=["bcrypt>=3.1.3", "cryptography>=2.5", "pynacl>=1.0.1"],
)
diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst
index ff87bfbb..032edb44 100644
--- a/sites/www/changelog.rst
+++ b/sites/www/changelog.rst
@@ -2,6 +2,29 @@
Changelog
=========
+- :support:`1379` (also :issue:`1369`) Raise Cryptography dependency
+ requirement to version 2.5 (from 1.5) and update some deprecated uses of its
+ API.
+
+ This removes a bunch of warnings of the style
+ ``CryptographyDeprecationWarning: encode_point has been deprecated on
+ EllipticCurvePublicNumbers and will be removed in a future version. Please
+ use EllipticCurvePublicKey.public_bytes to obtain both compressed and
+ uncompressed point encoding`` and similar, which users who had eventually
+ upgraded to Cryptography 2.x would encounter.
+
+ .. warning::
+ This change is backwards incompatible **if** you are unable to upgrade your
+ version of Cryptography. Please see `Cryptography's own changelog
+ <https://cryptography.io/en/latest/changelog/>`_ for details on what may
+ change when you upgrade; for the most part the only changes involved
+ dropping older Python versions (such as 2.6, 3.3, or some PyPy editions)
+ which Paramiko itself has already dropped.
+
+- :support:`1378 backported` Add support for the modern (as of Python 3.3)
+ import location of ``MutableMapping`` (used in host key management) to avoid
+ the old location becoming deprecated in Python 3.8. Thanks to Josh Karpel for
+ catch & patch.
- :release:`2.4.2 <2018-09-18>`
- :release:`2.3.3 <2018-09-18>`
- :release:`2.2.4 <2018-09-18>`
@@ -95,7 +118,7 @@ Changelog
- :support:`1100` Updated the test suite & related docs/metadata/config to be
compatible with pytest instead of using the old, custom, crufty
unittest-based ``test.py``.
-
+
This includes marking known-slow tests (mostly the SFTP ones) so they can be
filtered out by ``inv test``'s default behavior; as well as other minor
tweaks to test collection and/or display (for example, GSSAPI tests are
diff --git a/tests/test_kex.py b/tests/test_kex.py
index 62512beb..d42355a1 100644
--- a/tests/test_kex.py
+++ b/tests/test_kex.py
@@ -42,20 +42,20 @@ def dummy_urandom(n):
def dummy_generate_key_pair(obj):
private_key_value = 94761803665136558137557783047955027733968423115106677159790289642479432803037
public_key_numbers = "042bdab212fa8ba1b7c843301682a4db424d307246c7e1e6083c41d9ca7b098bf30b3d63e2ec6278488c135360456cc054b3444ecc45998c08894cbc1370f5f989"
- public_key_numbers_obj = ec.EllipticCurvePublicNumbers.from_encoded_point(
+ public_key_numbers_obj = ec.EllipticCurvePublicKey.from_encoded_point(
ec.SECP256R1(), unhexlify(public_key_numbers)
- )
+ ).public_numbers()
obj.P = ec.EllipticCurvePrivateNumbers(
private_value=private_key_value, public_numbers=public_key_numbers_obj
).private_key(default_backend())
if obj.transport.server_mode:
- obj.Q_S = ec.EllipticCurvePublicNumbers.from_encoded_point(
+ obj.Q_S = ec.EllipticCurvePublicKey.from_encoded_point(
ec.SECP256R1(), unhexlify(public_key_numbers)
- ).public_key(default_backend())
+ )
return
- obj.Q_C = ec.EllipticCurvePublicNumbers.from_encoded_point(
+ obj.Q_C = ec.EllipticCurvePublicKey.from_encoded_point(
ec.SECP256R1(), unhexlify(public_key_numbers)
- ).public_key(default_backend())
+ )
class FakeKey(object):