1879
|
1 |
diff -ur paramiko-1.7.4.orig/paramiko/transport.py paramiko-1.7.4/paramiko/transport.py
|
|
2 |
--- paramiko-1.7.4.orig/paramiko/transport.py 2008-07-07 02:12:55.000000000 +0100
|
|
3 |
+++ paramiko-1.7.4/paramiko/transport.py 2009-05-15 12:44:50.322005250 +0100
|
|
4 |
@@ -50,8 +50,12 @@
|
|
5 |
# i believe this on the standards track.
|
|
6 |
# PyCrypt compiled for Win32 can be downloaded from the HashTar homepage:
|
|
7 |
# http://nitace.bsd.uchicago.edu:8080/hashtar
|
|
8 |
-from Crypto.Cipher import Blowfish, AES, DES3
|
|
9 |
+from Crypto.Cipher import Blowfish, AES, DES3, ARC4
|
|
10 |
from Crypto.Hash import SHA, MD5
|
|
11 |
+try:
|
|
12 |
+ from Crypto.Util import Counter
|
|
13 |
+except ImportError:
|
|
14 |
+ from paramiko.util import Counter
|
|
15 |
|
|
16 |
|
|
17 |
# for thread cleanup
|
|
18 |
@@ -196,17 +200,22 @@
|
|
19 |
_PROTO_ID = '2.0'
|
|
20 |
_CLIENT_ID = 'paramiko_1.7.4'
|
|
21 |
|
|
22 |
- _preferred_ciphers = ( 'aes128-cbc', 'blowfish-cbc', 'aes256-cbc', '3des-cbc' )
|
|
23 |
+ _preferred_ciphers = ( 'aes128-ctr', 'aes256-ctr', 'aes128-cbc', 'blowfish-cbc', 'aes256-cbc', '3des-cbc',
|
|
24 |
+ 'arcfour128', 'arcfour256' )
|
|
25 |
_preferred_macs = ( 'hmac-sha1', 'hmac-md5', 'hmac-sha1-96', 'hmac-md5-96' )
|
|
26 |
_preferred_keys = ( 'ssh-rsa', 'ssh-dss' )
|
|
27 |
_preferred_kex = ( 'diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1' )
|
|
28 |
_preferred_compression = ( 'none', )
|
|
29 |
|
|
30 |
_cipher_info = {
|
|
31 |
+ 'aes128-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 16 },
|
|
32 |
+ 'aes256-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 32 },
|
|
33 |
'blowfish-cbc': { 'class': Blowfish, 'mode': Blowfish.MODE_CBC, 'block-size': 8, 'key-size': 16 },
|
|
34 |
'aes128-cbc': { 'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 16 },
|
|
35 |
'aes256-cbc': { 'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 32 },
|
|
36 |
'3des-cbc': { 'class': DES3, 'mode': DES3.MODE_CBC, 'block-size': 8, 'key-size': 24 },
|
|
37 |
+ 'arcfour128': { 'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 16 },
|
|
38 |
+ 'arcfour256': { 'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 32 },
|
|
39 |
}
|
|
40 |
|
|
41 |
_mac_info = {
|
|
42 |
@@ -1446,7 +1455,19 @@
|
|
43 |
def _get_cipher(self, name, key, iv):
|
|
44 |
if name not in self._cipher_info:
|
|
45 |
raise SSHException('Unknown client cipher ' + name)
|
|
46 |
- return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv)
|
|
47 |
+ if name in ('arcfour128', 'arcfour256'):
|
|
48 |
+ # arcfour cipher
|
|
49 |
+ cipher = self._cipher_info[name]['class'].new(key)
|
|
50 |
+ # as per RFC 4345, the first 1536 bytes of keystream
|
|
51 |
+ # generated by the cipher MUST be discarded
|
|
52 |
+ cipher.encrypt(" " * 1536)
|
|
53 |
+ return cipher
|
|
54 |
+ elif name.endswith("-ctr"):
|
|
55 |
+ # CTR modes, we need a counter
|
|
56 |
+ return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv,
|
|
57 |
+ Counter.new(nbits=self._cipher_info[name]['block-size']*8, initial_value=util.inflate_long(iv, True)))
|
|
58 |
+ else:
|
|
59 |
+ return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv)
|
|
60 |
|
|
61 |
def _set_x11_handler(self, handler):
|
|
62 |
# only called if a channel has turned on x11 forwarding
|
|
63 |
diff -ur paramiko-1.7.4.orig/paramiko/util.py paramiko-1.7.4/paramiko/util.py
|
|
64 |
--- paramiko-1.7.4.orig/paramiko/util.py 2007-02-13 02:59:59.000000000 +0000
|
|
65 |
+++ paramiko-1.7.4/paramiko/util.py 2009-05-16 17:27:21.266831004 +0100
|
|
66 |
@@ -22,6 +22,7 @@
|
|
67 |
|
|
68 |
from __future__ import generators
|
|
69 |
|
|
70 |
+import array
|
|
71 |
from binascii import hexlify, unhexlify
|
|
72 |
import sys
|
|
73 |
import struct
|
|
74 |
@@ -267,4 +268,33 @@
|
|
75 |
l.addFilter(_pfilter)
|
|
76 |
return l
|
|
77 |
|
|
78 |
+class Counter(object):
|
|
79 |
+ """Stateful counter for CTR mode crypto"""
|
|
80 |
+ def __init__(self, nbits, initial_value, overflow):
|
|
81 |
+ self.blocksize = nbits / 8
|
|
82 |
+ self.overflow = overflow
|
|
83 |
+ # start with value - 1 so we don't have to store intermediate values when counting
|
|
84 |
+ # could the iv be 0?
|
|
85 |
+ if initial_value != 0:
|
|
86 |
+ self.value = deflate_long(initial_value - 1, add_sign_padding=False)
|
|
87 |
+ self.value = '\x00' * (self.blocksize-len(self.value)) + self.value
|
|
88 |
+ else:
|
|
89 |
+ self.value = '\xFF' * self.blocksize
|
|
90 |
+ self.value = array.array('c', self.value)
|
|
91 |
+
|
|
92 |
+ def __call__(self):
|
|
93 |
+ """Increament the counter and return the new value"""
|
|
94 |
+ i = self.blocksize - 1
|
|
95 |
+ while i > -1:
|
|
96 |
+ c = self.value[i] = chr((ord(self.value[i]) + 1) % 256)
|
|
97 |
+ if c != '\x00':
|
|
98 |
+ return self.value.tostring()
|
|
99 |
+ i -= 1
|
|
100 |
+ # counter reset
|
|
101 |
+ self.value = array.array('c', Util.number.long_to_bytes(self.overflow, self.blocksize))
|
|
102 |
+ return self.value.tostring()
|
|
103 |
+
|
|
104 |
+ def new(cls, nbits, initial_value=1L, overflow=0L):
|
|
105 |
+ return cls(nbits, initial_value=initial_value, overflow=overflow)
|
|
106 |
+ new = classmethod(new)
|
|
107 |
|