summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthias Witte <m.witte@telekom.de>2014-07-15 12:22:11 +0200
committerMatthias Witte <m.witte@telekom.de>2014-07-15 12:22:11 +0200
commitbd21af3405a3591dcc0533993d587aa2e4db0c4f (patch)
treeeab33ffdf0b59dee0d761b83f23ab5be3ed9f1f7
parente811e715833373dd2f2ba898089695eee9c882ed (diff)
Add support for sha256 based hmac and kexgex
-rw-r--r--paramiko/kex_gex.py13
-rw-r--r--paramiko/transport.py26
2 files changed, 26 insertions, 13 deletions
diff --git a/paramiko/kex_gex.py b/paramiko/kex_gex.py
index 5ff8a287..1eadba03 100644
--- a/paramiko/kex_gex.py
+++ b/paramiko/kex_gex.py
@@ -23,7 +23,7 @@ client side, and a B{lot} more on the server side.
"""
import os
-from hashlib import sha1
+from hashlib import sha1, sha256
from paramiko import util
from paramiko.common import DEBUG
@@ -44,6 +44,7 @@ class KexGex (object):
min_bits = 1024
max_bits = 8192
preferred_bits = 2048
+ hash_algo = sha1
def __init__(self, transport):
self.transport = transport
@@ -87,7 +88,7 @@ class KexGex (object):
return self._parse_kexdh_gex_reply(m)
elif ptype == _MSG_KEXDH_GEX_REQUEST_OLD:
return self._parse_kexdh_gex_request_old(m)
- raise SSHException('KexGex asked to handle packet type %d' % ptype)
+ raise SSHException('KexGex %s asked to handle packet type %d' % self.name, ptype)
### internals...
@@ -204,7 +205,7 @@ class KexGex (object):
hm.add_mpint(self.e)
hm.add_mpint(self.f)
hm.add_mpint(K)
- H = sha1(hm.asbytes()).digest()
+ H = self.hash_algo(hm.asbytes()).digest()
self.transport._set_K_H(K, H)
# sign it
sig = self.transport.get_server_key().sign_ssh_data(H)
@@ -239,6 +240,10 @@ class KexGex (object):
hm.add_mpint(self.e)
hm.add_mpint(self.f)
hm.add_mpint(K)
- self.transport._set_K_H(K, sha1(hm.asbytes()).digest())
+ self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
self.transport._verify_key(host_key, sig)
self.transport._activate_outbound()
+
+class KexGexSHA256(KexGex):
+ name = 'diffie-hellman-group-exchange-sha256'
+ hash_algo = sha256
diff --git a/paramiko/transport.py b/paramiko/transport.py
index 406626a7..48ab1729 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -26,7 +26,7 @@ import sys
import threading
import time
import weakref
-from hashlib import md5, sha1
+from hashlib import md5, sha1, sha256
import paramiko
from paramiko import util
@@ -45,7 +45,7 @@ from paramiko.common import xffffffff, cMSG_CHANNEL_OPEN, cMSG_IGNORE, \
MSG_CHANNEL_EOF, MSG_CHANNEL_CLOSE
from paramiko.compress import ZlibCompressor, ZlibDecompressor
from paramiko.dsskey import DSSKey
-from paramiko.kex_gex import KexGex
+from paramiko.kex_gex import KexGex, KexGexSHA256
from paramiko.kex_group1 import KexGroup1
from paramiko.message import Message
from paramiko.packet import Packetizer, NeedRekeyException
@@ -90,9 +90,12 @@ class Transport (threading.Thread):
_preferred_ciphers = ('aes128-ctr', 'aes256-ctr', 'aes128-cbc', 'blowfish-cbc',
'aes256-cbc', '3des-cbc', 'arcfour128', 'arcfour256')
- _preferred_macs = ('hmac-sha1', 'hmac-md5', 'hmac-sha1-96', 'hmac-md5-96')
+ _preferred_macs = ('hmac-sha1', 'hmac-md5', 'hmac-sha1-96', 'hmac-md5-96',
+ 'hmac-sha2-256')
_preferred_keys = ('ssh-rsa', 'ssh-dss', 'ecdsa-sha2-nistp256')
- _preferred_kex = ('diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1')
+ _preferred_kex = ('diffie-hellman-group1-sha1',
+ 'diffie-hellman-group-exchange-sha1',
+ 'diffie-hellman-group-exchange-sha256')
_preferred_compression = ('none',)
_cipher_info = {
@@ -109,6 +112,7 @@ class Transport (threading.Thread):
_mac_info = {
'hmac-sha1': {'class': sha1, 'size': 20},
'hmac-sha1-96': {'class': sha1, 'size': 12},
+ 'hmac-sha2-256': {'class': sha256, 'size': 32},
'hmac-md5': {'class': md5, 'size': 16},
'hmac-md5-96': {'class': md5, 'size': 12},
}
@@ -122,6 +126,7 @@ class Transport (threading.Thread):
_kex_info = {
'diffie-hellman-group1-sha1': KexGroup1,
'diffie-hellman-group-exchange-sha1': KexGex,
+ 'diffie-hellman-group-exchange-sha256': KexGexSHA256,
}
_compression_info = {
@@ -1336,13 +1341,14 @@ class Transport (threading.Thread):
m.add_bytes(self.H)
m.add_byte(b(id))
m.add_bytes(self.session_id)
- out = sofar = sha1(m.asbytes()).digest()
+ hash_algo = self._mac_info[self.local_mac]['class']
+ out = sofar = hash_algo(m.asbytes()).digest()
while len(out) < nbytes:
m = Message()
m.add_mpint(self.K)
m.add_bytes(self.H)
m.add_bytes(sofar)
- digest = sha1(m.asbytes()).digest()
+ digest = hash_algo(m.asbytes()).digest()
out += digest
sofar += digest
return out[:nbytes]
@@ -1572,10 +1578,12 @@ class Transport (threading.Thread):
self.clear_to_send_lock.release()
self.in_kex = True
if self.server_mode:
- if (self._modulus_pack is None) and ('diffie-hellman-group-exchange-sha1' in self._preferred_kex):
+ mp_required_prefix = 'diffie-hellman-group-exchange-sha'
+ kex_mp = [k for k in self._preferred_kex if k.startswith(mp_required_prefix)]
+ if (self._modulus_pack is None) and (len(kex_mp) > 0):
# can't do group-exchange if we don't have a pack of potential primes
- pkex = list(self.get_security_options().kex)
- pkex.remove('diffie-hellman-group-exchange-sha1')
+ pkex = [k for k in self.get_security_options().kex
+ if not k.startswith(mp_required_prefix)]
self.get_security_options().kex = pkex
available_server_keys = list(filter(list(self.server_key_dict.keys()).__contains__,
self._preferred_keys))