diff --git a/compat.c b/compat.c index 2709dc5..7412a54 100644 --- a/compat.c +++ b/compat.c @@ -167,6 +167,7 @@ compat_datafellows(const char *version) SSH_BUG_SCANNER }, { "Probe-*", SSH_BUG_PROBE }, + { "Cisco-*", SSH_BUG_MAX4096DH }, { NULL, 0 } }; diff --git a/compat.h b/compat.h index a6c3f3d..d8def7d 100644 --- a/compat.h +++ b/compat.h @@ -60,6 +60,7 @@ #define SSH_NEW_OPENSSH 0x04000000 #define SSH_BUG_DYNAMIC_RPORT 0x08000000 #define SSH_BUG_CURVE25519PAD 0x10000000 +#define SSH_BUG_MAX4096DH 0x20000000 void enable_compat13(void); void enable_compat20(void); diff --git a/kexgexc.c b/kexgexc.c index 355b7ba..0a91bdd 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -58,20 +58,37 @@ kexgex_client(Kex *kex) int min, max, nbits; DH *dh; + min = DH_GRP_MIN; + max = DH_GRP_MAX; + + /* Servers with MAX4096DH need a preferred size (nbits) <= 4096. + * We need to also ensure that min < nbits < max */ + + if (datafellows & SSH_BUG_MAX4096DH) { + /* The largest min for these servers is 4096 */ + min = MIN(min, 4096); + } + nbits = dh_estimate(kex->dh_need * 8); + nbits = MIN(nbits, max); + nbits = MAX(nbits, min); + + if (datafellows & SSH_BUG_MAX4096DH) { + /* Cannot have a nbits > 4096 for these servers */ + nbits = MIN(nbits, 4096); + /* nbits has to be powers of two */ + if (nbits == 3072) + nbits = 4096; + } if (datafellows & SSH_OLD_DHGEX) { /* Old GEX request */ packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); packet_put_int(nbits); - min = DH_GRP_MIN; - max = DH_GRP_MAX; debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); } else { /* New GEX request */ - min = DH_GRP_MIN; - max = DH_GRP_MAX; packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); packet_put_int(min); packet_put_int(nbits);