Skip to content

Commit

Permalink
Update for cryptography 0.8 and general cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Mar 15, 2015
1 parent 5861cde commit 5130ad1
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 74 deletions.
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Requirements

- Python 2.6 or better <http://www.python.org/> - this includes Python
3.2 and higher as well.
- Cryptography 0.7 or better <https://cryptography.io>
- Cryptography 0.8 or better <https://cryptography.io>
- pyasn1 0.1.7 or better <https://pypi.python.org/pypi/pyasn1>

If you have setuptools, you can build and install paramiko and all its
Expand Down
4 changes: 2 additions & 2 deletions paramiko/dsskey.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ def sign_ssh_data(self, data):
m = Message()
m.add_string('ssh-dss')
# apparently, in rare cases, r or s may be shorter than 20 bytes!
rstr = util.deflate_long(int(r), 0)
sstr = util.deflate_long(int(s), 0)
rstr = util.deflate_long(r, 0)
sstr = util.deflate_long(s, 0)
if len(rstr) < 20:
rstr = zero_byte * (20 - len(rstr)) + rstr
if len(sstr) < 20:
Expand Down
70 changes: 5 additions & 65 deletions paramiko/ecdsakey.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
decode_rfc6979_signature, encode_rfc6979_signature
)

from pyasn1.codec.der import encoder
from pyasn1.type import namedtype, namedval, tag, univ

from paramiko.common import four_byte, one_byte, zero_byte
from paramiko.message import Message
from paramiko.pkey import PKey
Expand All @@ -43,40 +40,6 @@
from paramiko.util import deflate_long, inflate_long


# RFC 5480, section 2.1.1
class _ECParameters(univ.Choice):
# TODO: There are a few more options for this choice I think, the RFC says
# not to use them though...
componentType = namedtype.NamedTypes(
namedtype.NamedType("namedCurve", univ.ObjectIdentifier()),
)


# RFC 5915, Appendix A
class _ECPrivateKey(univ.Sequence):
componentType = namedtype.NamedTypes(
namedtype.NamedType(
"version",
univ.Integer(
namedValues=namedval.NamedValues(
("ecPrivkeyVer1", 1),
)
),
),
namedtype.NamedType("privateKey", univ.OctetString()),
namedtype.OptionalNamedType("parameters", _ECParameters().subtype(
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0),
)),
namedtype.OptionalNamedType("publicKey", univ.BitString().subtype(
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1),
)),
)


_CURVE_TO_OID = {
ec.SECP256R1: univ.ObjectIdentifier("1.2.840.10045.3.1.7")
}

class ECDSAKey(PKey):
"""
Representation of an ECDSA key which can be used to sign and verify SSH2
Expand Down Expand Up @@ -216,40 +179,17 @@ def _from_private_key(self, file_obj, password):
byte_chr(5) * 5, byte_chr(6) * 6, byte_chr(7) * 7]

def _decode_key(self, data):
s = """
-----BEGIN EC PRIVATE KEY-----
%s
-----END EC PRIVATE KEY-----
""" % "\n".join(textwrap.wrap(base64.b64encode(data).decode(), 64))
key = serialization.load_pem_private_key(s.encode(), password=None, backend=default_backend())
key = serialization.load_der_private_key(data, password=None, backend=default_backend())
self.signing_key = key
self.verifying_key = key.public_key()
self.size = key.curve.key_size

def _to_der(self, key):
private_numbers = key.private_numbers()
public_numbers = private_numbers.public_numbers

private_key = deflate_long(
private_numbers.private_value, add_sign_padding=False
return key.private_bytes(
serialization.Encoding.DER,
serialization.Format.TraditionalOpenSSL,
serialization.NoEncryption(),
)
x_str = deflate_long(public_numbers.x, add_sign_padding=False)
y_str = deflate_long(public_numbers.y, add_sign_padding=False)

key_length = key.curve.key_size // 8
if len(x_str) < key_length:
x_str = zero_byte * (key_length - len(x_str)) + x_str
if len(y_str) < key_length:
y_str = zero_byte * (key_length - len(y_str)) + y_str
public_key = b"\x04" + x_str + y_str

asn1_key = _ECPrivateKey()
asn1_key.setComponentByName("version", 1)
asn1_key.setComponentByName("privateKey", private_key)
asn1_key.setComponentByName("parameters")
asn1_key.getComponentByName("parameters").setComponentByName("namedCurve", _CURVE_TO_OID[type(key.curve)])
asn1_key.setComponentByName("publicKey", "'%s'H" % binascii.hexlify(public_key).decode())
return encoder.encode(asn1_key)

def _sigencode(self, r, s):
msg = Message()
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from setuptools import setup
kw = {
'install_requires': [
'cryptography >= 0.7',
'cryptography >= 0.8',
'pyasn1 >= 0.1.7',
],
}
Expand Down
6 changes: 2 additions & 4 deletions sites/www/installing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ We currently support **Python 2.6, 2.7, 3.3+, and PyPy** (Python **3.2** should
also work but has a less-strong compatibility guarantee from us.) Users on
Python 2.5 or older are urged to upgrade.

Paramiko has three hard dependencies: the pure-Python ECDSA module ``ecdsa``
and ASN1 module ``pyasn1``, and the Cryptography library. ``ecdsa`` is easily
installable from wherever you obtained Paramiko's package; Cryptography may
require more work. Read on for details.
Paramiko has two hard dependencies: the pure-Python ASN1 module ``pyasn1``, and
the Cryptography library. Read on for details on installing ``cryptography``.

If you need GSS-API / SSPI support, see :ref:`the below subsection on it
<gssapi>` for details on additional dependencies.
Expand Down
2 changes: 1 addition & 1 deletion tox-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Not sure why tox can't just read setup.py?
cryptography >= 0.7
cryptography >= 0.8
pyasn1 >= 0.1.7

0 comments on commit 5130ad1

Please sign in to comment.