components/python/paramiko/patches/01-nopycrypto.patch
branchs11-update
changeset 4508 d8924d870370
equal deleted inserted replaced
4506:e5c1a87858fd 4508:d8924d870370
       
     1 External but not-yet-integrated patch that changes Paramiko to use
       
     2 "cryptography" rather than "PyCrypto". The changes have been modified
       
     3 from
       
     4 
       
     5 	https://github.com/paramiko/paramiko/pull/394/files
       
     6 
       
     7 to patch cleanly into Paramiko 1.15.2.
       
     8 This patch is a stop-gap and will be removed when the upstream Paramiko
       
     9 completes the transition to "cryptography".
       
    10 
       
    11 --- paramiko-1.15.2/README.~1~	2014-12-19 15:01:22.000000000 -0800
       
    12 +++ paramiko-1.15.2/README	2015-04-12 17:36:15.204911382 -0700
       
    13 @@ -25,7 +25,7 @@ channels to remote services across the e
       
    14  works, for example).
       
    15  
       
    16  it is written entirely in python (no C or platform-dependent code) and is
       
    17 -released under the GNU LGPL (lesser GPL). 
       
    18 +released under the GNU LGPL (lesser GPL).
       
    19  
       
    20  the package and its API is fairly well documented in the "doc/" folder
       
    21  that should have come with this archive.
       
    22 @@ -36,8 +36,8 @@ Requirements
       
    23  
       
    24    - Python 2.6 or better <http://www.python.org/> - this includes Python
       
    25      3.2 and higher as well.
       
    26 -  - pycrypto 2.1 or better <https://www.dlitz.net/software/pycrypto/>
       
    27 -  - ecdsa 0.9 or better <https://pypi.python.org/pypi/ecdsa>
       
    28 +  - Cryptography 0.8 or better <https://cryptography.io>
       
    29 +  - pyasn1 0.1.7 or better <https://pypi.python.org/pypi/pyasn1>
       
    30  
       
    31  If you have setuptools, you can build and install paramiko and all its
       
    32  dependencies with this command (as root)::
       
    33 --- paramiko-1.15.2/paramiko/_winapi.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
    34 +++ paramiko-1.15.2/paramiko/_winapi.py	2015-04-12 17:36:15.205197752 -0700
       
    35 @@ -106,7 +106,7 @@ MapViewOfFile.restype = ctypes.wintypes.
       
    36  
       
    37  class MemoryMap(object):
       
    38      """
       
    39 -    A memory map object which can have security attributes overrideden.
       
    40 +    A memory map object which can have security attributes overridden.
       
    41      """
       
    42      def __init__(self, name, length, security_attributes=None):
       
    43          self.name = name
       
    44 --- paramiko-1.15.2/paramiko/agent.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
    45 +++ paramiko-1.15.2/paramiko/agent.py	2015-04-12 17:36:15.205474363 -0700
       
    46 @@ -32,7 +32,7 @@ from select import select
       
    47  from paramiko.common import asbytes, io_sleep
       
    48  from paramiko.py3compat import byte_chr
       
    49  
       
    50 -from paramiko.ssh_exception import SSHException
       
    51 +from paramiko.ssh_exception import SSHException, AuthenticationException
       
    52  from paramiko.message import Message
       
    53  from paramiko.pkey import PKey
       
    54  from paramiko.util import retry_on_signal
       
    55 @@ -109,9 +109,12 @@ class AgentProxyThread(threading.Thread)
       
    56      def run(self):
       
    57          try:
       
    58              (r, addr) = self.get_connection()
       
    59 +            # Found that r should be either a socket from the socket library or None
       
    60              self.__inr = r
       
    61 -            self.__addr = addr
       
    62 +            self.__addr = addr # This should be an IP address as a string? or None
       
    63              self._agent.connect()
       
    64 +            if not isinstance(self._agent, int) and (self._agent._conn is None or not hasattr(self._agent._conn, 'fileno')):
       
    65 +                raise AuthenticationException("Unable to connect to SSH agent")
       
    66              self._communicate()
       
    67          except:
       
    68              #XXX Not sure what to do here ... raise or pass ?
       
    69 --- paramiko-1.15.2/paramiko/channel.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
    70 +++ paramiko-1.15.2/paramiko/channel.py	2015-04-12 17:36:15.205880064 -0700
       
    71 @@ -337,7 +337,7 @@ class Channel (ClosingContextManager):
       
    72          further x11 requests can be made from the server to the client,
       
    73          when an x11 application is run in a shell session.
       
    74  
       
    75 -        From RFC4254::
       
    76 +        From :rfc:`4254`::
       
    77  
       
    78              It is RECOMMENDED that the 'x11 authentication cookie' that is
       
    79              sent be a fake, random cookie, and that the cookie be checked and
       
    80 --- paramiko-1.15.2/paramiko/client.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
    81 +++ paramiko-1.15.2/paramiko/client.py	2015-04-12 17:36:15.206296235 -0700
       
    82 @@ -25,6 +25,7 @@ import getpass
       
    83  import os
       
    84  import socket
       
    85  import warnings
       
    86 +from errno import ECONNREFUSED, EHOSTUNREACH
       
    87  
       
    88  from paramiko.agent import Agent
       
    89  from paramiko.common import DEBUG
       
    90 @@ -35,7 +36,9 @@ from paramiko.hostkeys import HostKeys
       
    91  from paramiko.py3compat import string_types
       
    92  from paramiko.resource import ResourceManager
       
    93  from paramiko.rsakey import RSAKey
       
    94 -from paramiko.ssh_exception import SSHException, BadHostKeyException
       
    95 +from paramiko.ssh_exception import (
       
    96 +    SSHException, BadHostKeyException, NoValidConnectionsError
       
    97 +)
       
    98  from paramiko.transport import Transport
       
    99  from paramiko.util import retry_on_signal, ClosingContextManager
       
   100  
       
   101 @@ -172,10 +175,46 @@ class SSHClient (ClosingContextManager):
       
   102          """
       
   103          self._policy = policy
       
   104  
       
   105 -    def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None,
       
   106 -                key_filename=None, timeout=None, allow_agent=True, look_for_keys=True,
       
   107 -                compress=False, sock=None, gss_auth=False, gss_kex=False,
       
   108 -                gss_deleg_creds=True, gss_host=None, banner_timeout=None):
       
   109 +    def _families_and_addresses(self, hostname, port):
       
   110 +        """
       
   111 +        Yield pairs of address families and addresses to try for connecting.
       
   112 +
       
   113 +        :param str hostname: the server to connect to
       
   114 +        :param int port: the server port to connect to
       
   115 +        :returns: Yields an iterable of ``(family, address)`` tuples
       
   116 +        """
       
   117 +        guess = True
       
   118 +        addrinfos = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
       
   119 +        for (family, socktype, proto, canonname, sockaddr) in addrinfos:
       
   120 +            if socktype == socket.SOCK_STREAM:
       
   121 +                yield family, sockaddr
       
   122 +                guess = False
       
   123 +
       
   124 +        # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :(
       
   125 +        # We only do this if we did not get a single result marked as socktype == SOCK_STREAM.
       
   126 +        if guess:
       
   127 +            for family, _, _, _, sockaddr in addrinfos:
       
   128 +                yield family, sockaddr
       
   129 +
       
   130 +    def connect(
       
   131 +        self,
       
   132 +        hostname,
       
   133 +        port=SSH_PORT,
       
   134 +        username=None,
       
   135 +        password=None,
       
   136 +        pkey=None,
       
   137 +        key_filename=None,
       
   138 +        timeout=None,
       
   139 +        allow_agent=True,
       
   140 +        look_for_keys=True,
       
   141 +        compress=False,
       
   142 +        sock=None,
       
   143 +        gss_auth=False,
       
   144 +        gss_kex=False,
       
   145 +        gss_deleg_creds=True,
       
   146 +        gss_host=None,
       
   147 +        banner_timeout=None
       
   148 +    ):
       
   149          """
       
   150          Connect to an SSH server and authenticate to it.  The server's host key
       
   151          is checked against the system host keys (see `load_system_host_keys`)
       
   152 @@ -206,8 +245,10 @@ class SSHClient (ClosingContextManager):
       
   153          :param str key_filename:
       
   154              the filename, or list of filenames, of optional private key(s) to
       
   155              try for authentication
       
   156 -        :param float timeout: an optional timeout (in seconds) for the TCP connect
       
   157 -        :param bool allow_agent: set to False to disable connecting to the SSH agent
       
   158 +        :param float timeout:
       
   159 +            an optional timeout (in seconds) for the TCP connect
       
   160 +        :param bool allow_agent:
       
   161 +            set to False to disable connecting to the SSH agent
       
   162          :param bool look_for_keys:
       
   163              set to False to disable searching for discoverable private key
       
   164              files in ``~/.ssh/``
       
   165 @@ -216,9 +257,11 @@ class SSHClient (ClosingContextManager):
       
   166              an open socket or socket-like object (such as a `.Channel`) to use
       
   167              for communication to the target host
       
   168          :param bool gss_auth: ``True`` if you want to use GSS-API authentication
       
   169 -        :param bool gss_kex: Perform GSS-API Key Exchange and user authentication
       
   170 +        :param bool gss_kex:
       
   171 +            Perform GSS-API Key Exchange and user authentication
       
   172          :param bool gss_deleg_creds: Delegate GSS-API client credentials or not
       
   173 -        :param str gss_host: The targets name in the kerberos database. default: hostname
       
   174 +        :param str gss_host:
       
   175 +            The targets name in the kerberos database. default: hostname
       
   176          :param float banner_timeout: an optional timeout (in seconds) to wait
       
   177              for the SSH banner to be presented.
       
   178  
       
   179 @@ -234,21 +277,37 @@ class SSHClient (ClosingContextManager):
       
   180              ``gss_deleg_creds`` and ``gss_host`` arguments.
       
   181          """
       
   182          if not sock:
       
   183 -            for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
       
   184 -                if socktype == socket.SOCK_STREAM:
       
   185 -                    af = family
       
   186 -                    addr = sockaddr
       
   187 -                    break
       
   188 -            else:
       
   189 -                # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :(
       
   190 -                af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
       
   191 -            sock = socket.socket(af, socket.SOCK_STREAM)
       
   192 -            if timeout is not None:
       
   193 +            errors = {}
       
   194 +            # Try multiple possible address families (e.g. IPv4 vs IPv6)
       
   195 +            to_try = list(self._families_and_addresses(hostname, port))
       
   196 +            for af, addr in to_try:
       
   197                  try:
       
   198 -                    sock.settimeout(timeout)
       
   199 -                except:
       
   200 -                    pass
       
   201 -            retry_on_signal(lambda: sock.connect(addr))
       
   202 +                    sock = socket.socket(af, socket.SOCK_STREAM)
       
   203 +                    if timeout is not None:
       
   204 +                        try:
       
   205 +                            sock.settimeout(timeout)
       
   206 +                        except:
       
   207 +                            pass
       
   208 +                    retry_on_signal(lambda: sock.connect(addr))
       
   209 +                    # Break out of the loop on success
       
   210 +                    break
       
   211 +                except socket.error as e:
       
   212 +                    # Raise anything that isn't a straight up connection error
       
   213 +                    # (such as a resolution error)
       
   214 +                    if e.errno not in (ECONNREFUSED, EHOSTUNREACH):
       
   215 +                        raise
       
   216 +                    # Capture anything else so we know how the run looks once
       
   217 +                    # iteration is complete. Retain info about which attempt
       
   218 +                    # this was.
       
   219 +                    errors[addr] = e
       
   220 +
       
   221 +            # Make sure we explode usefully if no address family attempts
       
   222 +            # succeeded. We've no way of knowing which error is the "right"
       
   223 +            # one, so we construct a hybrid exception containing all the real
       
   224 +            # ones, of a subclass that client code should still be watching for
       
   225 +            # (socket.error)
       
   226 +            if len(errors) == len(to_try):
       
   227 +                raise NoValidConnectionsError(errors)
       
   228  
       
   229          t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds)
       
   230          t.use_compression(compress=compress)
       
   231 --- paramiko-1.15.2/paramiko/config.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
   232 +++ paramiko-1.15.2/paramiko/config.py	2015-04-12 17:36:15.206521239 -0700
       
   233 @@ -98,7 +98,7 @@ class SSHConfig (object):
       
   234  
       
   235          The host-matching rules of OpenSSH's ``ssh_config`` man page are used:
       
   236          For each parameter, the first obtained value will be used.  The
       
   237 -        configuration files contain sections separated by ``Host''
       
   238 +        configuration files contain sections separated by ``Host``
       
   239          specifications, and that section is only applied for hosts that match
       
   240          one of the patterns given in the specification.
       
   241  
       
   242 --- paramiko-1.15.2/paramiko/dsskey.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
   243 +++ paramiko-1.15.2/paramiko/dsskey.py	2015-04-12 17:36:15.206846024 -0700
       
   244 @@ -20,21 +20,23 @@
       
   245  DSS keys.
       
   246  """
       
   247  
       
   248 -import os
       
   249 -from hashlib import sha1
       
   250 -
       
   251 -from Crypto.PublicKey import DSA
       
   252 +from cryptography.exceptions import InvalidSignature
       
   253 +from cryptography.hazmat.backends import default_backend
       
   254 +from cryptography.hazmat.primitives import hashes, serialization
       
   255 +from cryptography.hazmat.primitives.asymmetric import dsa
       
   256 +from cryptography.hazmat.primitives.asymmetric.utils import (
       
   257 +    decode_rfc6979_signature, encode_rfc6979_signature
       
   258 +)
       
   259  
       
   260  from paramiko import util
       
   261  from paramiko.common import zero_byte
       
   262 -from paramiko.py3compat import long
       
   263  from paramiko.ssh_exception import SSHException
       
   264  from paramiko.message import Message
       
   265  from paramiko.ber import BER, BERException
       
   266  from paramiko.pkey import PKey
       
   267  
       
   268  
       
   269 -class DSSKey (PKey):
       
   270 +class DSSKey(PKey):
       
   271      """
       
   272      Representation of a DSS key which can be used to sign an verify SSH2
       
   273      data.
       
   274 @@ -98,15 +100,21 @@ class DSSKey (PKey):
       
   275          return self.x is not None
       
   276  
       
   277      def sign_ssh_data(self, data):
       
   278 -        digest = sha1(data).digest()
       
   279 -        dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q), long(self.x)))
       
   280 -        # generate a suitable k
       
   281 -        qsize = len(util.deflate_long(self.q, 0))
       
   282 -        while True:
       
   283 -            k = util.inflate_long(os.urandom(qsize), 1)
       
   284 -            if (k > 2) and (k < self.q):
       
   285 -                break
       
   286 -        r, s = dss.sign(util.inflate_long(digest, 1), k)
       
   287 +        key = dsa.DSAPrivateNumbers(
       
   288 +            x=self.x,
       
   289 +            public_numbers=dsa.DSAPublicNumbers(
       
   290 +                y=self.y,
       
   291 +                parameter_numbers=dsa.DSAParameterNumbers(
       
   292 +                    p=self.p,
       
   293 +                    q=self.q,
       
   294 +                    g=self.g
       
   295 +                )
       
   296 +            )
       
   297 +        ).private_key(backend=default_backend())
       
   298 +        signer = key.signer(hashes.SHA1())
       
   299 +        signer.update(data)
       
   300 +        r, s = decode_rfc6979_signature(signer.finalize())
       
   301 +
       
   302          m = Message()
       
   303          m.add_string('ssh-dss')
       
   304          # apparently, in rare cases, r or s may be shorter than 20 bytes!
       
   305 @@ -132,27 +140,65 @@ class DSSKey (PKey):
       
   306          # pull out (r, s) which are NOT encoded as mpints
       
   307          sigR = util.inflate_long(sig[:20], 1)
       
   308          sigS = util.inflate_long(sig[20:], 1)
       
   309 -        sigM = util.inflate_long(sha1(data).digest(), 1)
       
   310  
       
   311 -        dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q)))
       
   312 -        return dss.verify(sigM, (sigR, sigS))
       
   313 +        signature = encode_rfc6979_signature(sigR, sigS)
       
   314  
       
   315 -    def _encode_key(self):
       
   316 -        if self.x is None:
       
   317 -            raise SSHException('Not enough key information')
       
   318 -        keylist = [0, self.p, self.q, self.g, self.y, self.x]
       
   319 +        key = dsa.DSAPublicNumbers(
       
   320 +            y=self.y,
       
   321 +            parameter_numbers=dsa.DSAParameterNumbers(
       
   322 +                p=self.p,
       
   323 +                q=self.q,
       
   324 +                g=self.g
       
   325 +            )
       
   326 +        ).public_key(backend=default_backend())
       
   327 +        verifier = key.verifier(signature, hashes.SHA1())
       
   328 +        verifier.update(data)
       
   329          try:
       
   330 -            b = BER()
       
   331 -            b.encode(keylist)
       
   332 -        except BERException:
       
   333 -            raise SSHException('Unable to create ber encoding of key')
       
   334 -        return b.asbytes()
       
   335 +            verifier.verify()
       
   336 +        except InvalidSignature:
       
   337 +            return False
       
   338 +        else:
       
   339 +            return True
       
   340  
       
   341      def write_private_key_file(self, filename, password=None):
       
   342 -        self._write_private_key_file('DSA', filename, self._encode_key(), password)
       
   343 +        key = dsa.DSAPrivateNumbers(
       
   344 +            x=self.x,
       
   345 +            public_numbers=dsa.DSAPublicNumbers(
       
   346 +                y=self.y,
       
   347 +                parameter_numbers=dsa.DSAParameterNumbers(
       
   348 +                    p=self.p,
       
   349 +                    q=self.q,
       
   350 +                    g=self.g
       
   351 +                )
       
   352 +            )
       
   353 +        ).private_key(backend=default_backend())
       
   354 +
       
   355 +        self._write_private_key_file(
       
   356 +            filename,
       
   357 +            key,
       
   358 +            serialization.PrivateFormat.TraditionalOpenSSL,
       
   359 +            password=password
       
   360 +        )
       
   361  
       
   362      def write_private_key(self, file_obj, password=None):
       
   363 -        self._write_private_key('DSA', file_obj, self._encode_key(), password)
       
   364 +        key = dsa.DSAPrivateNumbers(
       
   365 +            x=self.x,
       
   366 +            public_numbers=dsa.DSAPublicNumbers(
       
   367 +                y=self.y,
       
   368 +                parameter_numbers=dsa.DSAParameterNumbers(
       
   369 +                    p=self.p,
       
   370 +                    q=self.q,
       
   371 +                    g=self.g
       
   372 +                )
       
   373 +            )
       
   374 +        ).private_key(backend=default_backend())
       
   375 +
       
   376 +        self._write_private_key(
       
   377 +            file_obj,
       
   378 +            key,
       
   379 +            serialization.PrivateFormat.TraditionalOpenSSL,
       
   380 +            password=password
       
   381 +        )
       
   382  
       
   383      @staticmethod
       
   384      def generate(bits=1024, progress_func=None):
       
   385 @@ -161,14 +207,19 @@ class DSSKey (PKey):
       
   386          generate a new host key or authentication key.
       
   387  
       
   388          :param int bits: number of bits the generated key should be.
       
   389 -        :param function progress_func:
       
   390 -            an optional function to call at key points in key generation (used
       
   391 -            by ``pyCrypto.PublicKey``).
       
   392 +        :param function progress_func: Unused
       
   393          :return: new `.DSSKey` private key
       
   394          """
       
   395 -        dsa = DSA.generate(bits, os.urandom, progress_func)
       
   396 -        key = DSSKey(vals=(dsa.p, dsa.q, dsa.g, dsa.y))
       
   397 -        key.x = dsa.x
       
   398 +        numbers = dsa.generate_private_key(
       
   399 +            bits, backend=default_backend()
       
   400 +        ).private_numbers()
       
   401 +        key = DSSKey(vals=(
       
   402 +            numbers.public_numbers.parameter_numbers.p,
       
   403 +            numbers.public_numbers.parameter_numbers.q,
       
   404 +            numbers.public_numbers.parameter_numbers.g,
       
   405 +            numbers.public_numbers.y
       
   406 +        ))
       
   407 +        key.x = numbers.x
       
   408          return key
       
   409  
       
   410      ###  internals...
       
   411 --- paramiko-1.15.2/paramiko/ecdsakey.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
   412 +++ paramiko-1.15.2/paramiko/ecdsakey.py	2015-04-12 17:36:15.207208398 -0700
       
   413 @@ -21,18 +21,24 @@ ECDSA keys
       
   414  """
       
   415  
       
   416  import binascii
       
   417 -from hashlib import sha256
       
   418  
       
   419 -from ecdsa import SigningKey, VerifyingKey, der, curves
       
   420 +from cryptography.exceptions import InvalidSignature
       
   421 +from cryptography.hazmat.backends import default_backend
       
   422 +from cryptography.hazmat.primitives import hashes, serialization
       
   423 +from cryptography.hazmat.primitives.asymmetric import ec
       
   424 +from cryptography.hazmat.primitives.asymmetric.utils import (
       
   425 +    decode_rfc6979_signature, encode_rfc6979_signature
       
   426 +)
       
   427  
       
   428  from paramiko.common import four_byte, one_byte
       
   429  from paramiko.message import Message
       
   430  from paramiko.pkey import PKey
       
   431 -from paramiko.py3compat import byte_chr, u
       
   432 +from paramiko.py3compat import byte_chr
       
   433  from paramiko.ssh_exception import SSHException
       
   434 +from paramiko.util import deflate_long, inflate_long
       
   435  
       
   436  
       
   437 -class ECDSAKey (PKey):
       
   438 +class ECDSAKey(PKey):
       
   439      """
       
   440      Representation of an ECDSA key which can be used to sign and verify SSH2
       
   441      data.
       
   442 @@ -65,9 +71,13 @@ class ECDSAKey (PKey):
       
   443              if pointinfo[0:1] != four_byte:
       
   444                  raise SSHException('Point compression is being used: %s' %
       
   445                                     binascii.hexlify(pointinfo))
       
   446 -            self.verifying_key = VerifyingKey.from_string(pointinfo[1:],
       
   447 -                                                          curve=curves.NIST256p,
       
   448 -                                                          validate_point=validate_point)
       
   449 +            curve = ec.SECP256R1()
       
   450 +            numbers = ec.EllipticCurvePublicNumbers(
       
   451 +                x=inflate_long(pointinfo[1:1 + curve.key_size // 8], always_positive=True),
       
   452 +                y=inflate_long(pointinfo[1 + curve.key_size // 8:], always_positive=True),
       
   453 +                curve=curve
       
   454 +            )
       
   455 +            self.verifying_key = numbers.public_key(backend=default_backend())
       
   456          self.size = 256
       
   457  
       
   458      def asbytes(self):
       
   459 @@ -76,8 +86,15 @@ class ECDSAKey (PKey):
       
   460          m.add_string('ecdsa-sha2-nistp256')
       
   461          m.add_string('nistp256')
       
   462  
       
   463 -        point_str = four_byte + key.to_string()
       
   464 +        numbers = key.public_numbers()
       
   465  
       
   466 +        x_bytes = deflate_long(numbers.x, add_sign_padding=False)
       
   467 +        x_bytes = b'\x00' * (len(x_bytes) - key.curve.key_size // 8) + x_bytes
       
   468 +
       
   469 +        y_bytes = deflate_long(numbers.y, add_sign_padding=False)
       
   470 +        y_bytes = b'\x00' * (len(y_bytes) - key.curve.key_size // 8) + y_bytes
       
   471 +
       
   472 +        point_str = four_byte + x_bytes + y_bytes
       
   473          m.add_string(point_str)
       
   474          return m.asbytes()
       
   475  
       
   476 @@ -86,8 +103,8 @@ class ECDSAKey (PKey):
       
   477  
       
   478      def __hash__(self):
       
   479          h = hash(self.get_name())
       
   480 -        h = h * 37 + hash(self.verifying_key.pubkey.point.x())
       
   481 -        h = h * 37 + hash(self.verifying_key.pubkey.point.y())
       
   482 +        h = h * 37 + hash(self.verifying_key.public_numbers().x)
       
   483 +        h = h * 37 + hash(self.verifying_key.public_numbers().y)
       
   484          return hash(h)
       
   485  
       
   486      def get_name(self):
       
   487 @@ -100,46 +117,59 @@ class ECDSAKey (PKey):
       
   488          return self.signing_key is not None
       
   489  
       
   490      def sign_ssh_data(self, data):
       
   491 -        sig = self.signing_key.sign_deterministic(
       
   492 -            data, sigencode=self._sigencode, hashfunc=sha256)
       
   493 +        signer = self.signing_key.signer(ec.ECDSA(hashes.SHA256()))
       
   494 +        signer.update(data)
       
   495 +        sig = signer.finalize()
       
   496 +        r, s = decode_rfc6979_signature(sig)
       
   497 +
       
   498          m = Message()
       
   499          m.add_string('ecdsa-sha2-nistp256')
       
   500 -        m.add_string(sig)
       
   501 +        m.add_string(self._sigencode(r, s))
       
   502          return m
       
   503  
       
   504      def verify_ssh_sig(self, data, msg):
       
   505          if msg.get_text() != 'ecdsa-sha2-nistp256':
       
   506              return False
       
   507          sig = msg.get_binary()
       
   508 +        sigR, sigS = self._sigdecode(sig)
       
   509 +        signature = encode_rfc6979_signature(sigR, sigS)
       
   510  
       
   511 -        # verify the signature by SHA'ing the data and encrypting it
       
   512 -        # using the public key.
       
   513 -        hash_obj = sha256(data).digest()
       
   514 -        return self.verifying_key.verify_digest(sig, hash_obj,
       
   515 -                                                sigdecode=self._sigdecode)
       
   516 +        verifier = self.verifying_key.verifier(signature, ec.ECDSA(hashes.SHA256()))
       
   517 +        verifier.update(data)
       
   518 +        try:
       
   519 +            verifier.verify()
       
   520 +        except InvalidSignature:
       
   521 +            return False
       
   522 +        else:
       
   523 +            return True
       
   524  
       
   525      def write_private_key_file(self, filename, password=None):
       
   526 -        key = self.signing_key or self.verifying_key
       
   527 -        self._write_private_key_file('EC', filename, key.to_der(), password)
       
   528 +        self._write_private_key_file(
       
   529 +            filename,
       
   530 +            self.signing_key,
       
   531 +            serialization.PrivateFormat.TraditionalOpenSSL,
       
   532 +            password=password
       
   533 +        )
       
   534  
       
   535      def write_private_key(self, file_obj, password=None):
       
   536 -        key = self.signing_key or self.verifying_key
       
   537 -        self._write_private_key('EC', file_obj, key.to_der(), password)
       
   538 +        self._write_private_key(
       
   539 +            file_obj,
       
   540 +            self.signing_key,
       
   541 +            serialization.PrivateFormat.TraditionalOpenSSL,
       
   542 +            password=password
       
   543 +        )
       
   544  
       
   545      @staticmethod
       
   546 -    def generate(curve=curves.NIST256p, progress_func=None):
       
   547 +    def generate(curve=ec.SECP256R1(), progress_func=None):
       
   548          """
       
   549          Generate a new private RSA key.  This factory function can be used to
       
   550          generate a new host key or authentication key.
       
   551  
       
   552 -        :param function progress_func:
       
   553 -            an optional function to call at key points in key generation (used
       
   554 -            by ``pyCrypto.PublicKey``).
       
   555 +        :param function progress_func: Unused
       
   556          :returns: A new private key (`.RSAKey`) object
       
   557          """
       
   558 -        signing_key = SigningKey.generate(curve)
       
   559 -        key = ECDSAKey(vals=(signing_key, signing_key.get_verifying_key()))
       
   560 -        return key
       
   561 +        private_key = ec.generate_private_key(curve, backend=default_backend())
       
   562 +        return ECDSAKey(vals=(private_key, private_key.public_key()))
       
   563  
       
   564      ###  internals...
       
   565  
       
   566 @@ -155,23 +185,18 @@ class ECDSAKey (PKey):
       
   567                          byte_chr(5) * 5, byte_chr(6) * 6, byte_chr(7) * 7]
       
   568  
       
   569      def _decode_key(self, data):
       
   570 -        s, padding = der.remove_sequence(data)
       
   571 -        if padding:
       
   572 -            if padding not in self.ALLOWED_PADDINGS:
       
   573 -                raise ValueError("weird padding: %s" % u(binascii.hexlify(data)))
       
   574 -            data = data[:-len(padding)]
       
   575 -        key = SigningKey.from_der(data)
       
   576 +        key = serialization.load_der_private_key(data, password=None, backend=default_backend())
       
   577          self.signing_key = key
       
   578 -        self.verifying_key = key.get_verifying_key()
       
   579 -        self.size = 256
       
   580 +        self.verifying_key = key.public_key()
       
   581 +        self.size = key.curve.key_size
       
   582  
       
   583 -    def _sigencode(self, r, s, order):
       
   584 +    def _sigencode(self, r, s):
       
   585          msg = Message()
       
   586          msg.add_mpint(r)
       
   587          msg.add_mpint(s)
       
   588          return msg.asbytes()
       
   589  
       
   590 -    def _sigdecode(self, sig, order):
       
   591 +    def _sigdecode(self, sig):
       
   592          msg = Message(sig)
       
   593          r = msg.get_mpint()
       
   594          s = msg.get_mpint()
       
   595 --- paramiko-1.15.2/paramiko/kex_gss.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
   596 +++ paramiko-1.15.2/paramiko/kex_gss.py	2015-04-12 17:36:15.207554941 -0700
       
   597 @@ -21,14 +21,15 @@
       
   598  
       
   599  
       
   600  """
       
   601 -This module provides GSS-API / SSPI Key Exchange as defined in RFC 4462.
       
   602 +This module provides GSS-API / SSPI Key Exchange as defined in :rfc:`4462`.
       
   603  
       
   604  .. note:: Credential delegation is not supported in server mode.
       
   605  
       
   606  .. note::
       
   607 -    `RFC 4462 Section 2.2 <http://www.ietf.org/rfc/rfc4462.txt>`_ says we are
       
   608 -    not required to implement GSS-API error messages. Thus, in many methods
       
   609 -    within this module, if an error occurs an exception will be thrown and the
       
   610 +    `RFC 4462 Section 2.2
       
   611 +    <https://tools.ietf.org/html/rfc4462.html#section-2.2>`_ says we are not
       
   612 +    required to implement GSS-API error messages. Thus, in many methods within
       
   613 +    this module, if an error occurs an exception will be thrown and the
       
   614      connection will be terminated.
       
   615  
       
   616  .. seealso:: :doc:`/api/ssh_gss`
       
   617 @@ -55,8 +56,8 @@ c_MSG_KEXGSS_GROUPREQ, c_MSG_KEXGSS_GROU
       
   618  
       
   619  class KexGSSGroup1(object):
       
   620      """
       
   621 -    GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange
       
   622 -    as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_
       
   623 +    GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange as defined in `RFC
       
   624 +    4462 Section 2 <https://tools.ietf.org/html/rfc4462.html#section-2>`_
       
   625      """
       
   626      # draft-ietf-secsh-transport-09.txt, page 17
       
   627      P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF
       
   628 @@ -278,8 +279,9 @@ class KexGSSGroup1(object):
       
   629  
       
   630  class KexGSSGroup14(KexGSSGroup1):
       
   631      """
       
   632 -    GSS-API / SSPI Authenticated Diffie-Hellman Group14 Key Exchange
       
   633 -    as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_
       
   634 +    GSS-API / SSPI Authenticated Diffie-Hellman Group14 Key Exchange as defined
       
   635 +    in `RFC 4462 Section 2
       
   636 +    <https://tools.ietf.org/html/rfc4462.html#section-2>`_
       
   637      """
       
   638      P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF
       
   639      G = 2
       
   640 @@ -288,8 +290,8 @@ class KexGSSGroup14(KexGSSGroup1):
       
   641  
       
   642  class KexGSSGex(object):
       
   643      """
       
   644 -    GSS-API / SSPI Authenticated Diffie-Hellman Group Exchange
       
   645 -    as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_
       
   646 +    GSS-API / SSPI Authenticated Diffie-Hellman Group Exchange as defined in
       
   647 +    `RFC 4462 Section 2 <https://tools.ietf.org/html/rfc4462.html#section-2>`_
       
   648      """
       
   649      NAME = "gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g=="
       
   650      min_bits = 1024
       
   651 @@ -590,8 +592,9 @@ class KexGSSGex(object):
       
   652  
       
   653  class NullHostKey(object):
       
   654      """
       
   655 -    This class represents the Null Host Key for GSS-API Key Exchange
       
   656 -    as defined in `RFC 4462 Section 5 <http://www.ietf.org/rfc/rfc4462.txt>`_
       
   657 +    This class represents the Null Host Key for GSS-API Key Exchange as defined
       
   658 +    in `RFC 4462 Section 5
       
   659 +    <https://tools.ietf.org/html/rfc4462.html#section-5>`_
       
   660      """
       
   661      def __init__(self):
       
   662          self.key = ""
       
   663 --- paramiko-1.15.2/paramiko/packet.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
   664 +++ paramiko-1.15.2/paramiko/packet.py	2015-04-12 17:36:15.207839345 -0700
       
   665 @@ -307,7 +307,7 @@ class Packetizer (object):
       
   666                  self._log(DEBUG, 'Write packet <%s>, length %d' % (cmd_name, orig_len))
       
   667                  self._log(DEBUG, util.format_binary(packet, 'OUT: '))
       
   668              if self.__block_engine_out is not None:
       
   669 -                out = self.__block_engine_out.encrypt(packet)
       
   670 +                out = self.__block_engine_out.update(packet)
       
   671              else:
       
   672                  out = packet
       
   673              # + mac
       
   674 @@ -340,7 +340,7 @@ class Packetizer (object):
       
   675          """
       
   676          header = self.read_all(self.__block_size_in, check_rekey=True)
       
   677          if self.__block_engine_in is not None:
       
   678 -            header = self.__block_engine_in.decrypt(header)
       
   679 +            header = self.__block_engine_in.update(header)
       
   680          if self.__dump_packets:
       
   681              self._log(DEBUG, util.format_binary(header, 'IN: '))
       
   682          packet_size = struct.unpack('>I', header[:4])[0]
       
   683 @@ -352,7 +352,7 @@ class Packetizer (object):
       
   684          packet = buf[:packet_size - len(leftover)]
       
   685          post_packet = buf[packet_size - len(leftover):]
       
   686          if self.__block_engine_in is not None:
       
   687 -            packet = self.__block_engine_in.decrypt(packet)
       
   688 +            packet = self.__block_engine_in.update(packet)
       
   689          if self.__dump_packets:
       
   690              self._log(DEBUG, util.format_binary(packet, 'IN: '))
       
   691          packet = leftover + packet
       
   692 --- paramiko-1.15.2/paramiko/pkey.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
   693 +++ paramiko-1.15.2/paramiko/pkey.py	2015-04-12 17:36:15.208139348 -0700
       
   694 @@ -21,27 +21,39 @@ Common API for all public keys.
       
   695  """
       
   696  
       
   697  import base64
       
   698 -from binascii import hexlify, unhexlify
       
   699 +from binascii import unhexlify
       
   700  import os
       
   701  from hashlib import md5
       
   702  
       
   703 -from Crypto.Cipher import DES3, AES
       
   704 +from cryptography.hazmat.backends import default_backend
       
   705 +from cryptography.hazmat.primitives import serialization
       
   706 +from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher
       
   707  
       
   708  from paramiko import util
       
   709 -from paramiko.common import o600, zero_byte
       
   710 +from paramiko.common import o600
       
   711  from paramiko.py3compat import u, encodebytes, decodebytes, b
       
   712  from paramiko.ssh_exception import SSHException, PasswordRequiredException
       
   713  
       
   714  
       
   715 -class PKey (object):
       
   716 +class PKey(object):
       
   717      """
       
   718      Base class for public keys.
       
   719      """
       
   720  
       
   721      # known encryption types for private key files:
       
   722      _CIPHER_TABLE = {
       
   723 -        'AES-128-CBC': {'cipher': AES, 'keysize': 16, 'blocksize': 16, 'mode': AES.MODE_CBC},
       
   724 -        'DES-EDE3-CBC': {'cipher': DES3, 'keysize': 24, 'blocksize': 8, 'mode': DES3.MODE_CBC},
       
   725 +        'AES-128-CBC': {
       
   726 +            'cipher': algorithms.AES,
       
   727 +            'keysize': 16,
       
   728 +            'blocksize': 16,
       
   729 +            'mode': modes.CBC
       
   730 +        },
       
   731 +        'DES-EDE3-CBC': {
       
   732 +            'cipher': algorithms.TripleDES,
       
   733 +            'keysize': 24,
       
   734 +            'blocksize': 8,
       
   735 +            'mode': modes.CBC
       
   736 +        },
       
   737      }
       
   738  
       
   739      def __init__(self, msg=None, data=None):
       
   740 @@ -300,9 +312,12 @@ class PKey (object):
       
   741          mode = self._CIPHER_TABLE[encryption_type]['mode']
       
   742          salt = unhexlify(b(saltstr))
       
   743          key = util.generate_key_bytes(md5, salt, password, keysize)
       
   744 -        return cipher.new(key, mode, salt).decrypt(data)
       
   745 +        decryptor = Cipher(
       
   746 +            cipher(key), mode(salt), backend=default_backend()
       
   747 +        ).decryptor()
       
   748 +        return decryptor.update(data) + decryptor.finalize()
       
   749  
       
   750 -    def _write_private_key_file(self, tag, filename, data, password=None):
       
   751 +    def _write_private_key_file(self, filename, key, format, password=None):
       
   752          """
       
   753          Write an SSH2-format private key file in a form that can be read by
       
   754          paramiko or openssh.  If no password is given, the key is written in
       
   755 @@ -319,31 +334,16 @@ class PKey (object):
       
   756          with open(filename, 'w', o600) as f:
       
   757              # grrr... the mode doesn't always take hold
       
   758              os.chmod(filename, o600)
       
   759 -            self._write_private_key(tag, f, data, password)
       
   760 +            self._write_private_key(f, key, format)
       
   761  
       
   762 -    def _write_private_key(self, tag, f, data, password=None):
       
   763 -        f.write('-----BEGIN %s PRIVATE KEY-----\n' % tag)
       
   764 -        if password is not None:
       
   765 -            cipher_name = list(self._CIPHER_TABLE.keys())[0]
       
   766 -            cipher = self._CIPHER_TABLE[cipher_name]['cipher']
       
   767 -            keysize = self._CIPHER_TABLE[cipher_name]['keysize']
       
   768 -            blocksize = self._CIPHER_TABLE[cipher_name]['blocksize']
       
   769 -            mode = self._CIPHER_TABLE[cipher_name]['mode']
       
   770 -            salt = os.urandom(blocksize)
       
   771 -            key = util.generate_key_bytes(md5, salt, password, keysize)
       
   772 -            if len(data) % blocksize != 0:
       
   773 -                n = blocksize - len(data) % blocksize
       
   774 -                #data += os.urandom(n)
       
   775 -                # that would make more sense ^, but it confuses openssh.
       
   776 -                data += zero_byte * n
       
   777 -            data = cipher.new(key, mode, salt).encrypt(data)
       
   778 -            f.write('Proc-Type: 4,ENCRYPTED\n')
       
   779 -            f.write('DEK-Info: %s,%s\n' % (cipher_name, u(hexlify(salt)).upper()))
       
   780 -            f.write('\n')
       
   781 -        s = u(encodebytes(data))
       
   782 -        # re-wrap to 64-char lines
       
   783 -        s = ''.join(s.split('\n'))
       
   784 -        s = '\n'.join([s[i: i + 64] for i in range(0, len(s), 64)])
       
   785 -        f.write(s)
       
   786 -        f.write('\n')
       
   787 -        f.write('-----END %s PRIVATE KEY-----\n' % tag)
       
   788 +    def _write_private_key(self, f, key, format, password=None):
       
   789 +        if password is None:
       
   790 +            encryption = serialization.NoEncryption()
       
   791 +        else:
       
   792 +            encryption = serialization.BestEncryption(password)
       
   793 +
       
   794 +        f.write(key.private_bytes(
       
   795 +            serialization.Encoding.PEM,
       
   796 +            format,
       
   797 +            encryption
       
   798 +        ).decode())
       
   799 --- paramiko-1.15.2/paramiko/rsakey.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
   800 +++ paramiko-1.15.2/paramiko/rsakey.py	2015-04-12 17:36:15.208516662 -0700
       
   801 @@ -20,34 +20,26 @@
       
   802  RSA keys.
       
   803  """
       
   804  
       
   805 -import os
       
   806 -from hashlib import sha1
       
   807 +from cryptography.exceptions import InvalidSignature
       
   808 +from cryptography.hazmat.backends import default_backend
       
   809 +from cryptography.hazmat.primitives import hashes, serialization
       
   810 +from cryptography.hazmat.primitives.asymmetric import rsa, padding
       
   811  
       
   812 -from Crypto.PublicKey import RSA
       
   813 -
       
   814 -from paramiko import util
       
   815 -from paramiko.common import max_byte, zero_byte, one_byte
       
   816  from paramiko.message import Message
       
   817 -from paramiko.ber import BER, BERException
       
   818  from paramiko.pkey import PKey
       
   819 -from paramiko.py3compat import long
       
   820  from paramiko.ssh_exception import SSHException
       
   821  
       
   822  SHA1_DIGESTINFO = b'\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'
       
   823  
       
   824  
       
   825 -class RSAKey (PKey):
       
   826 +class RSAKey(PKey):
       
   827      """
       
   828      Representation of an RSA key which can be used to sign and verify SSH2
       
   829      data.
       
   830      """
       
   831  
       
   832 -    def __init__(self, msg=None, data=None, filename=None, password=None, vals=None, file_obj=None):
       
   833 -        self.n = None
       
   834 -        self.e = None
       
   835 -        self.d = None
       
   836 -        self.p = None
       
   837 -        self.q = None
       
   838 +    def __init__(self, msg=None, data=None, filename=None, password=None, key=None, file_obj=None):
       
   839 +        self.key = None
       
   840          if file_obj is not None:
       
   841              self._from_private_key(file_obj, password)
       
   842              return
       
   843 @@ -56,22 +48,33 @@ class RSAKey (PKey):
       
   844              return
       
   845          if (msg is None) and (data is not None):
       
   846              msg = Message(data)
       
   847 -        if vals is not None:
       
   848 -            self.e, self.n = vals
       
   849 +        if key is not None:
       
   850 +            self.key = key
       
   851          else:
       
   852              if msg is None:
       
   853                  raise SSHException('Key object may not be empty')
       
   854              if msg.get_text() != 'ssh-rsa':
       
   855                  raise SSHException('Invalid key')
       
   856 -            self.e = msg.get_mpint()
       
   857 -            self.n = msg.get_mpint()
       
   858 -        self.size = util.bit_length(self.n)
       
   859 +            self.key = rsa.RSAPublicNumbers(
       
   860 +                e=msg.get_mpint(), n=msg.get_mpint()
       
   861 +            ).public_key(default_backend())
       
   862 +
       
   863 +    @property
       
   864 +    def size(self):
       
   865 +        return self.key.key_size
       
   866 +
       
   867 +    @property
       
   868 +    def public_numbers(self):
       
   869 +        if isinstance(self.key, rsa.RSAPrivateKey):
       
   870 +            return self.key.private_numbers().public_numbers
       
   871 +        else:
       
   872 +            return self.key.public_numbers()
       
   873  
       
   874      def asbytes(self):
       
   875          m = Message()
       
   876          m.add_string('ssh-rsa')
       
   877 -        m.add_mpint(self.e)
       
   878 -        m.add_mpint(self.n)
       
   879 +        m.add_mpint(self.public_numbers.e)
       
   880 +        m.add_mpint(self.public_numbers.n)
       
   881          return m.asbytes()
       
   882  
       
   883      def __str__(self):
       
   884 @@ -79,8 +82,8 @@ class RSAKey (PKey):
       
   885  
       
   886      def __hash__(self):
       
   887          h = hash(self.get_name())
       
   888 -        h = h * 37 + hash(self.e)
       
   889 -        h = h * 37 + hash(self.n)
       
   890 +        h = h * 37 + hash(self.public_numbers.e)
       
   891 +        h = h * 37 + hash(self.public_numbers.n)
       
   892          return hash(h)
       
   893  
       
   894      def get_name(self):
       
   895 @@ -90,12 +93,16 @@ class RSAKey (PKey):
       
   896          return self.size
       
   897  
       
   898      def can_sign(self):
       
   899 -        return self.d is not None
       
   900 +        return isinstance(self.key, rsa.RSAPrivateKey)
       
   901  
       
   902      def sign_ssh_data(self, data):
       
   903 -        digest = sha1(data).digest()
       
   904 -        rsa = RSA.construct((long(self.n), long(self.e), long(self.d)))
       
   905 -        sig = util.deflate_long(rsa.sign(self._pkcs1imify(digest), bytes())[0], 0)
       
   906 +        signer = self.key.signer(
       
   907 +            padding=padding.PKCS1v15(),
       
   908 +            algorithm=hashes.SHA1(),
       
   909 +        )
       
   910 +        signer.update(data)
       
   911 +        sig = signer.finalize()
       
   912 +
       
   913          m = Message()
       
   914          m.add_string('ssh-rsa')
       
   915          m.add_string(sig)
       
   916 @@ -104,32 +111,38 @@ class RSAKey (PKey):
       
   917      def verify_ssh_sig(self, data, msg):
       
   918          if msg.get_text() != 'ssh-rsa':
       
   919              return False
       
   920 -        sig = util.inflate_long(msg.get_binary(), True)
       
   921 -        # verify the signature by SHA'ing the data and encrypting it using the
       
   922 -        # public key.  some wackiness ensues where we "pkcs1imify" the 20-byte
       
   923 -        # hash into a string as long as the RSA key.
       
   924 -        hash_obj = util.inflate_long(self._pkcs1imify(sha1(data).digest()), True)
       
   925 -        rsa = RSA.construct((long(self.n), long(self.e)))
       
   926 -        return rsa.verify(hash_obj, (sig,))
       
   927 -
       
   928 -    def _encode_key(self):
       
   929 -        if (self.p is None) or (self.q is None):
       
   930 -            raise SSHException('Not enough key info to write private key file')
       
   931 -        keylist = [0, self.n, self.e, self.d, self.p, self.q,
       
   932 -                   self.d % (self.p - 1), self.d % (self.q - 1),
       
   933 -                   util.mod_inverse(self.q, self.p)]
       
   934 +        key = self.key
       
   935 +        if isinstance(key, rsa.RSAPrivateKey):
       
   936 +            key = key.public_key()
       
   937 +
       
   938 +        verifier = key.verifier(
       
   939 +            signature=msg.get_binary(),
       
   940 +            padding=padding.PKCS1v15(),
       
   941 +            algorithm=hashes.SHA1(),
       
   942 +        )
       
   943 +        verifier.update(data)
       
   944          try:
       
   945 -            b = BER()
       
   946 -            b.encode(keylist)
       
   947 -        except BERException:
       
   948 -            raise SSHException('Unable to create ber encoding of key')
       
   949 -        return b.asbytes()
       
   950 +            verifier.verify()
       
   951 +        except InvalidSignature:
       
   952 +            return False
       
   953 +        else:
       
   954 +            return True
       
   955  
       
   956      def write_private_key_file(self, filename, password=None):
       
   957 -        self._write_private_key_file('RSA', filename, self._encode_key(), password)
       
   958 +        self._write_private_key_file(
       
   959 +            filename,
       
   960 +            self.key,
       
   961 +            serialization.PrivateFormat.TraditionalOpenSSL,
       
   962 +            password=password
       
   963 +        )
       
   964  
       
   965      def write_private_key(self, file_obj, password=None):
       
   966 -        self._write_private_key('RSA', file_obj, self._encode_key(), password)
       
   967 +        self._write_private_key(
       
   968 +            file_obj,
       
   969 +            self.key,
       
   970 +            serialization.PrivateFormat.TraditionalOpenSSL,
       
   971 +            password=password
       
   972 +        )
       
   973  
       
   974      @staticmethod
       
   975      def generate(bits, progress_func=None):
       
   976 @@ -138,29 +151,16 @@ class RSAKey (PKey):
       
   977          generate a new host key or authentication key.
       
   978  
       
   979          :param int bits: number of bits the generated key should be.
       
   980 -        :param function progress_func:
       
   981 -            an optional function to call at key points in key generation (used
       
   982 -            by ``pyCrypto.PublicKey``).
       
   983 +        :param function progress_func: Unused
       
   984          :return: new `.RSAKey` private key
       
   985          """
       
   986 -        rsa = RSA.generate(bits, os.urandom, progress_func)
       
   987 -        key = RSAKey(vals=(rsa.e, rsa.n))
       
   988 -        key.d = rsa.d
       
   989 -        key.p = rsa.p
       
   990 -        key.q = rsa.q
       
   991 -        return key
       
   992 +        key = rsa.generate_private_key(
       
   993 +            public_exponent=65537, key_size=bits, backend=default_backend()
       
   994 +        )
       
   995 +        return RSAKey(key=key)
       
   996  
       
   997      ###  internals...
       
   998  
       
   999 -    def _pkcs1imify(self, data):
       
  1000 -        """
       
  1001 -        turn a 20-byte SHA1 hash into a blob of data as large as the key's N,
       
  1002 -        using PKCS1's \"emsa-pkcs1-v1_5\" encoding.  totally bizarre.
       
  1003 -        """
       
  1004 -        size = len(util.deflate_long(self.n, 0))
       
  1005 -        filler = max_byte * (size - len(SHA1_DIGESTINFO) - len(data) - 3)
       
  1006 -        return zero_byte + one_byte + filler + zero_byte + SHA1_DIGESTINFO + data
       
  1007 -
       
  1008      def _from_private_key_file(self, filename, password):
       
  1009          data = self._read_private_key_file('RSA', filename, password)
       
  1010          self._decode_key(data)
       
  1011 @@ -170,18 +170,8 @@ class RSAKey (PKey):
       
  1012          self._decode_key(data)
       
  1013  
       
  1014      def _decode_key(self, data):
       
  1015 -        # private key file contains:
       
  1016 -        # RSAPrivateKey = { version = 0, n, e, d, p, q, d mod p-1, d mod q-1, q**-1 mod p }
       
  1017 -        try:
       
  1018 -            keylist = BER(data).decode()
       
  1019 -        except BERException:
       
  1020 -            raise SSHException('Unable to parse key file')
       
  1021 -        if (type(keylist) is not list) or (len(keylist) < 4) or (keylist[0] != 0):
       
  1022 -            raise SSHException('Not a valid RSA private key file (bad ber encoding)')
       
  1023 -        self.n = keylist[1]
       
  1024 -        self.e = keylist[2]
       
  1025 -        self.d = keylist[3]
       
  1026 -        # not really needed
       
  1027 -        self.p = keylist[4]
       
  1028 -        self.q = keylist[5]
       
  1029 -        self.size = util.bit_length(self.n)
       
  1030 +        key = serialization.load_der_private_key(
       
  1031 +            data, password=None, backend=default_backend()
       
  1032 +        )
       
  1033 +        assert isinstance(key, rsa.RSAPrivateKey)
       
  1034 +        self.key = key
       
  1035 --- paramiko-1.15.2/paramiko/ssh_exception.py.~1~	2014-09-08 10:42:16.000000000 -0700
       
  1036 +++ paramiko-1.15.2/paramiko/ssh_exception.py	2015-04-12 17:36:15.208756832 -0700
       
  1037 @@ -16,6 +16,8 @@
       
  1038  # along with Paramiko; if not, write to the Free Software Foundation, Inc.,
       
  1039  # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
       
  1040  
       
  1041 +import socket
       
  1042 +
       
  1043  
       
  1044  class SSHException (Exception):
       
  1045      """
       
  1046 @@ -129,3 +131,39 @@ class ProxyCommandFailure (SSHException)
       
  1047          self.error = error
       
  1048          # for unpickling
       
  1049          self.args = (command, error, )
       
  1050 +
       
  1051 +
       
  1052 +class NoValidConnectionsError(socket.error):
       
  1053 +    """
       
  1054 +    Multiple connection attempts were made and no families succeeded.
       
  1055 +
       
  1056 +    This exception class wraps multiple "real" underlying connection errors,
       
  1057 +    all of which represent failed connection attempts. Because these errors are
       
  1058 +    not guaranteed to all be of the same error type (i.e. different errno,
       
  1059 +    class, message, etc) we expose a single unified error message and a
       
  1060 +    ``None`` errno so that instances of this class match most normal handling
       
  1061 +    of `socket.error` objects.
       
  1062 +    
       
  1063 +    To see the wrapped exception objects, access the ``errors`` attribute.
       
  1064 +    ``errors`` is a dict whose keys are address tuples (e.g. ``('127.0.0.1',
       
  1065 +    22)``) and whose values are the exception encountered trying to connect to
       
  1066 +    that address.
       
  1067 +
       
  1068 +    It is implied/assumed that all the errors given to a single instance of
       
  1069 +    this class are from connecting to the same hostname + port (and thus that
       
  1070 +    the differences are in the resolution of the hostname - e.g. IPv4 vs v6).
       
  1071 +    """
       
  1072 +    def __init__(self, errors):
       
  1073 +        """
       
  1074 +        :param dict errors:
       
  1075 +            The errors dict to store, as described by class docstring.
       
  1076 +        """
       
  1077 +        addrs = errors.keys()
       
  1078 +        body = ', '.join([x[0] for x in addrs[:-1]])
       
  1079 +        tail = addrs[-1][0]
       
  1080 +        msg = "Unable to connect to port {0} on {1} or {2}"
       
  1081 +        super(NoValidConnectionsError, self).__init__(
       
  1082 +            None, # stand-in for errno
       
  1083 +            msg.format(addrs[0][1], body, tail)
       
  1084 +        )
       
  1085 +        self.errors = errors
       
  1086 --- paramiko-1.15.2/paramiko/ssh_gss.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1087 +++ paramiko-1.15.2/paramiko/ssh_gss.py	2015-04-12 17:36:15.209036497 -0700
       
  1088 @@ -20,7 +20,7 @@
       
  1089  
       
  1090  
       
  1091  """
       
  1092 -This module provides GSS-API / SSPI  authentication as defined in RFC 4462.
       
  1093 +This module provides GSS-API / SSPI  authentication as defined in :rfc:`4462`.
       
  1094  
       
  1095  .. note:: Credential delegation is not supported in server mode.
       
  1096  
       
  1097 @@ -39,22 +39,8 @@ import sys
       
  1098  """
       
  1099  GSS_AUTH_AVAILABLE = True
       
  1100  
       
  1101 -try:
       
  1102 -    from pyasn1.type.univ import ObjectIdentifier
       
  1103 -    from pyasn1.codec.der import encoder, decoder
       
  1104 -except ImportError:
       
  1105 -    GSS_AUTH_AVAILABLE = False
       
  1106 -    class ObjectIdentifier(object):
       
  1107 -        def __init__(self, *args):
       
  1108 -            raise NotImplementedError("Module pyasn1 not importable")
       
  1109 -
       
  1110 -    class decoder(object):
       
  1111 -        def decode(self):
       
  1112 -            raise NotImplementedError("Module pyasn1 not importable")
       
  1113 -
       
  1114 -    class encoder(object):
       
  1115 -        def encode(self):
       
  1116 -            raise NotImplementedError("Module pyasn1 not importable")
       
  1117 +from pyasn1.type.univ import ObjectIdentifier
       
  1118 +from pyasn1.codec.der import encoder, decoder
       
  1119  
       
  1120  from paramiko.common import MSG_USERAUTH_REQUEST
       
  1121  from paramiko.ssh_exception import SSHException
       
  1122 --- paramiko-1.15.2/paramiko/transport.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1123 +++ paramiko-1.15.2/paramiko/transport.py	2015-04-12 17:36:15.209751892 -0700
       
  1124 @@ -28,6 +28,9 @@ import time
       
  1125  import weakref
       
  1126  from hashlib import md5, sha1
       
  1127  
       
  1128 +from cryptography.hazmat.backends import default_backend
       
  1129 +from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes
       
  1130 +
       
  1131  import paramiko
       
  1132  from paramiko import util
       
  1133  from paramiko.auth_handler import AuthHandler
       
  1134 @@ -63,11 +66,6 @@ from paramiko.ssh_exception import (SSHE
       
  1135                                      ChannelException, ProxyCommandFailure)
       
  1136  from paramiko.util import retry_on_signal, ClosingContextManager, clamp_value
       
  1137  
       
  1138 -from Crypto.Cipher import Blowfish, AES, DES3, ARC4
       
  1139 -try:
       
  1140 -    from Crypto.Util import Counter
       
  1141 -except ImportError:
       
  1142 -    from paramiko.util import Counter
       
  1143  
       
  1144  
       
  1145  # for thread cleanup
       
  1146 @@ -91,6 +89,9 @@ class Transport (threading.Thread, Closi
       
  1147  
       
  1148      Instances of this class may be used as context managers.
       
  1149      """
       
  1150 +    _ENCRYPT = object()
       
  1151 +    _DECRYPT = object()
       
  1152 +
       
  1153      _PROTO_ID = '2.0'
       
  1154      _CLIENT_ID = 'paramiko_%s' % paramiko.__version__
       
  1155  
       
  1156 @@ -102,16 +103,57 @@ class Transport (threading.Thread, Closi
       
  1157      _preferred_compression = ('none',)
       
  1158  
       
  1159      _cipher_info = {
       
  1160 -        'aes128-ctr': {'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 16},
       
  1161 -        'aes256-ctr': {'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 32},
       
  1162 -        'blowfish-cbc': {'class': Blowfish, 'mode': Blowfish.MODE_CBC, 'block-size': 8, 'key-size': 16},
       
  1163 -        'aes128-cbc': {'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 16},
       
  1164 -        'aes256-cbc': {'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 32},
       
  1165 -        '3des-cbc': {'class': DES3, 'mode': DES3.MODE_CBC, 'block-size': 8, 'key-size': 24},
       
  1166 -        'arcfour128': {'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 16},
       
  1167 -        'arcfour256': {'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 32},
       
  1168 +        'aes128-ctr': {
       
  1169 +            'class': algorithms.AES,
       
  1170 +            'mode': modes.CTR,
       
  1171 +            'block-size': 16,
       
  1172 +            'key-size': 16
       
  1173 +        },
       
  1174 +        'aes256-ctr': {
       
  1175 +            'class': algorithms.AES,
       
  1176 +            'mode': modes.CTR,
       
  1177 +            'block-size': 16,
       
  1178 +            'key-size': 32
       
  1179 +        },
       
  1180 +        'blowfish-cbc': {
       
  1181 +            'class': algorithms.Blowfish,
       
  1182 +            'mode': modes.CBC,
       
  1183 +            'block-size': 8,
       
  1184 +            'key-size': 16
       
  1185 +        },
       
  1186 +        'aes128-cbc': {
       
  1187 +            'class': algorithms.AES,
       
  1188 +            'mode': modes.CBC,
       
  1189 +            'block-size': 16,
       
  1190 +            'key-size': 16
       
  1191 +        },
       
  1192 +        'aes256-cbc': {
       
  1193 +            'class': algorithms.AES,
       
  1194 +            'mode': modes.CBC,
       
  1195 +            'block-size': 16,
       
  1196 +            'key-size': 32
       
  1197 +        },
       
  1198 +        '3des-cbc': {
       
  1199 +            'class': algorithms.TripleDES,
       
  1200 +            'mode': modes.CBC,
       
  1201 +            'block-size': 8,
       
  1202 +            'key-size': 24
       
  1203 +        },
       
  1204 +        'arcfour128': {
       
  1205 +            'class': algorithms.ARC4,
       
  1206 +            'mode': None,
       
  1207 +            'block size': 8,
       
  1208 +            'key-size': 16
       
  1209 +        },
       
  1210 +        'arcfour256': {
       
  1211 +            'class': algorithms.ARC4,
       
  1212 +            'mode': None,
       
  1213 +            'block size': 8,
       
  1214 +            'key-size': 32
       
  1215 +        },
       
  1216      }
       
  1217  
       
  1218 +
       
  1219      _mac_info = {
       
  1220          'hmac-sha1': {'class': sha1, 'size': 20},
       
  1221          'hmac-sha1-96': {'class': sha1, 'size': 12},
       
  1222 @@ -1508,22 +1550,34 @@ class Transport (threading.Thread, Closi
       
  1223              sofar += digest
       
  1224          return out[:nbytes]
       
  1225  
       
  1226 -    def _get_cipher(self, name, key, iv):
       
  1227 +    def _get_cipher(self, name, key, iv, operation):
       
  1228          if name not in self._cipher_info:
       
  1229              raise SSHException('Unknown client cipher ' + name)
       
  1230          if name in ('arcfour128', 'arcfour256'):
       
  1231              # arcfour cipher
       
  1232 -            cipher = self._cipher_info[name]['class'].new(key)
       
  1233 +            cipher = Cipher(
       
  1234 +                self._cipher_info[name]['class'](key),
       
  1235 +                None,
       
  1236 +                backend=default_backend()
       
  1237 +            )
       
  1238 +            if operation is self._ENCRYPT:
       
  1239 +                engine = cipher.encryptor()
       
  1240 +            else:
       
  1241 +                engine = cipher.decryptor()
       
  1242              # as per RFC 4345, the first 1536 bytes of keystream
       
  1243              # generated by the cipher MUST be discarded
       
  1244 -            cipher.encrypt(" " * 1536)
       
  1245 -            return cipher
       
  1246 -        elif name.endswith("-ctr"):
       
  1247 -            # CTR modes, we need a counter
       
  1248 -            counter = Counter.new(nbits=self._cipher_info[name]['block-size'] * 8, initial_value=util.inflate_long(iv, True))
       
  1249 -            return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv, counter)
       
  1250 +            engine.encrypt(" " * 1536)
       
  1251 +            return engine
       
  1252          else:
       
  1253 -            return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv)
       
  1254 +            cipher = Cipher(
       
  1255 +                self._cipher_info[name]['class'](key),
       
  1256 +                self._cipher_info[name]['mode'](iv),
       
  1257 +                backend=default_backend(),
       
  1258 +            )
       
  1259 +            if operation is self._ENCRYPT:
       
  1260 +                return cipher.encryptor()
       
  1261 +            else:
       
  1262 +                return cipher.decryptor()
       
  1263  
       
  1264      def _set_forward_agent_handler(self, handler):
       
  1265          if handler is None:
       
  1266 @@ -1879,7 +1933,7 @@ class Transport (threading.Thread, Closi
       
  1267          else:
       
  1268              IV_in = self._compute_key('B', block_size)
       
  1269              key_in = self._compute_key('D', self._cipher_info[self.remote_cipher]['key-size'])
       
  1270 -        engine = self._get_cipher(self.remote_cipher, key_in, IV_in)
       
  1271 +        engine = self._get_cipher(self.remote_cipher, key_in, IV_in, self._DECRYPT)
       
  1272          mac_size = self._mac_info[self.remote_mac]['size']
       
  1273          mac_engine = self._mac_info[self.remote_mac]['class']
       
  1274          # initial mac keys are done in the hash's natural size (not the potentially truncated
       
  1275 @@ -1906,7 +1960,7 @@ class Transport (threading.Thread, Closi
       
  1276          else:
       
  1277              IV_out = self._compute_key('A', block_size)
       
  1278              key_out = self._compute_key('C', self._cipher_info[self.local_cipher]['key-size'])
       
  1279 -        engine = self._get_cipher(self.local_cipher, key_out, IV_out)
       
  1280 +        engine = self._get_cipher(self.local_cipher, key_out, IV_out, self._ENCRYPT)
       
  1281          mac_size = self._mac_info[self.local_mac]['size']
       
  1282          mac_engine = self._mac_info[self.local_mac]['class']
       
  1283          # initial mac keys are done in the hash's natural size (not the potentially truncated
       
  1284 --- paramiko-1.15.2/paramiko/util.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1285 +++ paramiko-1.15.2/paramiko/util.py	2015-04-12 17:36:15.210034924 -0700
       
  1286 @@ -22,7 +22,6 @@ Useful functions used by the rest of par
       
  1287  
       
  1288  from __future__ import generators
       
  1289  
       
  1290 -import array
       
  1291  import errno
       
  1292  import sys
       
  1293  import struct
       
  1294 @@ -31,7 +30,7 @@ import threading
       
  1295  import logging
       
  1296  
       
  1297  from paramiko.common import DEBUG, zero_byte, xffffffff, max_byte
       
  1298 -from paramiko.py3compat import PY2, long, byte_ord, b, byte_chr
       
  1299 +from paramiko.py3compat import PY2, long, byte_chr, byte_ord, b
       
  1300  from paramiko.config import SSHConfig
       
  1301  
       
  1302  
       
  1303 @@ -273,37 +272,6 @@ def retry_on_signal(function):
       
  1304                  raise
       
  1305  
       
  1306  
       
  1307 -class Counter (object):
       
  1308 -    """Stateful counter for CTR mode crypto"""
       
  1309 -    def __init__(self, nbits, initial_value=long(1), overflow=long(0)):
       
  1310 -        self.blocksize = nbits / 8
       
  1311 -        self.overflow = overflow
       
  1312 -        # start with value - 1 so we don't have to store intermediate values when counting
       
  1313 -        # could the iv be 0?
       
  1314 -        if initial_value == 0:
       
  1315 -            self.value = array.array('c', max_byte * self.blocksize)
       
  1316 -        else:
       
  1317 -            x = deflate_long(initial_value - 1, add_sign_padding=False)
       
  1318 -            self.value = array.array('c', zero_byte * (self.blocksize - len(x)) + x)
       
  1319 -
       
  1320 -    def __call__(self):
       
  1321 -        """Increament the counter and return the new value"""
       
  1322 -        i = self.blocksize - 1
       
  1323 -        while i > -1:
       
  1324 -            c = self.value[i] = byte_chr((byte_ord(self.value[i]) + 1) % 256)
       
  1325 -            if c != zero_byte:
       
  1326 -                return self.value.tostring()
       
  1327 -            i -= 1
       
  1328 -        # counter reset
       
  1329 -        x = deflate_long(self.overflow, add_sign_padding=False)
       
  1330 -        self.value = array.array('c', zero_byte * (self.blocksize - len(x)) + x)
       
  1331 -        return self.value.tostring()
       
  1332 -
       
  1333 -    @classmethod
       
  1334 -    def new(cls, nbits, initial_value=long(1), overflow=long(0)):
       
  1335 -        return cls(nbits, initial_value=initial_value, overflow=overflow)
       
  1336 -
       
  1337 -
       
  1338  def constant_time_bytes_eq(a, b):
       
  1339      if len(a) != len(b):
       
  1340          return False
       
  1341 --- paramiko-1.15.2/setup.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1342 +++ paramiko-1.15.2/setup.py	2015-04-12 17:36:15.210254883 -0700
       
  1343 @@ -24,7 +24,7 @@ connections between python scripts.  All
       
  1344  are supported.  SFTP client and server mode are both supported too.
       
  1345  
       
  1346  Required packages:
       
  1347 -    pyCrypto
       
  1348 +    Cryptography
       
  1349  
       
  1350  To install the `in-development version
       
  1351  <https://github.com/paramiko/paramiko/tarball/master#egg=paramiko-dev>`_, use
       
  1352 @@ -41,8 +41,8 @@ try:
       
  1353      from setuptools import setup
       
  1354      kw = {
       
  1355          'install_requires': [
       
  1356 -            'pycrypto >= 2.1, != 2.4',
       
  1357 -            'ecdsa >= 0.11',
       
  1358 +            'cryptography >= 0.8',
       
  1359 +            'pyasn1 >= 0.1.7',
       
  1360          ],
       
  1361      }
       
  1362  except ImportError:
       
  1363 --- paramiko-1.15.2/tests/test_auth.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1364 +++ paramiko-1.15.2/tests/test_auth.py	2015-04-12 17:36:15.210519848 -0700
       
  1365 @@ -83,13 +83,13 @@ class NullServer (ServerInterface):
       
  1366                  return AUTH_SUCCESSFUL
       
  1367              return AUTH_PARTIALLY_SUCCESSFUL
       
  1368          return AUTH_FAILED
       
  1369 -    
       
  1370 +
       
  1371      def check_auth_interactive(self, username, submethods):
       
  1372          if username == 'commie':
       
  1373              self.username = username
       
  1374              return InteractiveQuery('password', 'Please enter a password.', ('Password', False))
       
  1375          return AUTH_FAILED
       
  1376 -    
       
  1377 +
       
  1378      def check_auth_interactive_response(self, responses):
       
  1379          if self.username == 'commie':
       
  1380              if (len(responses) == 1) and (responses[0] == 'cat'):
       
  1381 @@ -111,7 +111,7 @@ class AuthTest (unittest.TestCase):
       
  1382          self.ts.close()
       
  1383          self.socks.close()
       
  1384          self.sockc.close()
       
  1385 -    
       
  1386 +
       
  1387      def start_server(self):
       
  1388          host_key = RSAKey.from_private_key_file(test_path('test_rsa.key'))
       
  1389          self.public_host_key = RSAKey(data=host_key.asbytes())
       
  1390 @@ -120,7 +120,7 @@ class AuthTest (unittest.TestCase):
       
  1391          self.server = NullServer()
       
  1392          self.assertTrue(not self.event.is_set())
       
  1393          self.ts.start_server(self.event, self.server)
       
  1394 -    
       
  1395 +
       
  1396      def verify_finished(self):
       
  1397          self.event.wait(1.0)
       
  1398          self.assertTrue(self.event.is_set())
       
  1399 @@ -156,7 +156,7 @@ class AuthTest (unittest.TestCase):
       
  1400              self.assertTrue(issubclass(etype, AuthenticationException))
       
  1401          self.tc.auth_password(username='slowdive', password='pygmalion')
       
  1402          self.verify_finished()
       
  1403 -    
       
  1404 +
       
  1405      def test_3_multipart_auth(self):
       
  1406          """
       
  1407          verify that multipart auth works.
       
  1408 @@ -187,7 +187,7 @@ class AuthTest (unittest.TestCase):
       
  1409          self.assertEqual(self.got_prompts, [('Password', False)])
       
  1410          self.assertEqual([], remain)
       
  1411          self.verify_finished()
       
  1412 -        
       
  1413 +
       
  1414      def test_5_interactive_auth_fallback(self):
       
  1415          """
       
  1416          verify that a password auth attempt will fallback to "interactive"
       
  1417 --- paramiko-1.15.2/tests/test_client.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1418 +++ paramiko-1.15.2/tests/test_client.py	2015-04-12 17:36:15.210808627 -0700
       
  1419 @@ -22,6 +22,8 @@ Some unit tests for SSHClient.
       
  1420  
       
  1421  from __future__ import with_statement
       
  1422  
       
  1423 +import gc
       
  1424 +import platform
       
  1425  import socket
       
  1426  from tempfile import mkstemp
       
  1427  import threading
       
  1428 @@ -31,8 +33,9 @@ import warnings
       
  1429  import os
       
  1430  import time
       
  1431  from tests.util import test_path
       
  1432 +
       
  1433  import paramiko
       
  1434 -from paramiko.common import PY2, b
       
  1435 +from paramiko.common import PY2
       
  1436  from paramiko.ssh_exception import SSHException
       
  1437  
       
  1438  
       
  1439 @@ -266,14 +269,13 @@ class SSHClientTest (unittest.TestCase):
       
  1440          transport's packetizer) is closed.
       
  1441          """
       
  1442          # Unclear why this is borked on Py3, but it is, and does not seem worth
       
  1443 -        # pursuing at the moment.
       
  1444 +        # pursuing at the moment. Skipped on PyPy because it fails on travis
       
  1445 +        # for unknown reasons, works fine locally.
       
  1446          # XXX: It's the release of the references to e.g packetizer that fails
       
  1447          # in py3...
       
  1448 -        if not PY2:
       
  1449 +        if not PY2 or platform.python_implementation() == "PyPy":
       
  1450              return
       
  1451          threading.Thread(target=self._run).start()
       
  1452 -        host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
       
  1453 -        public_host_key = paramiko.RSAKey(data=host_key.asbytes())
       
  1454  
       
  1455          self.tc = paramiko.SSHClient()
       
  1456          self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
       
  1457 @@ -289,14 +291,10 @@ class SSHClientTest (unittest.TestCase):
       
  1458          self.tc.close()
       
  1459          del self.tc
       
  1460  
       
  1461 -        # hrm, sometimes p isn't cleared right away.  why is that?
       
  1462 -        #st = time.time()
       
  1463 -        #while (time.time() - st < 5.0) and (p() is not None):
       
  1464 -        #    time.sleep(0.1)
       
  1465 -
       
  1466 -        # instead of dumbly waiting for the GC to collect, force a collection
       
  1467 -        # to see whether the SSHClient object is deallocated correctly
       
  1468 -        import gc
       
  1469 +        # force a collection to see whether the SSHClient object is deallocated
       
  1470 +        # correctly. 2 GCs are needed to make sure it's really collected on
       
  1471 +        # PyPy
       
  1472 +        gc.collect()
       
  1473          gc.collect()
       
  1474  
       
  1475          self.assertTrue(p() is None)
       
  1476 @@ -306,8 +304,6 @@ class SSHClientTest (unittest.TestCase):
       
  1477          verify that an SSHClient can be used a context manager
       
  1478          """
       
  1479          threading.Thread(target=self._run).start()
       
  1480 -        host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
       
  1481 -        public_host_key = paramiko.RSAKey(data=host_key.asbytes())
       
  1482  
       
  1483          with paramiko.SSHClient() as tc:
       
  1484              self.tc = tc
       
  1485 --- paramiko-1.15.2/tests/test_packetizer.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1486 +++ paramiko-1.15.2/tests/test_packetizer.py	2015-04-12 17:36:15.211084420 -0700
       
  1487 @@ -23,9 +23,10 @@ Some unit tests for the ssh2 protocol in
       
  1488  import unittest
       
  1489  from hashlib import sha1
       
  1490  
       
  1491 -from tests.loop import LoopSocket
       
  1492 +from cryptography.hazmat.backends import default_backend
       
  1493 +from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes
       
  1494  
       
  1495 -from Crypto.Cipher import AES
       
  1496 +from tests.loop import LoopSocket
       
  1497  
       
  1498  from paramiko import Message, Packetizer, util
       
  1499  from paramiko.common import byte_chr, zero_byte
       
  1500 @@ -43,8 +44,12 @@ class PacketizerTest (unittest.TestCase)
       
  1501          p = Packetizer(wsock)
       
  1502          p.set_log(util.get_logger('paramiko.transport'))
       
  1503          p.set_hexdump(True)
       
  1504 -        cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
       
  1505 -        p.set_outbound_cipher(cipher, 16, sha1, 12, x1f * 20)
       
  1506 +        encryptor = Cipher(
       
  1507 +            algorithms.AES(zero_byte * 16),
       
  1508 +            modes.CBC(x55 * 16),
       
  1509 +            backend=default_backend()
       
  1510 +        ).encryptor()
       
  1511 +        p.set_outbound_cipher(encryptor, 16, sha1, 12, x1f * 20)
       
  1512  
       
  1513          # message has to be at least 16 bytes long, so we'll have at least one
       
  1514          # block of data encrypted that contains zero random padding bytes
       
  1515 @@ -66,8 +71,12 @@ class PacketizerTest (unittest.TestCase)
       
  1516          p = Packetizer(rsock)
       
  1517          p.set_log(util.get_logger('paramiko.transport'))
       
  1518          p.set_hexdump(True)
       
  1519 -        cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
       
  1520 -        p.set_inbound_cipher(cipher, 16, sha1, 12, x1f * 20)
       
  1521 +        decryptor = Cipher(
       
  1522 +            algorithms.AES(zero_byte * 16),
       
  1523 +            modes.CBC(x55 * 16),
       
  1524 +            backend=default_backend()
       
  1525 +        ).decryptor()
       
  1526 +        p.set_inbound_cipher(decryptor, 16, sha1, 12, x1f * 20)
       
  1527          wsock.send(b'\x43\x91\x97\xbd\x5b\x50\xac\x25\x87\xc2\xc4\x6b\xc7\xe9\x38\xc0\x90\xd2\x16\x56\x0d\x71\x73\x61\x38\x7c\x4c\x3d\xfb\x97\x7d\xe2\x6e\x03\xb1\xa0\xc2\x1c\xd6\x41\x41\x4c\xb4\x59')
       
  1528          cmd, m = p.read_message()
       
  1529          self.assertEqual(100, cmd)
       
  1530 @@ -82,8 +91,12 @@ class PacketizerTest (unittest.TestCase)
       
  1531          p = Packetizer(wsock)
       
  1532          p.set_log(util.get_logger('paramiko.transport'))
       
  1533          p.set_hexdump(True)
       
  1534 -        cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
       
  1535 -        p.set_outbound_cipher(cipher, 16, sha1, 12, x1f * 20)
       
  1536 +        encryptor = Cipher(
       
  1537 +            algorithms.AES(zero_byte * 16),
       
  1538 +            modes.CBC(x55 * 16),
       
  1539 +            backend=default_backend()
       
  1540 +        ).encryptor()
       
  1541 +        p.set_outbound_cipher(encryptor, 16, sha1, 12, x1f * 20)
       
  1542  
       
  1543          # message has to be at least 16 bytes long, so we'll have at least one
       
  1544          # block of data encrypted that contains zero random padding bytes
       
  1545 --- paramiko-1.15.2/tests/test_pkey.py.~1~	2014-12-19 15:01:22.000000000 -0800
       
  1546 +++ paramiko-1.15.2/tests/test_pkey.py	2015-04-12 17:36:15.211328345 -0700
       
  1547 @@ -42,34 +42,34 @@ SIGNED_RSA = '20:d7:8a:31:21:cb:f7:92:12
       
  1548  
       
  1549  RSA_PRIVATE_OUT = """\
       
  1550  -----BEGIN RSA PRIVATE KEY-----
       
  1551 -MIICXAIBAAKCAIEA049W6geFpmsljTwfvI1UmKWWJPNFI74+vNKTk4dmzkQY2yAM
       
  1552 -s6FhlvhlI8ysU4oj71ZsRYMecHbBbxdN79+JRFVYTKaLqjwGENeTd+yv4q+V2PvZ
       
  1553 -v3fLnzApI3l7EJCqhWwJUHJ1jAkZzqDx0tyOL4uoZpww3nmE0kb3y21tH4cCASMC
       
  1554 -ggCAEiI6plhqipt4P05L3PYr0pHZq2VPEbE4k9eI/gRKo/c1VJxY3DJnc1cenKsk
       
  1555 -trQRtW3OxCEufqsX5PNec6VyKkW+Ox6beJjMKm4KF8ZDpKi9Nw6MdX3P6Gele9D9
       
  1556 -+ieyhVFljrnAqcXsgChTBOYlL2imqCs3qRGAJ3cMBIAx3VsCQQD3pIFVYW398kE0
       
  1557 -n0e1icEpkbDRV4c5iZVhu8xKy2yyfy6f6lClSb2+Ub9uns7F3+b5v0pYSHbE9+/r
       
  1558 -OpRq83AfAkEA2rMZlr8SnMXgnyka2LuggA9QgMYy18hyao1dUxySubNDa9N+q2QR
       
  1559 -mwDisTUgRFHKIlDHoQmzPbXAmYZX1YlDmQJBAPCRLS5epV0XOAc7pL762OaNhzHC
       
  1560 -veAfQKgVhKBt105PqaKpGyQ5AXcNlWQlPeTK4GBTbMrKDPna6RBkyrEJvV8CQBK+
       
  1561 -5O+p+kfztCrmRCE0p1tvBuZ3Y3GU1ptrM+KNa6mEZN1bRV8l1Z+SXJLYqv6Kquz/
       
  1562 -nBUeFq2Em3rfoSDugiMCQDyG3cxD5dKX3IgkhLyBWls/FLDk4x/DQ+NUTu0F1Cu6
       
  1563 -JJye+5ARLkL0EweMXf0tmIYfWItDLsWB0fKg/56h0js=
       
  1564 +MIICWgIBAAKBgQDTj1bqB4WmayWNPB+8jVSYpZYk80Ujvj680pOTh2bORBjbIAyz
       
  1565 +oWGW+GUjzKxTiiPvVmxFgx5wdsFvF03v34lEVVhMpouqPAYQ15N37K/ir5XY+9m/
       
  1566 +d8ufMCkjeXsQkKqFbAlQcnWMCRnOoPHS3I4vi6hmnDDeeYTSRvfLbW0fhwIBIwKB
       
  1567 +gBIiOqZYaoqbeD9OS9z2K9KR2atlTxGxOJPXiP4ESqP3NVScWNwyZ3NXHpyrJLa0
       
  1568 +EbVtzsQhLn6rF+TzXnOlcipFvjsem3iYzCpuChfGQ6SovTcOjHV9z+hnpXvQ/fon
       
  1569 +soVRZY65wKnF7IAoUwTmJS9opqgrN6kRgCd3DASAMd1bAkEA96SBVWFt/fJBNJ9H
       
  1570 +tYnBKZGw0VeHOYmVYbvMSstssn8un+pQpUm9vlG/bp7Oxd/m+b9KWEh2xPfv6zqU
       
  1571 +avNwHwJBANqzGZa/EpzF4J8pGti7oIAPUIDGMtfIcmqNXVMckrmzQ2vTfqtkEZsA
       
  1572 +4rE1IERRyiJQx6EJsz21wJmGV9WJQ5kCQQDwkS0uXqVdFzgHO6S++tjmjYcxwr3g
       
  1573 +H0CoFYSgbddOT6miqRskOQF3DZVkJT3kyuBgU2zKygz52ukQZMqxCb1fAkASvuTv
       
  1574 +qfpH87Qq5kQhNKdbbwbmd2NxlNabazPijWuphGTdW0VfJdWfklyS2Kr+iqrs/5wV
       
  1575 +HhathJt636Eg7oIjAkA8ht3MQ+XSl9yIJIS8gVpbPxSw5OMfw0PjVE7tBdQruiSc
       
  1576 +nvuQES5C9BMHjF39LZiGH1iLQy7FgdHyoP+eodI7
       
  1577  -----END RSA PRIVATE KEY-----
       
  1578  """
       
  1579  
       
  1580  DSS_PRIVATE_OUT = """\
       
  1581  -----BEGIN DSA PRIVATE KEY-----
       
  1582 -MIIBvgIBAAKCAIEA54GmA2d9HOv+3CYBBG7ZfBYCncIW2tWe6Dqzp+DCP+guNhtW
       
  1583 -2MDLqmX+HQQoJbHat/Uh63I2xPFaueID0jod4OPrlfUXIOSDqDy28Kdo0Hxen9RS
       
  1584 -G7Me4awwiKlHEHHD0sXrTwSplyPUTfK2S2hbkHk5yOuQSjPfEbsL6ukiNi8CFQDw
       
  1585 -z4UnmsGiSNu5iqjn3uTzwUpshwKCAIEAkxfFeY8P2wZpDjX0MimZl5wkoFQDL25c
       
  1586 -PzGBuB4OnB8NoUk/yjAHIIpEShw8V+LzouMK5CTJQo5+Ngw3qIch/WgRmMHy4kBq
       
  1587 -1SsXMjQCte1So6HBMvBPIW5SiMTmjCfZZiw4AYHK+B/JaOwaG9yRg2Ejg4Ok10+X
       
  1588 -FDxlqZo8Y+wCggCARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lY
       
  1589 -ukmnjO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+N
       
  1590 -wacIBlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgECFGI9
       
  1591 -QPSch9pT9XHqn+1rZ4bK+QGA
       
  1592 +MIIBuwIBAAKBgQDngaYDZ30c6/7cJgEEbtl8FgKdwhba1Z7oOrOn4MI/6C42G1bY
       
  1593 +wMuqZf4dBCglsdq39SHrcjbE8Vq54gPSOh3g4+uV9Rcg5IOoPLbwp2jQfF6f1FIb
       
  1594 +sx7hrDCIqUcQccPSxetPBKmXI9RN8rZLaFuQeTnI65BKM98Ruwvq6SI2LwIVAPDP
       
  1595 +hSeawaJI27mKqOfe5PPBSmyHAoGBAJMXxXmPD9sGaQ419DIpmZecJKBUAy9uXD8x
       
  1596 +gbgeDpwfDaFJP8owByCKREocPFfi86LjCuQkyUKOfjYMN6iHIf1oEZjB8uJAatUr
       
  1597 +FzI0ArXtUqOhwTLwTyFuUojE5own2WYsOAGByvgfyWjsGhvckYNhI4ODpNdPlxQ8
       
  1598 +ZamaPGPsAoGARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lYukmn
       
  1599 +jO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+NwacI
       
  1600 +BlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgECFGI9QPSc
       
  1601 +h9pT9XHqn+1rZ4bK+QGA
       
  1602  -----END DSA PRIVATE KEY-----
       
  1603  """
       
  1604  
       
  1605 @@ -121,7 +121,7 @@ class KeyTest (unittest.TestCase):
       
  1606          self.assertEqual(exp_rsa, my_rsa)
       
  1607          self.assertEqual(PUB_RSA.split()[1], key.get_base64())
       
  1608          self.assertEqual(1024, key.get_bits())
       
  1609 -        
       
  1610 +
       
  1611      def test_4_load_dss(self):
       
  1612          key = DSSKey.from_private_key_file(test_path('test_dss.key'))
       
  1613          self.assertEqual('ssh-dss', key.get_name())