Switched hash functions from PyCrypto to hashlib.
There's a few advantages to this: 1) It's probably fast, OpenSSL, which typically backs hashlib, receives far more attention for optimizaitons than PyCrypto. 2) It's the first step to supporting PyPy, where PyCrypto doesn't run.
This commit is contained in:
parent
5a430def22
commit
4d3e0b711a
|
@ -20,8 +20,9 @@
|
||||||
DSS keys.
|
DSS keys.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from hashlib import sha1
|
||||||
|
|
||||||
from Crypto.PublicKey import DSA
|
from Crypto.PublicKey import DSA
|
||||||
from Crypto.Hash import SHA
|
|
||||||
|
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
from paramiko.common import zero_byte, rng
|
from paramiko.common import zero_byte, rng
|
||||||
|
@ -96,7 +97,7 @@ class DSSKey (PKey):
|
||||||
return self.x is not None
|
return self.x is not None
|
||||||
|
|
||||||
def sign_ssh_data(self, rng, data):
|
def sign_ssh_data(self, rng, data):
|
||||||
digest = SHA.new(data).digest()
|
digest = sha1(data).digest()
|
||||||
dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q), long(self.x)))
|
dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q), long(self.x)))
|
||||||
# generate a suitable k
|
# generate a suitable k
|
||||||
qsize = len(util.deflate_long(self.q, 0))
|
qsize = len(util.deflate_long(self.q, 0))
|
||||||
|
@ -130,7 +131,7 @@ class DSSKey (PKey):
|
||||||
# pull out (r, s) which are NOT encoded as mpints
|
# pull out (r, s) which are NOT encoded as mpints
|
||||||
sigR = util.inflate_long(sig[:20], 1)
|
sigR = util.inflate_long(sig[:20], 1)
|
||||||
sigS = util.inflate_long(sig[20:], 1)
|
sigS = util.inflate_long(sig[20:], 1)
|
||||||
sigM = util.inflate_long(SHA.new(data).digest(), 1)
|
sigM = util.inflate_long(sha1(data).digest(), 1)
|
||||||
|
|
||||||
dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q)))
|
dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q)))
|
||||||
return dss.verify(sigM, (sigR, sigS))
|
return dss.verify(sigM, (sigR, sigS))
|
||||||
|
|
|
@ -21,11 +21,12 @@ L{ECDSAKey}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
from ecdsa import SigningKey, VerifyingKey, der, curves
|
from hashlib import sha256
|
||||||
from Crypto.Hash import SHA256
|
|
||||||
from ecdsa.test_pyecdsa import ECDSA
|
|
||||||
from paramiko.common import four_byte, one_byte
|
|
||||||
|
|
||||||
|
from ecdsa import SigningKey, VerifyingKey, der, curves
|
||||||
|
from ecdsa.test_pyecdsa import ECDSA
|
||||||
|
|
||||||
|
from paramiko.common import four_byte, one_byte
|
||||||
from paramiko.message import Message
|
from paramiko.message import Message
|
||||||
from paramiko.pkey import PKey
|
from paramiko.pkey import PKey
|
||||||
from paramiko.py3compat import byte_chr, u
|
from paramiko.py3compat import byte_chr, u
|
||||||
|
@ -98,7 +99,7 @@ class ECDSAKey (PKey):
|
||||||
return self.signing_key is not None
|
return self.signing_key is not None
|
||||||
|
|
||||||
def sign_ssh_data(self, rpool, data):
|
def sign_ssh_data(self, rpool, data):
|
||||||
digest = SHA256.new(data).digest()
|
digest = sha256(data).digest()
|
||||||
sig = self.signing_key.sign_digest(digest, entropy=rpool.read,
|
sig = self.signing_key.sign_digest(digest, entropy=rpool.read,
|
||||||
sigencode=self._sigencode)
|
sigencode=self._sigencode)
|
||||||
m = Message()
|
m = Message()
|
||||||
|
@ -113,7 +114,7 @@ class ECDSAKey (PKey):
|
||||||
|
|
||||||
# verify the signature by SHA'ing the data and encrypting it
|
# verify the signature by SHA'ing the data and encrypting it
|
||||||
# using the public key.
|
# using the public key.
|
||||||
hash_obj = SHA256.new(data).digest()
|
hash_obj = sha256(data).digest()
|
||||||
return self.verifying_key.verify_digest(sig, hash_obj,
|
return self.verifying_key.verify_digest(sig, hash_obj,
|
||||||
sigdecode=self._sigdecode)
|
sigdecode=self._sigdecode)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
|
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
from Crypto.Hash import SHA, HMAC
|
from hashlib import sha1
|
||||||
|
from hmac import HMAC
|
||||||
|
|
||||||
from paramiko.common import rng
|
from paramiko.common import rng
|
||||||
from paramiko.py3compat import b, u, encodebytes, decodebytes
|
from paramiko.py3compat import b, u, encodebytes, decodebytes
|
||||||
|
|
||||||
|
@ -262,13 +264,13 @@ class HostKeys (MutableMapping):
|
||||||
:return: the hashed hostname as a `str`
|
:return: the hashed hostname as a `str`
|
||||||
"""
|
"""
|
||||||
if salt is None:
|
if salt is None:
|
||||||
salt = rng.read(SHA.digest_size)
|
salt = rng.read(sha1().digest_size)
|
||||||
else:
|
else:
|
||||||
if salt.startswith('|1|'):
|
if salt.startswith('|1|'):
|
||||||
salt = salt.split('|')[2]
|
salt = salt.split('|')[2]
|
||||||
salt = decodebytes(b(salt))
|
salt = decodebytes(b(salt))
|
||||||
assert len(salt) == SHA.digest_size
|
assert len(salt) == sha1().digest_size
|
||||||
hmac = HMAC.HMAC(salt, b(hostname), SHA).digest()
|
hmac = HMAC(salt, b(hostname), sha1).digest()
|
||||||
hostkey = '|1|%s|%s' % (u(encodebytes(salt)), u(encodebytes(hmac)))
|
hostkey = '|1|%s|%s' % (u(encodebytes(salt)), u(encodebytes(hmac)))
|
||||||
return hostkey.replace('\n', '')
|
return hostkey.replace('\n', '')
|
||||||
hash_host = staticmethod(hash_host)
|
hash_host = staticmethod(hash_host)
|
||||||
|
|
|
@ -22,7 +22,7 @@ generator "g" are provided by the server. A bit more work is required on the
|
||||||
client side, and a B{lot} more on the server side.
|
client side, and a B{lot} more on the server side.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from Crypto.Hash import SHA
|
from hashlib import sha1
|
||||||
|
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
from paramiko.common import DEBUG
|
from paramiko.common import DEBUG
|
||||||
|
@ -203,7 +203,7 @@ class KexGex (object):
|
||||||
hm.add_mpint(self.e)
|
hm.add_mpint(self.e)
|
||||||
hm.add_mpint(self.f)
|
hm.add_mpint(self.f)
|
||||||
hm.add_mpint(K)
|
hm.add_mpint(K)
|
||||||
H = SHA.new(hm.asbytes()).digest()
|
H = sha1(hm.asbytes()).digest()
|
||||||
self.transport._set_K_H(K, H)
|
self.transport._set_K_H(K, H)
|
||||||
# sign it
|
# sign it
|
||||||
sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H)
|
sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H)
|
||||||
|
@ -238,6 +238,6 @@ class KexGex (object):
|
||||||
hm.add_mpint(self.e)
|
hm.add_mpint(self.e)
|
||||||
hm.add_mpint(self.f)
|
hm.add_mpint(self.f)
|
||||||
hm.add_mpint(K)
|
hm.add_mpint(K)
|
||||||
self.transport._set_K_H(K, SHA.new(hm.asbytes()).digest())
|
self.transport._set_K_H(K, sha1(hm.asbytes()).digest())
|
||||||
self.transport._verify_key(host_key, sig)
|
self.transport._verify_key(host_key, sig)
|
||||||
self.transport._activate_outbound()
|
self.transport._activate_outbound()
|
||||||
|
|
|
@ -21,7 +21,7 @@ Standard SSH key exchange ("kex" if you wanna sound cool). Diffie-Hellman of
|
||||||
1024 bit key halves, using a known "p" prime and "g" generator.
|
1024 bit key halves, using a known "p" prime and "g" generator.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from Crypto.Hash import SHA
|
from hashlib import sha1
|
||||||
|
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
from paramiko.common import max_byte, zero_byte
|
from paramiko.common import max_byte, zero_byte
|
||||||
|
@ -105,7 +105,7 @@ class KexGroup1(object):
|
||||||
hm.add_mpint(self.e)
|
hm.add_mpint(self.e)
|
||||||
hm.add_mpint(self.f)
|
hm.add_mpint(self.f)
|
||||||
hm.add_mpint(K)
|
hm.add_mpint(K)
|
||||||
self.transport._set_K_H(K, SHA.new(hm.asbytes()).digest())
|
self.transport._set_K_H(K, sha1(hm.asbytes()).digest())
|
||||||
self.transport._verify_key(host_key, sig)
|
self.transport._verify_key(host_key, sig)
|
||||||
self.transport._activate_outbound()
|
self.transport._activate_outbound()
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ class KexGroup1(object):
|
||||||
hm.add_mpint(self.e)
|
hm.add_mpint(self.e)
|
||||||
hm.add_mpint(self.f)
|
hm.add_mpint(self.f)
|
||||||
hm.add_mpint(K)
|
hm.add_mpint(K)
|
||||||
H = SHA.new(hm.asbytes()).digest()
|
H = sha1(hm.asbytes()).digest()
|
||||||
self.transport._set_K_H(K, H)
|
self.transport._set_K_H(K, H)
|
||||||
# sign it
|
# sign it
|
||||||
sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H)
|
sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import socket
|
||||||
import struct
|
import struct
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from hmac import HMAC
|
||||||
|
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
from paramiko.common import linefeed_byte, cr_byte_value, asbytes, MSG_NAMES, \
|
from paramiko.common import linefeed_byte, cr_byte_value, asbytes, MSG_NAMES, \
|
||||||
|
@ -34,12 +35,6 @@ from paramiko.ssh_exception import SSHException, ProxyCommandFailure
|
||||||
from paramiko.message import Message
|
from paramiko.message import Message
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
from r_hmac import HMAC
|
|
||||||
except ImportError:
|
|
||||||
from Crypto.Hash.HMAC import HMAC
|
|
||||||
|
|
||||||
|
|
||||||
def compute_hmac(key, message, digest_class):
|
def compute_hmac(key, message, digest_class):
|
||||||
return HMAC(key, message, digest_class).digest()
|
return HMAC(key, message, digest_class).digest()
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ Common API for all public keys.
|
||||||
import base64
|
import base64
|
||||||
from binascii import hexlify, unhexlify
|
from binascii import hexlify, unhexlify
|
||||||
import os
|
import os
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
from Crypto.Hash import MD5
|
|
||||||
from Crypto.Cipher import DES3, AES
|
from Crypto.Cipher import DES3, AES
|
||||||
|
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
|
@ -126,7 +126,7 @@ class PKey (object):
|
||||||
a 16-byte `string <str>` (binary) of the MD5 fingerprint, in SSH
|
a 16-byte `string <str>` (binary) of the MD5 fingerprint, in SSH
|
||||||
format.
|
format.
|
||||||
"""
|
"""
|
||||||
return MD5.new(self.asbytes()).digest()
|
return md5(self.asbytes()).digest()
|
||||||
|
|
||||||
def get_base64(self):
|
def get_base64(self):
|
||||||
"""
|
"""
|
||||||
|
@ -300,7 +300,7 @@ class PKey (object):
|
||||||
keysize = self._CIPHER_TABLE[encryption_type]['keysize']
|
keysize = self._CIPHER_TABLE[encryption_type]['keysize']
|
||||||
mode = self._CIPHER_TABLE[encryption_type]['mode']
|
mode = self._CIPHER_TABLE[encryption_type]['mode']
|
||||||
salt = unhexlify(b(saltstr))
|
salt = unhexlify(b(saltstr))
|
||||||
key = util.generate_key_bytes(MD5, salt, password, keysize)
|
key = util.generate_key_bytes(md5, salt, password, keysize)
|
||||||
return cipher.new(key, mode, salt).decrypt(data)
|
return cipher.new(key, mode, salt).decrypt(data)
|
||||||
|
|
||||||
def _write_private_key_file(self, tag, filename, data, password=None):
|
def _write_private_key_file(self, tag, filename, data, password=None):
|
||||||
|
@ -332,7 +332,7 @@ class PKey (object):
|
||||||
blocksize = self._CIPHER_TABLE[cipher_name]['blocksize']
|
blocksize = self._CIPHER_TABLE[cipher_name]['blocksize']
|
||||||
mode = self._CIPHER_TABLE[cipher_name]['mode']
|
mode = self._CIPHER_TABLE[cipher_name]['mode']
|
||||||
salt = rng.read(16)
|
salt = rng.read(16)
|
||||||
key = util.generate_key_bytes(MD5, salt, password, keysize)
|
key = util.generate_key_bytes(md5, salt, password, keysize)
|
||||||
if len(data) % blocksize != 0:
|
if len(data) % blocksize != 0:
|
||||||
n = blocksize - len(data) % blocksize
|
n = blocksize - len(data) % blocksize
|
||||||
#data += rng.read(n)
|
#data += rng.read(n)
|
||||||
|
|
|
@ -20,8 +20,9 @@
|
||||||
RSA keys.
|
RSA keys.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from hashlib import sha1
|
||||||
|
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
from Crypto.Hash import SHA
|
|
||||||
|
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
from paramiko.common import rng, max_byte, zero_byte, one_byte
|
from paramiko.common import rng, max_byte, zero_byte, one_byte
|
||||||
|
@ -91,7 +92,7 @@ class RSAKey (PKey):
|
||||||
return self.d is not None
|
return self.d is not None
|
||||||
|
|
||||||
def sign_ssh_data(self, rpool, data):
|
def sign_ssh_data(self, rpool, data):
|
||||||
digest = SHA.new(data).digest()
|
digest = sha1(data).digest()
|
||||||
rsa = RSA.construct((long(self.n), long(self.e), long(self.d)))
|
rsa = RSA.construct((long(self.n), long(self.e), long(self.d)))
|
||||||
sig = util.deflate_long(rsa.sign(self._pkcs1imify(digest), bytes())[0], 0)
|
sig = util.deflate_long(rsa.sign(self._pkcs1imify(digest), bytes())[0], 0)
|
||||||
m = Message()
|
m = Message()
|
||||||
|
@ -106,7 +107,7 @@ class RSAKey (PKey):
|
||||||
# verify the signature by SHA'ing the data and encrypting it using the
|
# verify the signature by SHA'ing the data and encrypting it using the
|
||||||
# public key. some wackiness ensues where we "pkcs1imify" the 20-byte
|
# public key. some wackiness ensues where we "pkcs1imify" the 20-byte
|
||||||
# hash into a string as long as the RSA key.
|
# hash into a string as long as the RSA key.
|
||||||
hash_obj = util.inflate_long(self._pkcs1imify(SHA.new(data).digest()), True)
|
hash_obj = util.inflate_long(self._pkcs1imify(sha1(data).digest()), True)
|
||||||
rsa = RSA.construct((long(self.n), long(self.e)))
|
rsa = RSA.construct((long(self.n), long(self.e)))
|
||||||
return rsa.verify(hash_obj, (sig,))
|
return rsa.verify(hash_obj, (sig,))
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,9 @@ Server-mode SFTP support.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import errno
|
import errno
|
||||||
|
|
||||||
from Crypto.Hash import MD5, SHA
|
|
||||||
import sys
|
import sys
|
||||||
|
from hashlib import md5, sha1
|
||||||
|
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
from paramiko.sftp import BaseSFTP, Message, SFTP_FAILURE, \
|
from paramiko.sftp import BaseSFTP, Message, SFTP_FAILURE, \
|
||||||
SFTP_PERMISSION_DENIED, SFTP_NO_SUCH_FILE
|
SFTP_PERMISSION_DENIED, SFTP_NO_SUCH_FILE
|
||||||
|
@ -45,8 +45,8 @@ from paramiko.sftp import CMD_HANDLE, SFTP_DESC, CMD_STATUS, SFTP_EOF, CMD_NAME,
|
||||||
CMD_READLINK, CMD_SYMLINK, CMD_REALPATH, CMD_EXTENDED, SFTP_OP_UNSUPPORTED
|
CMD_READLINK, CMD_SYMLINK, CMD_REALPATH, CMD_EXTENDED, SFTP_OP_UNSUPPORTED
|
||||||
|
|
||||||
_hash_class = {
|
_hash_class = {
|
||||||
'sha1': SHA,
|
'sha1': sha1,
|
||||||
'md5': MD5,
|
'md5': md5,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
||||||
# don't try to read more than about 64KB at a time
|
# don't try to read more than about 64KB at a time
|
||||||
chunklen = min(blocklen, 65536)
|
chunklen = min(blocklen, 65536)
|
||||||
count = 0
|
count = 0
|
||||||
hash_obj = alg.new()
|
hash_obj = alg()
|
||||||
while count < blocklen:
|
while count < blocklen:
|
||||||
data = f.read(offset, chunklen)
|
data = f.read(offset, chunklen)
|
||||||
if not isinstance(data, bytes_types):
|
if not isinstance(data, bytes_types):
|
||||||
|
|
|
@ -25,6 +25,7 @@ import sys
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import weakref
|
import weakref
|
||||||
|
from hashlib import md5, sha1
|
||||||
|
|
||||||
import paramiko
|
import paramiko
|
||||||
from paramiko import util
|
from paramiko import util
|
||||||
|
@ -59,7 +60,6 @@ from paramiko.util import retry_on_signal
|
||||||
|
|
||||||
from Crypto import Random
|
from Crypto import Random
|
||||||
from Crypto.Cipher import Blowfish, AES, DES3, ARC4
|
from Crypto.Cipher import Blowfish, AES, DES3, ARC4
|
||||||
from Crypto.Hash import SHA, MD5
|
|
||||||
try:
|
try:
|
||||||
from Crypto.Util import Counter
|
from Crypto.Util import Counter
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -107,10 +107,10 @@ class Transport (threading.Thread):
|
||||||
}
|
}
|
||||||
|
|
||||||
_mac_info = {
|
_mac_info = {
|
||||||
'hmac-sha1': {'class': SHA, 'size': 20},
|
'hmac-sha1': {'class': sha1, 'size': 20},
|
||||||
'hmac-sha1-96': {'class': SHA, 'size': 12},
|
'hmac-sha1-96': {'class': sha1, 'size': 12},
|
||||||
'hmac-md5': {'class': MD5, 'size': 16},
|
'hmac-md5': {'class': md5, 'size': 16},
|
||||||
'hmac-md5-96': {'class': MD5, 'size': 12},
|
'hmac-md5-96': {'class': md5, 'size': 12},
|
||||||
}
|
}
|
||||||
|
|
||||||
_key_info = {
|
_key_info = {
|
||||||
|
@ -1338,13 +1338,13 @@ class Transport (threading.Thread):
|
||||||
m.add_bytes(self.H)
|
m.add_bytes(self.H)
|
||||||
m.add_byte(b(id))
|
m.add_byte(b(id))
|
||||||
m.add_bytes(self.session_id)
|
m.add_bytes(self.session_id)
|
||||||
out = sofar = SHA.new(m.asbytes()).digest()
|
out = sofar = sha1(m.asbytes()).digest()
|
||||||
while len(out) < nbytes:
|
while len(out) < nbytes:
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_mpint(self.K)
|
m.add_mpint(self.K)
|
||||||
m.add_bytes(self.H)
|
m.add_bytes(self.H)
|
||||||
m.add_bytes(sofar)
|
m.add_bytes(sofar)
|
||||||
digest = SHA.new(m.asbytes()).digest()
|
digest = sha1(m.asbytes()).digest()
|
||||||
out += digest
|
out += digest
|
||||||
sofar += digest
|
sofar += digest
|
||||||
return out[:nbytes]
|
return out[:nbytes]
|
||||||
|
@ -1719,9 +1719,9 @@ class Transport (threading.Thread):
|
||||||
# initial mac keys are done in the hash's natural size (not the potentially truncated
|
# initial mac keys are done in the hash's natural size (not the potentially truncated
|
||||||
# transmission size)
|
# transmission size)
|
||||||
if self.server_mode:
|
if self.server_mode:
|
||||||
mac_key = self._compute_key('E', mac_engine.digest_size)
|
mac_key = self._compute_key('E', mac_engine().digest_size)
|
||||||
else:
|
else:
|
||||||
mac_key = self._compute_key('F', mac_engine.digest_size)
|
mac_key = self._compute_key('F', mac_engine().digest_size)
|
||||||
self.packetizer.set_inbound_cipher(engine, block_size, mac_engine, mac_size, mac_key)
|
self.packetizer.set_inbound_cipher(engine, block_size, mac_engine, mac_size, mac_key)
|
||||||
compress_in = self._compression_info[self.remote_compression][1]
|
compress_in = self._compression_info[self.remote_compression][1]
|
||||||
if (compress_in is not None) and ((self.remote_compression != 'zlib@openssh.com') or self.authenticated):
|
if (compress_in is not None) and ((self.remote_compression != 'zlib@openssh.com') or self.authenticated):
|
||||||
|
@ -1746,9 +1746,9 @@ class Transport (threading.Thread):
|
||||||
# initial mac keys are done in the hash's natural size (not the potentially truncated
|
# initial mac keys are done in the hash's natural size (not the potentially truncated
|
||||||
# transmission size)
|
# transmission size)
|
||||||
if self.server_mode:
|
if self.server_mode:
|
||||||
mac_key = self._compute_key('F', mac_engine.digest_size)
|
mac_key = self._compute_key('F', mac_engine().digest_size)
|
||||||
else:
|
else:
|
||||||
mac_key = self._compute_key('E', mac_engine.digest_size)
|
mac_key = self._compute_key('E', mac_engine().digest_size)
|
||||||
sdctr = self.local_cipher.endswith('-ctr')
|
sdctr = self.local_cipher.endswith('-ctr')
|
||||||
self.packetizer.set_outbound_cipher(engine, block_size, mac_engine, mac_size, mac_key, sdctr)
|
self.packetizer.set_outbound_cipher(engine, block_size, mac_engine, mac_size, mac_key, sdctr)
|
||||||
compress_out = self._compression_info[self.local_compression][0]
|
compress_out = self._compression_info[self.local_compression][0]
|
||||||
|
|
|
@ -143,15 +143,14 @@ def tb_strings():
|
||||||
return ''.join(traceback.format_exception(*sys.exc_info())).split('\n')
|
return ''.join(traceback.format_exception(*sys.exc_info())).split('\n')
|
||||||
|
|
||||||
|
|
||||||
def generate_key_bytes(hashclass, salt, key, nbytes):
|
def generate_key_bytes(hash_alg, salt, key, nbytes):
|
||||||
"""
|
"""
|
||||||
Given a password, passphrase, or other human-source key, scramble it
|
Given a password, passphrase, or other human-source key, scramble it
|
||||||
through a secure hash into some keyworthy bytes. This specific algorithm
|
through a secure hash into some keyworthy bytes. This specific algorithm
|
||||||
is used for encrypting/decrypting private key files.
|
is used for encrypting/decrypting private key files.
|
||||||
|
|
||||||
:param class hashclass:
|
:param function hash_alg: A function which creates a new hash object, such
|
||||||
class from `Crypto.Hash` that can be used as a secure hashing function
|
as ``hashlib.sha256``.
|
||||||
(like ``MD5`` or ``SHA``).
|
|
||||||
:param salt: data to salt the hash with.
|
:param salt: data to salt the hash with.
|
||||||
:type salt: byte string
|
:type salt: byte string
|
||||||
:param str key: human-entered password or passphrase.
|
:param str key: human-entered password or passphrase.
|
||||||
|
@ -163,7 +162,7 @@ def generate_key_bytes(hashclass, salt, key, nbytes):
|
||||||
if len(salt) > 8:
|
if len(salt) > 8:
|
||||||
salt = salt[:8]
|
salt = salt[:8]
|
||||||
while nbytes > 0:
|
while nbytes > 0:
|
||||||
hash_obj = hashclass.new()
|
hash_obj = hash_alg()
|
||||||
if len(digest) > 0:
|
if len(digest) > 0:
|
||||||
hash_obj.update(digest)
|
hash_obj.update(digest)
|
||||||
hash_obj.update(b(key))
|
hash_obj.update(b(key))
|
||||||
|
|
|
@ -21,9 +21,12 @@ Some unit tests for the ssh2 protocol in Transport.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
from hashlib import sha1
|
||||||
|
|
||||||
from tests.loop import LoopSocket
|
from tests.loop import LoopSocket
|
||||||
|
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto.Hash import SHA
|
|
||||||
from paramiko import Message, Packetizer, util
|
from paramiko import Message, Packetizer, util
|
||||||
from paramiko.common import byte_chr, zero_byte
|
from paramiko.common import byte_chr, zero_byte
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ class PacketizerTest (unittest.TestCase):
|
||||||
p.set_log(util.get_logger('paramiko.transport'))
|
p.set_log(util.get_logger('paramiko.transport'))
|
||||||
p.set_hexdump(True)
|
p.set_hexdump(True)
|
||||||
cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
|
cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
|
||||||
p.set_outbound_cipher(cipher, 16, SHA, 12, x1f * 20)
|
p.set_outbound_cipher(cipher, 16, sha1, 12, x1f * 20)
|
||||||
|
|
||||||
# message has to be at least 16 bytes long, so we'll have at least one
|
# message has to be at least 16 bytes long, so we'll have at least one
|
||||||
# block of data encrypted that contains zero random padding bytes
|
# block of data encrypted that contains zero random padding bytes
|
||||||
|
@ -64,7 +67,7 @@ class PacketizerTest (unittest.TestCase):
|
||||||
p.set_log(util.get_logger('paramiko.transport'))
|
p.set_log(util.get_logger('paramiko.transport'))
|
||||||
p.set_hexdump(True)
|
p.set_hexdump(True)
|
||||||
cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
|
cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
|
||||||
p.set_inbound_cipher(cipher, 16, SHA, 12, x1f * 20)
|
p.set_inbound_cipher(cipher, 16, sha1, 12, x1f * 20)
|
||||||
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')
|
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')
|
||||||
cmd, m = p.read_message()
|
cmd, m = p.read_message()
|
||||||
self.assertEqual(100, cmd)
|
self.assertEqual(100, cmd)
|
||||||
|
|
|
@ -20,11 +20,14 @@
|
||||||
Some unit tests for public/private key objects.
|
Some unit tests for public/private key objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from binascii import hexlify
|
|
||||||
import unittest
|
import unittest
|
||||||
|
from binascii import hexlify
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
from paramiko import RSAKey, DSSKey, ECDSAKey, Message, util
|
from paramiko import RSAKey, DSSKey, ECDSAKey, Message, util
|
||||||
from paramiko.py3compat import StringIO, byte_chr, b, bytes
|
from paramiko.py3compat import StringIO, byte_chr, b, bytes
|
||||||
from paramiko.common import rng
|
from paramiko.common import rng
|
||||||
|
|
||||||
from tests.util import test_path
|
from tests.util import test_path
|
||||||
|
|
||||||
# from openssh's ssh-keygen
|
# from openssh's ssh-keygen
|
||||||
|
@ -90,8 +93,7 @@ class KeyTest (unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_1_generate_key_bytes(self):
|
def test_1_generate_key_bytes(self):
|
||||||
from Crypto.Hash import MD5
|
key = util.generate_key_bytes(md5, x1234, 'happy birthday', 30)
|
||||||
key = util.generate_key_bytes(MD5, x1234, 'happy birthday', 30)
|
|
||||||
exp = b'\x61\xE1\xF2\x72\xF4\xC1\xC4\x56\x15\x86\xBD\x32\x24\x98\xC0\xE9\x24\x67\x27\x80\xF4\x7B\xB3\x7D\xDA\x7D\x54\x01\x9E\x64'
|
exp = b'\x61\xE1\xF2\x72\xF4\xC1\xC4\x56\x15\x86\xBD\x32\x24\x98\xC0\xE9\x24\x67\x27\x80\xF4\x7B\xB3\x7D\xDA\x7D\x54\x01\x9E\x64'
|
||||||
self.assertEqual(exp, key)
|
self.assertEqual(exp, key)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ Some unit tests for utility functions.
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
from Crypto.Hash import SHA
|
from hashlib import sha1
|
||||||
|
|
||||||
import paramiko.util
|
import paramiko.util
|
||||||
from paramiko.util import lookup_ssh_host_config as host_config
|
from paramiko.util import lookup_ssh_host_config as host_config
|
||||||
from paramiko.py3compat import StringIO, byte_ord
|
from paramiko.py3compat import StringIO, byte_ord
|
||||||
|
@ -136,7 +137,7 @@ class UtilTest(ParamikoTest):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_4_generate_key_bytes(self):
|
def test_4_generate_key_bytes(self):
|
||||||
x = paramiko.util.generate_key_bytes(SHA, b'ABCDEFGH', 'This is my secret passphrase.', 64)
|
x = paramiko.util.generate_key_bytes(sha1, b'ABCDEFGH', 'This is my secret passphrase.', 64)
|
||||||
hex = ''.join(['%02x' % byte_ord(c) for c in x])
|
hex = ''.join(['%02x' % byte_ord(c) for c in x])
|
||||||
self.assertEqual(hex, '9110e2f6793b69363e58173e9436b13a5a4b339005741d5c680e505f57d871347b4239f14fb5c46e857d5e100424873ba849ac699cea98d729e57b3e84378e8b')
|
self.assertEqual(hex, '9110e2f6793b69363e58173e9436b13a5a4b339005741d5c680e505f57d871347b4239f14fb5c46e857d5e100424873ba849ac699cea98d729e57b3e84378e8b')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue