vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Jakub Jelen 72514f
From 6ff8f667f792052fd47689c3e421fcd6ddca1cd0 Mon Sep 17 00:00:00 2001
Jakub Jelen 72514f
From: Jakub Jelen <jjelen@redhat.com>
Jakub Jelen 72514f
Date: Fri, 25 Aug 2017 19:15:48 +0200
Jakub Jelen 72514f
Subject: [PATCH 1/3] GSSAPI Key exchange methods with DH and SHA2
Jakub Jelen 72514f
Jakub Jelen 72514f
---
Jakub Jelen 72514f
 gss-genr.c         | 10 ++++++++++
Jakub Jelen 72514f
 kex.c              |  2 ++
Jakub Jelen 72514f
 kex.h              |  2 ++
Jakub Jelen 72514f
 kexgssc.c          |  6 ++++++
Jakub Jelen 72514f
 kexgsss.c          |  6 ++++++
Jakub Jelen 72514f
 monitor.c          |  2 ++
Jakub Jelen 72514f
 regress/kextype.sh |  4 +++-
Jakub Jelen 72514f
 regress/rekey.sh   |  8 ++++++--
Jakub Jelen 72514f
 ssh-gss.h          |  2 ++
Jakub Jelen 72514f
 ssh_config.5       |  4 +++-
Jakub Jelen 72514f
 sshconnect2.c      |  2 ++
Jakub Jelen 72514f
 sshd.c             |  2 ++
Jakub Jelen 72514f
 sshd_config.5      |  4 +++-
Jakub Jelen 72514f
 13 files changed, 49 insertions(+), 5 deletions(-)
Jakub Jelen 72514f
Jakub Jelen 72514f
diff --git a/gss-genr.c b/gss-genr.c
Jakub Jelen 72514f
index dc63682d..c6eff3d7 100644
Jakub Jelen 72514f
--- a/gss-genr.c
Jakub Jelen 72514f
+++ b/gss-genr.c
Jakub Jelen 72514f
@@ -183,6 +183,16 @@ ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
Jakub Jelen 72514f
 			return GSS_C_NO_OID;
Jakub Jelen 72514f
 		name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
Jakub Jelen 72514f
 		break;
Jakub Jelen 72514f
+	case KEX_GSS_GRP14_SHA256:
Jakub Jelen 72514f
+		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA256_ID))
Jakub Jelen 72514f
+			return GSS_C_NO_OID;
Jakub Jelen 72514f
+		name += sizeof(KEX_GSS_GRP14_SHA256_ID) - 1;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_GRP16_SHA512:
Jakub Jelen 72514f
+		if (strlen(name) < sizeof(KEX_GSS_GRP16_SHA512_ID))
Jakub Jelen 72514f
+			return GSS_C_NO_OID;
Jakub Jelen 72514f
+		name += sizeof(KEX_GSS_GRP16_SHA512_ID) - 1;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
 	case KEX_GSS_GEX_SHA1:
Jakub Jelen 72514f
 		if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID))
Jakub Jelen 72514f
 			return GSS_C_NO_OID;
Jakub Jelen 72514f
diff --git a/kex.c b/kex.c
Jakub Jelen 72514f
index 63e028fa..e798fecb 100644
Jakub Jelen 72514f
--- a/kex.c
Jakub Jelen 72514f
+++ b/kex.c
Jakub Jelen 72514f
@@ -112,6 +112,8 @@ static const struct kexalg kexalgs[] = {
Jakub Jelen 72514f
 	{ KEX_GSS_GEX_SHA1_ID, KEX_GSS_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
Jakub Jelen 72514f
 	{ KEX_GSS_GRP1_SHA1_ID, KEX_GSS_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
Jakub Jelen 72514f
 	{ KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
Jakub Jelen 72514f
+	{ KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
Jakub Jelen 72514f
+	{ KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
 	{ NULL, -1, -1, -1},
Jakub Jelen 72514f
 };
Jakub Jelen 72514f
diff --git a/kex.h b/kex.h
Jakub Jelen 72514f
index 8a2b37c5..f27958ae 100644
Jakub Jelen 72514f
--- a/kex.h
Jakub Jelen 72514f
+++ b/kex.h
Jakub Jelen 72514f
@@ -102,6 +102,8 @@ enum kex_exchange {
Jakub Jelen 72514f
 #ifdef GSSAPI
Jakub Jelen 72514f
 	KEX_GSS_GRP1_SHA1,
Jakub Jelen 72514f
 	KEX_GSS_GRP14_SHA1,
Jakub Jelen 72514f
+	KEX_GSS_GRP14_SHA256,
Jakub Jelen 72514f
+	KEX_GSS_GRP16_SHA512,
Jakub Jelen 72514f
 	KEX_GSS_GEX_SHA1,
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
 	KEX_MAX
Jakub Jelen 72514f
diff --git a/kexgssc.c b/kexgssc.c
Jakub Jelen 72514f
index 132df8b5..ed23f06d 100644
Jakub Jelen 72514f
--- a/kexgssc.c
Jakub Jelen 72514f
+++ b/kexgssc.c
Jakub Jelen 72514f
@@ -88,8 +88,12 @@ kexgss_client(struct ssh *ssh) {
Jakub Jelen 72514f
 		dh = dh_new_group1();
Jakub Jelen 72514f
 		break;
Jakub Jelen 72514f
 	case KEX_GSS_GRP14_SHA1:
Jakub Jelen 72514f
+	case KEX_GSS_GRP14_SHA256:
Jakub Jelen 72514f
 		dh = dh_new_group14();
Jakub Jelen 72514f
 		break;
Jakub Jelen 72514f
+	case KEX_GSS_GRP16_SHA512:
Jakub Jelen 72514f
+		dh = dh_new_group16();
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
 	case KEX_GSS_GEX_SHA1:
Jakub Jelen 72514f
 		debug("Doing group exchange\n");
Jakub Jelen 72514f
 		nbits = dh_estimate(ssh->kex->we_need * 8);
Jakub Jelen 72514f
@@ -272,6 +276,8 @@ kexgss_client(struct ssh *ssh) {
Jakub Jelen 72514f
 	switch (ssh->kex->kex_type) {
Jakub Jelen 72514f
 	case KEX_GSS_GRP1_SHA1:
Jakub Jelen 72514f
 	case KEX_GSS_GRP14_SHA1:
Jakub Jelen 72514f
+	case KEX_GSS_GRP14_SHA256:
Jakub Jelen 72514f
+	case KEX_GSS_GRP16_SHA512:
Jakub Jelen 72514f
 		kex_dh_hash(ssh->kex->hash_alg, ssh->kex->client_version_string, 
Jakub Jelen 72514f
 		    ssh->kex->server_version_string,
Jakub Jelen 72514f
 		    buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my),
Jakub Jelen 72514f
diff --git a/kexgsss.c b/kexgsss.c
Jakub Jelen 72514f
index 82a715cc..b7da8823 100644
Jakub Jelen 72514f
--- a/kexgsss.c
Jakub Jelen 72514f
+++ b/kexgsss.c
Jakub Jelen 72514f
@@ -104,8 +104,12 @@ kexgss_server(struct ssh *ssh)
Jakub Jelen 72514f
 		dh = dh_new_group1();
Jakub Jelen 72514f
 		break;
Jakub Jelen 72514f
 	case KEX_GSS_GRP14_SHA1:
Jakub Jelen 72514f
+	case KEX_GSS_GRP14_SHA256:
Jakub Jelen 72514f
 		dh = dh_new_group14();
Jakub Jelen 72514f
 		break;
Jakub Jelen 72514f
+	case KEX_GSS_GRP16_SHA512:
Jakub Jelen 72514f
+		dh = dh_new_group16();
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
 	case KEX_GSS_GEX_SHA1:
Jakub Jelen 72514f
 		debug("Doing group exchange");
Jakub Jelen 72514f
 		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
Jakub Jelen 72514f
@@ -223,6 +227,8 @@ kexgss_server(struct ssh *ssh)
Jakub Jelen 72514f
 	switch (ssh->kex->kex_type) {
Jakub Jelen 72514f
 	case KEX_GSS_GRP1_SHA1:
Jakub Jelen 72514f
 	case KEX_GSS_GRP14_SHA1:
Jakub Jelen 72514f
+	case KEX_GSS_GRP14_SHA256:
Jakub Jelen 72514f
+	case KEX_GSS_GRP16_SHA512:
Jakub Jelen 72514f
 		kex_dh_hash(ssh->kex->hash_alg,
Jakub Jelen 72514f
 		    ssh->kex->client_version_string, ssh->kex->server_version_string,
Jakub Jelen 72514f
 		    buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer),
Jakub Jelen 72514f
diff --git a/monitor.c b/monitor.c
Jakub Jelen 72514f
index 17046936..d6bc7ac7 100644
Jakub Jelen 72514f
--- a/monitor.c
Jakub Jelen 72514f
+++ b/monitor.c
Jakub Jelen 72514f
@@ -1648,6 +1648,8 @@ monitor_apply_keystate(struct monitor *pmonitor)
Jakub Jelen 72514f
 	if (options.gss_keyex) {
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
diff --git a/regress/kextype.sh b/regress/kextype.sh
Jakub Jelen 72514f
index 780362ca..45f4f16d 100644
Jakub Jelen 72514f
--- a/regress/kextype.sh
Jakub Jelen 72514f
+++ b/regress/kextype.sh
Jakub Jelen 72514f
@@ -14,7 +14,9 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 tries="1 2 3 4"
Jakub Jelen 72514f
 for k in `${SSH} -Q kex`; do
Jakub Jelen 72514f
-	if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o $k = "gss-group14-sha1-" ]; then
Jakub Jelen 72514f
+	if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
+	    $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
+	    $k = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
 		continue
Jakub Jelen 72514f
 	fi
Jakub Jelen 72514f
 	verbose "kex $k"
Jakub Jelen 72514f
diff --git a/regress/rekey.sh b/regress/rekey.sh
Jakub Jelen 72514f
index 9fbe9b38..a2921bef 100644
Jakub Jelen 72514f
--- a/regress/rekey.sh
Jakub Jelen 72514f
+++ b/regress/rekey.sh
Jakub Jelen 72514f
@@ -38,7 +38,9 @@ increase_datafile_size 300
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 opts=""
Jakub Jelen 72514f
 for i in `${SSH} -Q kex`; do
Jakub Jelen 72514f
-	if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o $i = "gss-group14-sha1-" ]; then
Jakub Jelen 72514f
+	if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
+	    $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
+	    $i = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
 		continue
Jakub Jelen 72514f
 	fi
Jakub Jelen 72514f
 	opts="$opts KexAlgorithms=$i"
Jakub Jelen 72514f
@@ -59,7 +61,9 @@ done
Jakub Jelen 72514f
 if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then
Jakub Jelen 72514f
   for c in `${SSH} -Q cipher-auth`; do
Jakub Jelen 72514f
     for kex in `${SSH} -Q kex`; do
Jakub Jelen 72514f
-	if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o $kex = "gss-group14-sha1-" ]; then
Jakub Jelen 72514f
+	if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
+	    $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
+	    $kex = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
 		continue
Jakub Jelen 72514f
 	fi
Jakub Jelen 72514f
 	verbose "client rekey $c $kex"
Jakub Jelen 72514f
diff --git a/ssh-gss.h b/ssh-gss.h
Jakub Jelen 72514f
index 6b6adb2b..7bf8d75e 100644
Jakub Jelen 72514f
--- a/ssh-gss.h
Jakub Jelen 72514f
+++ b/ssh-gss.h
Jakub Jelen 72514f
@@ -70,6 +70,8 @@
Jakub Jelen 72514f
 #define SSH2_MSG_KEXGSS_GROUP				41
Jakub Jelen 72514f
 #define KEX_GSS_GRP1_SHA1_ID				"gss-group1-sha1-"
Jakub Jelen 72514f
 #define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
Jakub Jelen 72514f
+#define KEX_GSS_GRP14_SHA256_ID			"gss-group14-sha256-"
Jakub Jelen 72514f
+#define KEX_GSS_GRP16_SHA512_ID			"gss-group16-sha512-"
Jakub Jelen 72514f
 #define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 #define        GSS_KEX_DEFAULT_KEX \
Jakub Jelen 72514f
diff --git a/ssh_config.5 b/ssh_config.5
Jakub Jelen 72514f
index 6b24649e..3d6da510 100644
Jakub Jelen 72514f
--- a/ssh_config.5
Jakub Jelen 72514f
+++ b/ssh_config.5
Jakub Jelen 72514f
@@ -760,7 +760,9 @@ key exchange. Possible values are
Jakub Jelen 72514f
 .Bd -literal -offset 3n
Jakub Jelen 72514f
 gss-gex-sha1-,
Jakub Jelen 72514f
 gss-group1-sha1-,
Jakub Jelen 72514f
-gss-group14-sha1-
Jakub Jelen 72514f
+gss-group14-sha1-,
Jakub Jelen 72514f
+gss-group14-sha256-,
Jakub Jelen 72514f
+gss-group16-sha512-
Jakub Jelen 72514f
 .Ed
Jakub Jelen 72514f
 .Pp
Jakub Jelen 72514f
 The default is
Jakub Jelen 72514f
diff --git a/sshconnect2.c b/sshconnect2.c
Jakub Jelen 72514f
index 8db98293..5d6b8be0 100644
Jakub Jelen 72514f
--- a/sshconnect2.c
Jakub Jelen 72514f
+++ b/sshconnect2.c
Jakub Jelen 72514f
@@ -253,6 +253,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
Jakub Jelen 72514f
 	if (options.gss_keyex) {
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
diff --git a/sshd.c b/sshd.c
Jakub Jelen 72514f
index 895df26f..e4c879a2 100644
Jakub Jelen 72514f
--- a/sshd.c
Jakub Jelen 72514f
+++ b/sshd.c
Jakub Jelen 72514f
@@ -2244,6 +2244,8 @@ do_ssh2_kex(void)
Jakub Jelen 72514f
 	if (options.gss_keyex) {
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
diff --git a/sshd_config.5 b/sshd_config.5
Jakub Jelen 72514f
index bf81f6af..0793418b 100644
Jakub Jelen 72514f
--- a/sshd_config.5
Jakub Jelen 72514f
+++ b/sshd_config.5
Jakub Jelen 72514f
@@ -675,7 +675,9 @@ key exchange. Possible values are
Jakub Jelen 72514f
 .Bd -literal -offset 3n
Jakub Jelen 72514f
 gss-gex-sha1-,
Jakub Jelen 72514f
 gss-group1-sha1-,
Jakub Jelen 72514f
-gss-group14-sha1-
Jakub Jelen 72514f
+gss-group14-sha1-,
Jakub Jelen 72514f
+gss-group14-sha256-,
Jakub Jelen 72514f
+gss-group16-sha512-
Jakub Jelen 72514f
 .Ed
Jakub Jelen 72514f
 .Pp
Jakub Jelen 72514f
 The default is
Jakub Jelen 72514f
-- 
Jakub Jelen 72514f
2.13.5
Jakub Jelen 72514f
Jakub Jelen 72514f
Jakub Jelen 72514f
From 7d56144903fc625c33da7fabf103f4f6bba4d43a Mon Sep 17 00:00:00 2001
Jakub Jelen 72514f
From: Jakub Jelen <jjelen@redhat.com>
Jakub Jelen 72514f
Date: Tue, 29 Aug 2017 15:32:14 +0200
Jakub Jelen 72514f
Subject: [PATCH 2/3] GSSAPI Key exchange using ECDH and SHA2
Jakub Jelen 72514f
Jakub Jelen 72514f
---
Jakub Jelen 72514f
 gss-genr.c         |  10 ++
Jakub Jelen 72514f
 kex.c              |   3 +
Jakub Jelen 72514f
 kex.h              |   4 +
Jakub Jelen 72514f
 kexgssc.c          | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
Jakub Jelen 72514f
 kexgsss.c          | 333 +++++++++++++++++++++++++++++++++++++++++++++
Jakub Jelen 72514f
 monitor.c          |   5 +-
Jakub Jelen 72514f
 regress/kextype.sh |   1 +
Jakub Jelen 72514f
 regress/rekey.sh   |   2 +
Jakub Jelen 72514f
 ssh-gss.h          |   2 +
Jakub Jelen 72514f
 ssh_config.5       |   4 +-
Jakub Jelen 72514f
 sshconnect2.c      |   2 +
Jakub Jelen 72514f
 sshd.c             |   2 +
Jakub Jelen 72514f
 sshd_config.5      |   4 +-
Jakub Jelen 72514f
 13 files changed, 754 insertions(+), 10 deletions(-)
Jakub Jelen 72514f
Jakub Jelen 72514f
diff --git a/gss-genr.c b/gss-genr.c
Jakub Jelen 72514f
index c6eff3d7..22040244 100644
Jakub Jelen 72514f
--- a/gss-genr.c
Jakub Jelen 72514f
+++ b/gss-genr.c
Jakub Jelen 72514f
@@ -198,6 +198,16 @@ ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
Jakub Jelen 72514f
 			return GSS_C_NO_OID;
Jakub Jelen 72514f
 		name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
Jakub Jelen 72514f
 		break;
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if (strlen(name) < sizeof(KEX_GSS_NISTP256_SHA256_ID))
Jakub Jelen 72514f
+			return GSS_C_NO_OID;
Jakub Jelen 72514f
+		name += sizeof(KEX_GSS_NISTP256_SHA256_ID) - 1;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		if (strlen(name) < sizeof(KEX_GSS_C25519_SHA256_ID))
Jakub Jelen 72514f
+			return GSS_C_NO_OID;
Jakub Jelen 72514f
+		name += sizeof(KEX_GSS_C25519_SHA256_ID) - 1;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
 	default:
Jakub Jelen 72514f
 		return GSS_C_NO_OID;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
diff --git a/kex.c b/kex.c
Jakub Jelen 72514f
index e798fecb..bdeeada9 100644
Jakub Jelen 72514f
--- a/kex.c
Jakub Jelen 72514f
+++ b/kex.c
Jakub Jelen 72514f
@@ -114,6 +114,9 @@ static const struct kexalg kexalgs[] = {
Jakub Jelen 72514f
 	{ KEX_GSS_GRP14_SHA1_ID, KEX_GSS_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
Jakub Jelen 72514f
 	{ KEX_GSS_GRP14_SHA256_ID, KEX_GSS_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
Jakub Jelen 72514f
 	{ KEX_GSS_GRP16_SHA512_ID, KEX_GSS_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
Jakub Jelen 72514f
+	{ KEX_GSS_NISTP256_SHA256_ID, KEX_GSS_NISTP256_SHA256,
Jakub Jelen 72514f
+	    NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
Jakub Jelen 72514f
+	{ KEX_GSS_C25519_SHA256_ID, KEX_GSS_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
 	{ NULL, -1, -1, -1},
Jakub Jelen 72514f
 };
Jakub Jelen 72514f
diff --git a/kex.h b/kex.h
Jakub Jelen 72514f
index f27958ae..7def8561 100644
Jakub Jelen 72514f
--- a/kex.h
Jakub Jelen 72514f
+++ b/kex.h
Jakub Jelen 72514f
@@ -105,6 +105,8 @@ enum kex_exchange {
Jakub Jelen 72514f
 	KEX_GSS_GRP14_SHA256,
Jakub Jelen 72514f
 	KEX_GSS_GRP16_SHA512,
Jakub Jelen 72514f
 	KEX_GSS_GEX_SHA1,
Jakub Jelen 72514f
+	KEX_GSS_NISTP256_SHA256,
Jakub Jelen 72514f
+	KEX_GSS_C25519_SHA256,
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
 	KEX_MAX
Jakub Jelen 72514f
 };
Jakub Jelen 72514f
@@ -211,6 +213,8 @@ int	 kexecdh_server(struct ssh *);
Jakub Jelen 72514f
 int	 kexc25519_client(struct ssh *);
Jakub Jelen 72514f
 int	 kexc25519_server(struct ssh *);
Jakub Jelen 72514f
 #ifdef GSSAPI
Jakub Jelen 72514f
+int	 kexecgss_client(struct ssh *);
Jakub Jelen 72514f
+int	 kexecgss_server(struct ssh *);
Jakub Jelen 72514f
 int	 kexgss_client(struct ssh *);
Jakub Jelen 72514f
 int	 kexgss_server(struct ssh *);
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
diff --git a/kexgssc.c b/kexgssc.c
Jakub Jelen 72514f
index ed23f06d..bdb3109a 100644
Jakub Jelen 72514f
--- a/kexgssc.c
Jakub Jelen 72514f
+++ b/kexgssc.c
Jakub Jelen 72514f
@@ -43,6 +43,7 @@
Jakub Jelen 72514f
 #include "packet.h"
Jakub Jelen 72514f
 #include "dh.h"
Jakub Jelen 72514f
 #include "digest.h"
Jakub Jelen 72514f
+#include "ssherr.h"
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 #include "ssh-gss.h"
Jakub Jelen 72514f
 
Jakub Jelen 72514f
@@ -52,7 +53,7 @@ kexgss_client(struct ssh *ssh) {
Jakub Jelen 72514f
 	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
Jakub Jelen 72514f
 	Gssctxt *ctxt;
Jakub Jelen 72514f
 	OM_uint32 maj_status, min_status, ret_flags;
Jakub Jelen 72514f
-	u_int klen, kout, slen = 0, strlen;
Jakub Jelen 72514f
+	u_int klen, kout, slen = 0, packet_len;
Jakub Jelen 72514f
 	DH *dh; 
Jakub Jelen 72514f
 	BIGNUM *dh_server_pub = NULL;
Jakub Jelen 72514f
 	BIGNUM *shared_secret = NULL;
Jakub Jelen 72514f
@@ -201,20 +202,20 @@ kexgss_client(struct ssh *ssh) {
Jakub Jelen 72514f
 				debug("Received GSSAPI_CONTINUE");
Jakub Jelen 72514f
 				if (maj_status == GSS_S_COMPLETE) 
Jakub Jelen 72514f
 					fatal("GSSAPI Continue received from server when complete");
Jakub Jelen 72514f
-				recv_tok.value = packet_get_string(&strlen);
Jakub Jelen 72514f
-				recv_tok.length = strlen; 
Jakub Jelen 72514f
+				recv_tok.value = packet_get_string(&packet_len);
Jakub Jelen 72514f
+				recv_tok.length = packet_len;
Jakub Jelen 72514f
 				break;
Jakub Jelen 72514f
 			case SSH2_MSG_KEXGSS_COMPLETE:
Jakub Jelen 72514f
 				debug("Received GSSAPI_COMPLETE");
Jakub Jelen 72514f
 				packet_get_bignum2(dh_server_pub);
Jakub Jelen 72514f
-				msg_tok.value =  packet_get_string(&strlen);
Jakub Jelen 72514f
-				msg_tok.length = strlen; 
Jakub Jelen 72514f
+				msg_tok.value =  packet_get_string(&packet_len);
Jakub Jelen 72514f
+				msg_tok.length = packet_len;
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 				/* Is there a token included? */
Jakub Jelen 72514f
 				if (packet_get_char()) {
Jakub Jelen 72514f
 					recv_tok.value=
Jakub Jelen 72514f
-					    packet_get_string(&strlen);
Jakub Jelen 72514f
-					recv_tok.length = strlen;
Jakub Jelen 72514f
+					    packet_get_string(&packet_len);
Jakub Jelen 72514f
+					recv_tok.length = packet_len;
Jakub Jelen 72514f
 					/* If we're already complete - protocol error */
Jakub Jelen 72514f
 					if (maj_status == GSS_S_COMPLETE)
Jakub Jelen 72514f
 						packet_disconnect("Protocol error: received token when complete");
Jakub Jelen 72514f
@@ -344,4 +345,381 @@ kexgss_client(struct ssh *ssh) {
Jakub Jelen 72514f
 	return kex_send_newkeys(ssh);
Jakub Jelen 72514f
 }
Jakub Jelen 72514f
 
Jakub Jelen 72514f
+int
Jakub Jelen 72514f
+kexecgss_client(struct ssh *ssh) {
Jakub Jelen 72514f
+	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Jakub Jelen 72514f
+	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
Jakub Jelen 72514f
+	Gssctxt *ctxt;
Jakub Jelen 72514f
+	OM_uint32 maj_status, min_status, ret_flags;
Jakub Jelen 72514f
+	u_int klen = 0, slen = 0, packet_len;
Jakub Jelen 72514f
+	u_char *server_pub = NULL;
Jakub Jelen 72514f
+	u_int server_pub_len = 0;
Jakub Jelen 72514f
+	BIGNUM *shared_secret = NULL;
Jakub Jelen 72514f
+	u_char *kbuf;
Jakub Jelen 72514f
+	u_char *serverhostkey = NULL;
Jakub Jelen 72514f
+	u_char *empty = "";
Jakub Jelen 72514f
+	char *msg;
Jakub Jelen 72514f
+	char *lang;
Jakub Jelen 72514f
+	int type = 0;
Jakub Jelen 72514f
+	int first = 1;
Jakub Jelen 72514f
+	u_char hash[SSH_DIGEST_MAX_LENGTH];
Jakub Jelen 72514f
+	size_t hashlen;
Jakub Jelen 72514f
+	const EC_GROUP *group = NULL;
Jakub Jelen 72514f
+	const EC_POINT *public_key;
Jakub Jelen 72514f
+	struct sshbuf *Q_C = NULL;
Jakub Jelen 72514f
+	struct kex *kex = ssh->kex;
Jakub Jelen 72514f
+	EC_POINT *server_public = NULL;
Jakub Jelen 72514f
+	struct sshbuf *c25519_shared_secret = NULL;
Jakub Jelen 72514f
+	int r;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* Initialise our GSSAPI world */
Jakub Jelen 72514f
+	ssh_gssapi_build_ctx(&ctxt);
Jakub Jelen 72514f
+	if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type)
Jakub Jelen 72514f
+	    == GSS_C_NO_OID)
Jakub Jelen 72514f
+		fatal("Couldn't identify host exchange");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (ssh_gssapi_import_name(ctxt, kex->gss_host))
Jakub Jelen 72514f
+		fatal("Couldn't import hostname");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (kex->gss_client &&
Jakub Jelen 72514f
+	    ssh_gssapi_client_identity(ctxt, kex->gss_client))
Jakub Jelen 72514f
+		fatal("Couldn't acquire client credentials");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if ((Q_C = sshbuf_new()) == NULL) {
Jakub Jelen 72514f
+		r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+		goto out;
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if ((kex->ec_client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if (EC_KEY_generate_key(kex->ec_client_key) != 1) {
Jakub Jelen 72514f
+			r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		group = EC_KEY_get0_group(kex->ec_client_key);
Jakub Jelen 72514f
+		public_key = EC_KEY_get0_public_key(kex->ec_client_key);
Jakub Jelen 72514f
+#ifdef DEBUG_KEXECDH
Jakub Jelen 72514f
+	fputs("client private key:\n", stderr);
Jakub Jelen 72514f
+	sshkey_dump_ec_key(kex->ec_client_key);
Jakub Jelen 72514f
+#endif
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		sshbuf_put_ec(Q_C, public_key, group);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		kexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey);
Jakub Jelen 72514f
+#ifdef DEBUG_KEXECDH
Jakub Jelen 72514f
+		dump_digest("client private key:", kex->c25519_client_key,
Jakub Jelen 72514f
+		    sizeof(kex->c25519_client_key));
Jakub Jelen 72514f
+#endif
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		sshbuf_put_string(Q_C, kex->c25519_client_pubkey,
Jakub Jelen 72514f
+		    sizeof(kex->c25519_client_pubkey));
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	token_ptr = GSS_C_NO_BUFFER;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	do {
Jakub Jelen 72514f
+		/* Step 2 - call GSS_Init_sec_context() */
Jakub Jelen 72514f
+		debug("Calling gss_init_sec_context");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		maj_status = ssh_gssapi_init_ctx(ctxt,
Jakub Jelen 72514f
+		    kex->gss_deleg_creds, token_ptr, &send_tok,
Jakub Jelen 72514f
+		    &ret_flags);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (GSS_ERROR(maj_status)) {
Jakub Jelen 72514f
+			if (send_tok.length != 0) {
Jakub Jelen 72514f
+				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jakub Jelen 72514f
+				packet_put_string(send_tok.value,
Jakub Jelen 72514f
+				    send_tok.length);
Jakub Jelen 72514f
+			}
Jakub Jelen 72514f
+			fatal("gss_init_context failed");
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/* If we've got an old receive buffer get rid of it */
Jakub Jelen 72514f
+		if (token_ptr != GSS_C_NO_BUFFER)
Jakub Jelen 72514f
+			free(recv_tok.value);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (maj_status == GSS_S_COMPLETE) {
Jakub Jelen 72514f
+			/* If mutual state flag is not true, kex fails */
Jakub Jelen 72514f
+			if (!(ret_flags & GSS_C_MUTUAL_FLAG))
Jakub Jelen 72514f
+				fatal("Mutual authentication failed");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+			/* If integ avail flag is not true kex fails */
Jakub Jelen 72514f
+			if (!(ret_flags & GSS_C_INTEG_FLAG))
Jakub Jelen 72514f
+				fatal("Integrity check failed");
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/*
Jakub Jelen 72514f
+		 * If we have data to send, then the last message that we
Jakub Jelen 72514f
+		 * received cannot have been a 'complete'.
Jakub Jelen 72514f
+		 */
Jakub Jelen 72514f
+		if (send_tok.length != 0) {
Jakub Jelen 72514f
+			if (first) {
Jakub Jelen 72514f
+				const u_char * ptr;
Jakub Jelen 72514f
+				size_t len;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+				packet_start(SSH2_MSG_KEXGSS_INIT);
Jakub Jelen 72514f
+				packet_put_string(send_tok.value,
Jakub Jelen 72514f
+				    send_tok.length);
Jakub Jelen 72514f
+				sshbuf_get_string_direct(Q_C, &ptr, &len;;
Jakub Jelen 72514f
+				packet_put_string(ptr, len);
Jakub Jelen 72514f
+				first = 0;
Jakub Jelen 72514f
+			} else {
Jakub Jelen 72514f
+				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jakub Jelen 72514f
+				packet_put_string(send_tok.value,
Jakub Jelen 72514f
+				    send_tok.length);
Jakub Jelen 72514f
+			}
Jakub Jelen 72514f
+			packet_send();
Jakub Jelen 72514f
+			gss_release_buffer(&min_status, &send_tok);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+			/* If we've sent them data, they should reply */
Jakub Jelen 72514f
+			do {
Jakub Jelen 72514f
+				type = packet_read();
Jakub Jelen 72514f
+				if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
Jakub Jelen 72514f
+					debug("Received KEXGSS_HOSTKEY");
Jakub Jelen 72514f
+					if (serverhostkey)
Jakub Jelen 72514f
+						fatal("Server host key received more than once");
Jakub Jelen 72514f
+					serverhostkey =
Jakub Jelen 72514f
+					    packet_get_string(&slen);
Jakub Jelen 72514f
+				}
Jakub Jelen 72514f
+			} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+			switch (type) {
Jakub Jelen 72514f
+			case SSH2_MSG_KEXGSS_CONTINUE:
Jakub Jelen 72514f
+				debug("Received GSSAPI_CONTINUE");
Jakub Jelen 72514f
+				if (maj_status == GSS_S_COMPLETE)
Jakub Jelen 72514f
+					fatal("GSSAPI Continue received from server when complete");
Jakub Jelen 72514f
+				recv_tok.value = packet_get_string(&packet_len);
Jakub Jelen 72514f
+				recv_tok.length = packet_len;
Jakub Jelen 72514f
+				break;
Jakub Jelen 72514f
+			case SSH2_MSG_KEXGSS_COMPLETE:
Jakub Jelen 72514f
+				debug("Received GSSAPI_COMPLETE");
Jakub Jelen 72514f
+				server_pub = packet_get_string(&server_pub_len);
Jakub Jelen 72514f
+				msg_tok.value = packet_get_string(&packet_len);
Jakub Jelen 72514f
+				msg_tok.length = packet_len;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+				/* Is there a token included? */
Jakub Jelen 72514f
+				if (packet_get_char()) {
Jakub Jelen 72514f
+					recv_tok.value=
Jakub Jelen 72514f
+					    packet_get_string(&packet_len);
Jakub Jelen 72514f
+					recv_tok.length = packet_len;
Jakub Jelen 72514f
+					/* If we're already complete - protocol error */
Jakub Jelen 72514f
+					if (maj_status == GSS_S_COMPLETE)
Jakub Jelen 72514f
+						packet_disconnect("Protocol error: received token when complete");
Jakub Jelen 72514f
+					} else {
Jakub Jelen 72514f
+						/* No token included */
Jakub Jelen 72514f
+						if (maj_status != GSS_S_COMPLETE)
Jakub Jelen 72514f
+							packet_disconnect("Protocol error: did not receive final token");
Jakub Jelen 72514f
+				}
Jakub Jelen 72514f
+				break;
Jakub Jelen 72514f
+			case SSH2_MSG_KEXGSS_ERROR:
Jakub Jelen 72514f
+				debug("Received Error");
Jakub Jelen 72514f
+				maj_status = packet_get_int();
Jakub Jelen 72514f
+				min_status = packet_get_int();
Jakub Jelen 72514f
+				msg = packet_get_string(NULL);
Jakub Jelen 72514f
+				lang = packet_get_string(NULL);
Jakub Jelen 72514f
+				fatal("GSSAPI Error: \n%.400s",msg);
Jakub Jelen 72514f
+			default:
Jakub Jelen 72514f
+				packet_disconnect("Protocol error: didn't expect packet type %d",
Jakub Jelen 72514f
+				    type);
Jakub Jelen 72514f
+			}
Jakub Jelen 72514f
+			token_ptr = &recv_tok;
Jakub Jelen 72514f
+		} else {
Jakub Jelen 72514f
+			/* No data, and not complete */
Jakub Jelen 72514f
+			if (maj_status != GSS_S_COMPLETE)
Jakub Jelen 72514f
+				fatal("Not complete, and no token output");
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+	} while (maj_status & GSS_S_CONTINUE_NEEDED);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/*
Jakub Jelen 72514f
+	 * We _must_ have received a COMPLETE message in reply from the
Jakub Jelen 72514f
+	 * server, which will have set dh_server_pub and msg_tok
Jakub Jelen 72514f
+	 */
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (type != SSH2_MSG_KEXGSS_COMPLETE)
Jakub Jelen 72514f
+		fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* 7. C verifies that the key Q_S is valid */
Jakub Jelen 72514f
+	/* 8. C computes shared secret */
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if (server_pub_len != 65)
Jakub Jelen 72514f
+			fatal("The received NIST-P256 key did not match"
Jakub Jelen 72514f
+			    "expected length (expected 65, got %d)", server_pub_len);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (server_pub[0] != POINT_CONVERSION_UNCOMPRESSED)
Jakub Jelen 72514f
+			fatal("The received NIST-P256 key does not have first octet 0x04");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if ((server_public = EC_POINT_new(group)) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (!EC_POINT_oct2point(group, server_public, server_pub,
Jakub Jelen 72514f
+		    server_pub_len, NULL))
Jakub Jelen 72514f
+			fatal("Can not decode received NIST-P256 client key");
Jakub Jelen 72514f
+#ifdef DEBUG_KEXECDH
Jakub Jelen 72514f
+		fputs("server public key:\n", stderr);
Jakub Jelen 72514f
+		sshkey_dump_ec_point(group, server_public);
Jakub Jelen 72514f
+#endif
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (sshkey_ec_validate_public(group, server_public) != 0) {
Jakub Jelen 72514f
+			sshpkt_disconnect(ssh, "invalid client public key");
Jakub Jelen 72514f
+			r = SSH_ERR_MESSAGE_INCOMPLETE;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (!EC_POINT_is_on_curve(group, server_public, NULL))
Jakub Jelen 72514f
+			fatal("Received NIST-P256 client key is not on curve");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/* Calculate shared_secret */
Jakub Jelen 72514f
+		klen = (EC_GROUP_get_degree(group) + 7) / 8;
Jakub Jelen 72514f
+		if ((kbuf = malloc(klen)) == NULL ||
Jakub Jelen 72514f
+		    (shared_secret = BN_new()) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if (ECDH_compute_key(kbuf, klen, server_public,
Jakub Jelen 72514f
+		    kex->ec_client_key, NULL) != (int)klen ||
Jakub Jelen 72514f
+		    BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+#ifdef DEBUG_KEXECDH
Jakub Jelen 72514f
+		dump_digest("shared secret", kbuf, klen);
Jakub Jelen 72514f
+#endif
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		if (server_pub_len != 32)
Jakub Jelen 72514f
+			fatal("The received curve25519 key did not match"
Jakub Jelen 72514f
+			    "expected length (expected 32, got %d)", server_pub_len);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (server_pub[server_pub_len-1] & 0x80)
Jakub Jelen 72514f
+			fatal("The received key has MSB of last octet set!");
Jakub Jelen 72514f
+#ifdef DEBUG_KEXECDH
Jakub Jelen 72514f
+		dump_digest("server public key:", server_pub, CURVE25519_SIZE);
Jakub Jelen 72514f
+#endif
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/* generate shared secret */
Jakub Jelen 72514f
+		if ((c25519_shared_secret = sshbuf_new()) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if ((r = kexc25519_shared_key(kex->c25519_client_key,
Jakub Jelen 72514f
+		    server_pub, c25519_shared_secret)) < 0)
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/* if all octets of the shared secret are zero octets,
Jakub Jelen 72514f
+		 * is already checked in kexc25519_shared_key() */
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	hashlen = sizeof(hash);
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		kex_ecdh_hash(
Jakub Jelen 72514f
+		    kex->hash_alg,
Jakub Jelen 72514f
+		    group,
Jakub Jelen 72514f
+		    kex->client_version_string,
Jakub Jelen 72514f
+		    kex->server_version_string,
Jakub Jelen 72514f
+		    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
Jakub Jelen 72514f
+		    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
Jakub Jelen 72514f
+		    (serverhostkey ? serverhostkey : empty), slen,
Jakub Jelen 72514f
+		    EC_KEY_get0_public_key(kex->ec_client_key),
Jakub Jelen 72514f
+		    server_public,
Jakub Jelen 72514f
+		    shared_secret,
Jakub Jelen 72514f
+		    hash, &hashlen
Jakub Jelen 72514f
+		);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		kex_c25519_hash(
Jakub Jelen 72514f
+		    kex->hash_alg,
Jakub Jelen 72514f
+		    kex->client_version_string, kex->server_version_string,
Jakub Jelen 72514f
+		    buffer_ptr(kex->my), buffer_len(kex->my),
Jakub Jelen 72514f
+		    buffer_ptr(kex->peer), buffer_len(kex->peer),
Jakub Jelen 72514f
+		    (serverhostkey ? serverhostkey : empty), slen,
Jakub Jelen 72514f
+		    kex->c25519_client_pubkey, server_pub,
Jakub Jelen 72514f
+		    sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret),
Jakub Jelen 72514f
+		    hash, &hashlen
Jakub Jelen 72514f
+		);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	gssbuf.value = hash;
Jakub Jelen 72514f
+	gssbuf.length = hashlen;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* Verify that the hash matches the MIC we just got. */
Jakub Jelen 72514f
+	if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
Jakub Jelen 72514f
+		packet_disconnect("Hash's MIC didn't verify");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	free(msg_tok.value);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* save session id */
Jakub Jelen 72514f
+	if (kex->session_id == NULL) {
Jakub Jelen 72514f
+		kex->session_id_len = hashlen;
Jakub Jelen 72514f
+		kex->session_id = xmalloc(kex->session_id_len);
Jakub Jelen 72514f
+		memcpy(kex->session_id, hash, kex->session_id_len);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (kex->gss_deleg_creds)
Jakub Jelen 72514f
+		ssh_gssapi_credentials_updated(ctxt);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (gss_kex_context == NULL)
Jakub Jelen 72514f
+		gss_kex_context = ctxt;
Jakub Jelen 72514f
+	else
Jakub Jelen 72514f
+		ssh_gssapi_delete_ctx(&ctxt);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* Finally derive the keys and send them */
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) != 0)
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		if ((r = kex_derive_keys(ssh, hash, hashlen, c25519_shared_secret)) != 0)
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+	r = kex_send_newkeys(ssh);
Jakub Jelen 72514f
+out:
Jakub Jelen 72514f
+	free(serverhostkey);
Jakub Jelen 72514f
+	explicit_bzero(hash, sizeof(hash));
Jakub Jelen 72514f
+	sshbuf_free(Q_C);
Jakub Jelen 72514f
+	if (server_pub)
Jakub Jelen 72514f
+		free(server_pub);
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if (kex->ec_client_key) {
Jakub Jelen 72514f
+			EC_KEY_free(kex->ec_client_key);
Jakub Jelen 72514f
+			kex->ec_client_key = NULL;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if (server_public)
Jakub Jelen 72514f
+			EC_POINT_clear_free(server_public);
Jakub Jelen 72514f
+		if (kbuf) {
Jakub Jelen 72514f
+			explicit_bzero(kbuf, klen);
Jakub Jelen 72514f
+			free(kbuf);
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if (shared_secret)
Jakub Jelen 72514f
+			BN_clear_free(shared_secret);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
Jakub Jelen 72514f
+		sshbuf_free(c25519_shared_secret);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+	return r;
Jakub Jelen 72514f
+}
Jakub Jelen 72514f
 #endif /* GSSAPI */
Jakub Jelen 72514f
diff --git a/kexgsss.c b/kexgsss.c
Jakub Jelen 72514f
index b7da8823..a7c42803 100644
Jakub Jelen 72514f
--- a/kexgsss.c
Jakub Jelen 72514f
+++ b/kexgsss.c
Jakub Jelen 72514f
@@ -46,6 +46,7 @@
Jakub Jelen 72514f
 #include "servconf.h"
Jakub Jelen 72514f
 #include "ssh-gss.h"
Jakub Jelen 72514f
 #include "digest.h"
Jakub Jelen 72514f
+#include "ssherr.h"
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 extern ServerOptions options;
Jakub Jelen 72514f
 
Jakub Jelen 72514f
@@ -303,4 +304,336 @@ kexgss_server(struct ssh *ssh)
Jakub Jelen 72514f
 		ssh_gssapi_rekey_creds();
Jakub Jelen 72514f
 	return 0;
Jakub Jelen 72514f
 }
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+int
Jakub Jelen 72514f
+kexecgss_server(struct ssh *ssh)
Jakub Jelen 72514f
+{
Jakub Jelen 72514f
+	OM_uint32 maj_status, min_status;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/*
Jakub Jelen 72514f
+	 * Some GSSAPI implementations use the input value of ret_flags (an
Jakub Jelen 72514f
+	 * output variable) as a means of triggering mechanism specific
Jakub Jelen 72514f
+	 * features. Initializing it to zero avoids inadvertently
Jakub Jelen 72514f
+	 * activating this non-standard behaviour.
Jakub Jelen 72514f
+	 */
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	OM_uint32 ret_flags = 0;
Jakub Jelen 72514f
+	gss_buffer_desc gssbuf, recv_tok, msg_tok;
Jakub Jelen 72514f
+	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Jakub Jelen 72514f
+	Gssctxt *ctxt = NULL;
Jakub Jelen 72514f
+	u_int slen, klen = 0;
Jakub Jelen 72514f
+	u_char *kbuf;
Jakub Jelen 72514f
+	BIGNUM *shared_secret = NULL;
Jakub Jelen 72514f
+	int type = 0;
Jakub Jelen 72514f
+	gss_OID oid;
Jakub Jelen 72514f
+	char *mechs;
Jakub Jelen 72514f
+	u_char hash[SSH_DIGEST_MAX_LENGTH];
Jakub Jelen 72514f
+	size_t hashlen;
Jakub Jelen 72514f
+	u_char *client_pub = NULL;
Jakub Jelen 72514f
+	u_int client_pub_len = 0;
Jakub Jelen 72514f
+	const EC_GROUP *group = NULL;
Jakub Jelen 72514f
+	EC_POINT *client_public = NULL;
Jakub Jelen 72514f
+	EC_KEY *server_key = NULL;
Jakub Jelen 72514f
+	const EC_POINT *public_key;
Jakub Jelen 72514f
+	u_char c25519_server_key[CURVE25519_SIZE];
Jakub Jelen 72514f
+	u_char c25519_server_pubkey[CURVE25519_SIZE];
Jakub Jelen 72514f
+	struct sshbuf *c25519_shared_secret = NULL;
Jakub Jelen 72514f
+	struct sshbuf *Q_S;
Jakub Jelen 72514f
+	struct kex *kex = ssh->kex;
Jakub Jelen 72514f
+	int r;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* Initialise GSSAPI */
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* If we're rekeying, privsep means that some of the private structures
Jakub Jelen 72514f
+	 * in the GSSAPI code are no longer available. This kludges them back
Jakub Jelen 72514f
+	 * into life
Jakub Jelen 72514f
+	 */
Jakub Jelen 72514f
+	if (!ssh_gssapi_oid_table_ok())
Jakub Jelen 72514f
+		if ((mechs = ssh_gssapi_server_mechanisms()))
Jakub Jelen 72514f
+			free(mechs);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	debug2("%s: Identifying %s", __func__, kex->name);
Jakub Jelen 72514f
+	oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
Jakub Jelen 72514f
+	if (oid == GSS_C_NO_OID)
Jakub Jelen 72514f
+	   fatal("Unknown gssapi mechanism");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	debug2("%s: Acquiring credentials", __func__);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid))))
Jakub Jelen 72514f
+		fatal("Unable to acquire credentials for the server");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if ((Q_S = sshbuf_new()) == NULL) {
Jakub Jelen 72514f
+		r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+		goto out;
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* 5. S generates an ephemeral key pair (do the allocations early) */
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if (EC_KEY_generate_key(server_key) != 1) {
Jakub Jelen 72514f
+			r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		group = EC_KEY_get0_group(server_key);
Jakub Jelen 72514f
+		public_key = EC_KEY_get0_public_key(server_key);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		sshbuf_put_ec(Q_S, public_key, group);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		kexc25519_keygen(c25519_server_key, c25519_server_pubkey);
Jakub Jelen 72514f
+#ifdef DEBUG_KEXECDH
Jakub Jelen 72514f
+		dump_digest("server private key:", c25519_server_key,
Jakub Jelen 72514f
+		    sizeof(c25519_server_key));
Jakub Jelen 72514f
+#endif
Jakub Jelen 72514f
+		sshbuf_put_string(Q_S, c25519_server_pubkey,
Jakub Jelen 72514f
+		    sizeof(c25519_server_pubkey));
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	do {
Jakub Jelen 72514f
+		debug("Wait SSH2_MSG_GSSAPI_INIT");
Jakub Jelen 72514f
+		type = packet_read();
Jakub Jelen 72514f
+		switch(type) {
Jakub Jelen 72514f
+		case SSH2_MSG_KEXGSS_INIT:
Jakub Jelen 72514f
+			if (client_pub != NULL)
Jakub Jelen 72514f
+				fatal("Received KEXGSS_INIT after initialising");
Jakub Jelen 72514f
+			recv_tok.value = packet_get_string(&slen);
Jakub Jelen 72514f
+			recv_tok.length = slen;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+			client_pub = packet_get_string(&client_pub_len);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+			/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
Jakub Jelen 72514f
+			break;
Jakub Jelen 72514f
+		case SSH2_MSG_KEXGSS_CONTINUE:
Jakub Jelen 72514f
+			recv_tok.value = packet_get_string(&slen);
Jakub Jelen 72514f
+			recv_tok.length = slen;
Jakub Jelen 72514f
+			break;
Jakub Jelen 72514f
+		default:
Jakub Jelen 72514f
+			packet_disconnect(
Jakub Jelen 72514f
+			    "Protocol error: didn't expect packet type %d",
Jakub Jelen 72514f
+			    type);
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok,
Jakub Jelen 72514f
+		    &send_tok, &ret_flags));
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		free(recv_tok.value);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
Jakub Jelen 72514f
+			fatal("Zero length token output when incomplete");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (client_pub == NULL)
Jakub Jelen 72514f
+			fatal("No client public key");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (maj_status & GSS_S_CONTINUE_NEEDED) {
Jakub Jelen 72514f
+			debug("Sending GSSAPI_CONTINUE");
Jakub Jelen 72514f
+			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jakub Jelen 72514f
+			packet_put_string(send_tok.value, send_tok.length);
Jakub Jelen 72514f
+			packet_send();
Jakub Jelen 72514f
+			gss_release_buffer(&min_status, &send_tok);
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+	} while (maj_status & GSS_S_CONTINUE_NEEDED);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (GSS_ERROR(maj_status)) {
Jakub Jelen 72514f
+		if (send_tok.length > 0) {
Jakub Jelen 72514f
+			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
Jakub Jelen 72514f
+			packet_put_string(send_tok.value, send_tok.length);
Jakub Jelen 72514f
+			packet_send();
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		fatal("accept_ctx died");
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (!(ret_flags & GSS_C_MUTUAL_FLAG))
Jakub Jelen 72514f
+		fatal("Mutual Authentication flag wasn't set");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (!(ret_flags & GSS_C_INTEG_FLAG))
Jakub Jelen 72514f
+		fatal("Integrity flag wasn't set");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* 3. S verifies that the (client) key is valid */
Jakub Jelen 72514f
+	/* calculate shared secret */
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if (client_pub_len != 65)
Jakub Jelen 72514f
+			fatal("The received NIST-P256 key did not match"
Jakub Jelen 72514f
+			    "expected length (expected 65, got %d)", client_pub_len);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (client_pub[0] != POINT_CONVERSION_UNCOMPRESSED)
Jakub Jelen 72514f
+			fatal("The received NIST-P256 key does not have first octet 0x04");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if ((client_public = EC_POINT_new(group)) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (!EC_POINT_oct2point(group, client_public, client_pub,
Jakub Jelen 72514f
+		    client_pub_len, NULL))
Jakub Jelen 72514f
+			fatal("Can not decode received NIST-P256 client key");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (sshkey_ec_validate_public(group, client_public) != 0) {
Jakub Jelen 72514f
+			sshpkt_disconnect(ssh, "invalid client public key");
Jakub Jelen 72514f
+			r = SSH_ERR_MESSAGE_INCOMPLETE;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (!EC_POINT_is_on_curve(group, client_public, NULL))
Jakub Jelen 72514f
+			fatal("Received NIST-P256 client key is not on curve");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/* Calculate shared_secret */
Jakub Jelen 72514f
+		klen = (EC_GROUP_get_degree(group) + 7) / 8;
Jakub Jelen 72514f
+		if ((kbuf = malloc(klen)) == NULL ||
Jakub Jelen 72514f
+		    (shared_secret = BN_new()) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if (ECDH_compute_key(kbuf, klen, client_public,
Jakub Jelen 72514f
+		    server_key, NULL) != (int)klen ||
Jakub Jelen 72514f
+		    BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_LIBCRYPTO_ERROR;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		if (client_pub_len != 32)
Jakub Jelen 72514f
+			fatal("The received curve25519 key did not match"
Jakub Jelen 72514f
+			    "expected length (expected 32, got %d)", client_pub_len);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		if (client_pub[client_pub_len-1] & 0x80)
Jakub Jelen 72514f
+			fatal("The received key has MSB of last octet set!");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/* generate shared secret */
Jakub Jelen 72514f
+		if ((c25519_shared_secret = sshbuf_new()) == NULL) {
Jakub Jelen 72514f
+			r = SSH_ERR_ALLOC_FAIL;
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if ((r = kexc25519_shared_key(c25519_server_key,
Jakub Jelen 72514f
+		    client_pub, c25519_shared_secret)) < 0)
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+		/* if all octets of the shared secret are zero octets,
Jakub Jelen 72514f
+		 * is already checked in kexc25519_shared_key() */
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	hashlen = sizeof(hash);
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		kex_ecdh_hash(
Jakub Jelen 72514f
+		    kex->hash_alg,
Jakub Jelen 72514f
+		    group,
Jakub Jelen 72514f
+		    kex->client_version_string,
Jakub Jelen 72514f
+		    kex->server_version_string,
Jakub Jelen 72514f
+		    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
Jakub Jelen 72514f
+		    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
Jakub Jelen 72514f
+		    NULL, 0,
Jakub Jelen 72514f
+		    client_public,
Jakub Jelen 72514f
+		    EC_KEY_get0_public_key(server_key),
Jakub Jelen 72514f
+		    shared_secret,
Jakub Jelen 72514f
+		    hash, &hashlen
Jakub Jelen 72514f
+		);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		kex_c25519_hash(
Jakub Jelen 72514f
+		    kex->hash_alg,
Jakub Jelen 72514f
+		    kex->client_version_string, kex->server_version_string,
Jakub Jelen 72514f
+		    buffer_ptr(kex->peer), buffer_len(kex->peer),
Jakub Jelen 72514f
+		    buffer_ptr(kex->my), buffer_len(kex->my),
Jakub Jelen 72514f
+		    NULL, 0,
Jakub Jelen 72514f
+		    client_pub, c25519_server_pubkey,
Jakub Jelen 72514f
+		    sshbuf_ptr(c25519_shared_secret), sshbuf_len(c25519_shared_secret),
Jakub Jelen 72514f
+		    hash, &hashlen
Jakub Jelen 72514f
+		);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (kex->session_id == NULL) {
Jakub Jelen 72514f
+		kex->session_id_len = hashlen;
Jakub Jelen 72514f
+		kex->session_id = xmalloc(kex->session_id_len);
Jakub Jelen 72514f
+		memcpy(kex->session_id, hash, kex->session_id_len);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	gssbuf.value = hash;
Jakub Jelen 72514f
+	gssbuf.length = hashlen;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok))))
Jakub Jelen 72514f
+		fatal("Couldn't get MIC");
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
Jakub Jelen 72514f
+	{
Jakub Jelen 72514f
+		const u_char *ptr;
Jakub Jelen 72514f
+		size_t len;
Jakub Jelen 72514f
+		sshbuf_get_string_direct(Q_S, &ptr, &len;;
Jakub Jelen 72514f
+		packet_put_string(ptr, len);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+	packet_put_string(msg_tok.value, msg_tok.length);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (send_tok.length != 0) {
Jakub Jelen 72514f
+		packet_put_char(1); /* true */
Jakub Jelen 72514f
+		packet_put_string(send_tok.value, send_tok.length);
Jakub Jelen 72514f
+	} else {
Jakub Jelen 72514f
+		packet_put_char(0); /* false */
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+	packet_send();
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	gss_release_buffer(&min_status, &send_tok);
Jakub Jelen 72514f
+	gss_release_buffer(&min_status, &msg_tok);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	if (gss_kex_context == NULL)
Jakub Jelen 72514f
+		gss_kex_context = ctxt;
Jakub Jelen 72514f
+	else
Jakub Jelen 72514f
+		ssh_gssapi_delete_ctx(&ctxt);
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* Finally derive the keys and send them */
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) != 0)
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		if ((r = kex_derive_keys(ssh, hash, hashlen, c25519_shared_secret)) != 0)
Jakub Jelen 72514f
+			goto out;
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	default:
Jakub Jelen 72514f
+		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+	if ((r = kex_send_newkeys(ssh)) != 0)
Jakub Jelen 72514f
+		goto out;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	/* If this was a rekey, then save out any delegated credentials we
Jakub Jelen 72514f
+	 * just exchanged.  */
Jakub Jelen 72514f
+	if (options.gss_store_rekey)
Jakub Jelen 72514f
+		ssh_gssapi_rekey_creds();
Jakub Jelen 72514f
+out:
Jakub Jelen 72514f
+	explicit_bzero(hash, sizeof(hash));
Jakub Jelen 72514f
+	if (Q_S)
Jakub Jelen 72514f
+		sshbuf_free(Q_S);
Jakub Jelen 72514f
+	if (client_pub)
Jakub Jelen 72514f
+		free(client_pub);
Jakub Jelen 72514f
+	switch (kex->kex_type) {
Jakub Jelen 72514f
+	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
+		if (server_key)
Jakub Jelen 72514f
+			EC_KEY_free(server_key);
Jakub Jelen 72514f
+		if (kbuf) {
Jakub Jelen 72514f
+			explicit_bzero(kbuf, klen);
Jakub Jelen 72514f
+			free(kbuf);
Jakub Jelen 72514f
+		}
Jakub Jelen 72514f
+		if (shared_secret)
Jakub Jelen 72514f
+			BN_clear_free(shared_secret);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
+		explicit_bzero(c25519_server_key, sizeof(c25519_server_key));
Jakub Jelen 72514f
+		sshbuf_free(c25519_shared_secret);
Jakub Jelen 72514f
+		break;
Jakub Jelen 72514f
+	}
Jakub Jelen 72514f
+	return r;
Jakub Jelen 72514f
+}
Jakub Jelen 72514f
 #endif /* GSSAPI */
Jakub Jelen 72514f
diff --git a/monitor.c b/monitor.c
Jakub Jelen 72514f
index d6bc7ac7..b11616c8 100644
Jakub Jelen 72514f
--- a/monitor.c
Jakub Jelen 72514f
+++ b/monitor.c
Jakub Jelen 72514f
@@ -1651,6 +1651,8 @@ monitor_apply_keystate(struct monitor *pmonitor)
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_server;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
 		kex->load_host_public_key=&get_hostkey_public_by_type;
Jakub Jelen 72514f
@@ -1867,7 +1869,8 @@ mm_answer_gss_sign(int socket, Buffer *m)
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 	data.value = buffer_get_string(m, &len;;
Jakub Jelen 72514f
 	data.length = len;
Jakub Jelen 72514f
-	if (data.length != 20) 
Jakub Jelen 72514f
+	/* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */
Jakub Jelen 72514f
+	if (data.length != 20 && data.length != 32 && data.length != 64)
Jakub Jelen 72514f
 		fatal("%s: data length incorrect: %d", __func__, 
Jakub Jelen 72514f
 		    (int) data.length);
Jakub Jelen 72514f
 
Jakub Jelen 72514f
diff --git a/regress/kextype.sh b/regress/kextype.sh
Jakub Jelen 72514f
index 45f4f16d..d5b4a713 100644
Jakub Jelen 72514f
--- a/regress/kextype.sh
Jakub Jelen 72514f
+++ b/regress/kextype.sh
Jakub Jelen 72514f
@@ -15,6 +15,7 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy
Jakub Jelen 72514f
 tries="1 2 3 4"
Jakub Jelen 72514f
 for k in `${SSH} -Q kex`; do
Jakub Jelen 72514f
 	if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
+	    $k = "gss-nistp256-sha256-" -o $k = "gss-curve25519-sha256-" -o \
Jakub Jelen 72514f
 	    $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
 	    $k = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
 		continue
Jakub Jelen 72514f
diff --git a/regress/rekey.sh b/regress/rekey.sh
Jakub Jelen 72514f
index a2921bef..b118c6c8 100644
Jakub Jelen 72514f
--- a/regress/rekey.sh
Jakub Jelen 72514f
+++ b/regress/rekey.sh
Jakub Jelen 72514f
@@ -39,6 +39,7 @@ increase_datafile_size 300
Jakub Jelen 72514f
 opts=""
Jakub Jelen 72514f
 for i in `${SSH} -Q kex`; do
Jakub Jelen 72514f
 	if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
+	    $i = "gss-nistp256-sha256-" -o $i = "gss-curve25519-sha256-" -o \
Jakub Jelen 72514f
 	    $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
 	    $i = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
 		continue
Jakub Jelen 72514f
@@ -62,6 +63,7 @@ if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then
Jakub Jelen 72514f
   for c in `${SSH} -Q cipher-auth`; do
Jakub Jelen 72514f
     for kex in `${SSH} -Q kex`; do
Jakub Jelen 72514f
 	if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
+	    $kex = "gss-nistp256-sha256-" -o $kex = "gss-curve25519-sha256-" -o \
Jakub Jelen 72514f
 	    $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
 	    $kex = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
 		continue
Jakub Jelen 72514f
diff --git a/ssh-gss.h b/ssh-gss.h
Jakub Jelen 72514f
index 7bf8d75e..1f73721d 100644
Jakub Jelen 72514f
--- a/ssh-gss.h
Jakub Jelen 72514f
+++ b/ssh-gss.h
Jakub Jelen 72514f
@@ -73,6 +73,8 @@
Jakub Jelen 72514f
 #define KEX_GSS_GRP14_SHA256_ID			"gss-group14-sha256-"
Jakub Jelen 72514f
 #define KEX_GSS_GRP16_SHA512_ID			"gss-group16-sha512-"
Jakub Jelen 72514f
 #define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
Jakub Jelen 72514f
+#define KEX_GSS_NISTP256_SHA256_ID			"gss-nistp256-sha256-"
Jakub Jelen 72514f
+#define KEX_GSS_C25519_SHA256_ID			"gss-curve25519-sha256-"
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 #define        GSS_KEX_DEFAULT_KEX \
Jakub Jelen 72514f
 	KEX_GSS_GEX_SHA1_ID "," \
Jakub Jelen 72514f
diff --git a/ssh_config.5 b/ssh_config.5
Jakub Jelen 72514f
index 3d6da510..1dc29bf1 100644
Jakub Jelen 72514f
--- a/ssh_config.5
Jakub Jelen 72514f
+++ b/ssh_config.5
Jakub Jelen 72514f
@@ -762,7 +762,9 @@ gss-gex-sha1-,
Jakub Jelen 72514f
 gss-group1-sha1-,
Jakub Jelen 72514f
 gss-group14-sha1-,
Jakub Jelen 72514f
 gss-group14-sha256-,
Jakub Jelen 72514f
-gss-group16-sha512-
Jakub Jelen 72514f
+gss-group16-sha512-,
Jakub Jelen 72514f
+gss-nistp256-sha256-,
Jakub Jelen 72514f
+gss-curve25519-sha256-
Jakub Jelen 72514f
 .Ed
Jakub Jelen 72514f
 .Pp
Jakub Jelen 72514f
 The default is
Jakub Jelen 72514f
diff --git a/sshconnect2.c b/sshconnect2.c
Jakub Jelen 72514f
index 5d6b8be0..280ae5a6 100644
Jakub Jelen 72514f
--- a/sshconnect2.c
Jakub Jelen 72514f
+++ b/sshconnect2.c
Jakub Jelen 72514f
@@ -256,6 +256,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_client;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_client;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_client;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_client;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
 	kex->kex[KEX_C25519_SHA256] = kexc25519_client;
Jakub Jelen 72514f
diff --git a/sshd.c b/sshd.c
Jakub Jelen 72514f
index e4c879a2..a35735d8 100644
Jakub Jelen 72514f
--- a/sshd.c
Jakub Jelen 72514f
+++ b/sshd.c
Jakub Jelen 72514f
@@ -2247,6 +2247,8 @@ do_ssh2_kex(void)
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
Jakub Jelen 72514f
 		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_NISTP256_SHA256] = kexecgss_server;
Jakub Jelen 72514f
+		kex->kex[KEX_GSS_C25519_SHA256] = kexecgss_server;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
 #endif
Jakub Jelen 72514f
 	kex->server = 1;
Jakub Jelen 72514f
diff --git a/sshd_config.5 b/sshd_config.5
Jakub Jelen 72514f
index 0793418b..888316bf 100644
Jakub Jelen 72514f
--- a/sshd_config.5
Jakub Jelen 72514f
+++ b/sshd_config.5
Jakub Jelen 72514f
@@ -677,7 +677,9 @@ gss-gex-sha1-,
Jakub Jelen 72514f
 gss-group1-sha1-,
Jakub Jelen 72514f
 gss-group14-sha1-,
Jakub Jelen 72514f
 gss-group14-sha256-,
Jakub Jelen 72514f
-gss-group16-sha512-
Jakub Jelen 72514f
+gss-group16-sha512-,
Jakub Jelen 72514f
+gss-nistp256-sha256-,
Jakub Jelen 72514f
+gss-curve25519-sha256-
Jakub Jelen 72514f
 .Ed
Jakub Jelen 72514f
 .Pp
Jakub Jelen 72514f
 The default is
Jakub Jelen 72514f
-- 
Jakub Jelen 72514f
2.13.5
Jakub Jelen 72514f
Jakub Jelen 72514f
Jakub Jelen 72514f
From 0431695660d5eb1dd1169d42a1624c75a92aa5d2 Mon Sep 17 00:00:00 2001
Jakub Jelen 72514f
From: Jakub Jelen <jjelen@redhat.com>
Jakub Jelen 72514f
Date: Wed, 30 Aug 2017 15:30:51 +0200
Jakub Jelen 72514f
Subject: [PATCH 3/3] Simplify rough edges of GSSAPI Kex
Jakub Jelen 72514f
Jakub Jelen 72514f
---
Jakub Jelen 72514f
 gss-genr.c         | 53 +++++++++++++++++------------------------------------
Jakub Jelen 72514f
 regress/kextype.sh | 10 ++++------
Jakub Jelen 72514f
 regress/rekey.sh   | 20 ++++++++------------
Jakub Jelen 72514f
 3 files changed, 29 insertions(+), 54 deletions(-)
Jakub Jelen 72514f
Jakub Jelen 72514f
diff --git a/gss-genr.c b/gss-genr.c
Jakub Jelen 72514f
index 22040244..c671be31 100644
Jakub Jelen 72514f
--- a/gss-genr.c
Jakub Jelen 72514f
+++ b/gss-genr.c
Jakub Jelen 72514f
@@ -171,47 +171,28 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
Jakub Jelen 72514f
 gss_OID
Jakub Jelen 72514f
 ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
Jakub Jelen 72514f
 	int i = 0;
Jakub Jelen 72514f
-	
Jakub Jelen 72514f
-	switch (kex_type) {
Jakub Jelen 72514f
-	case KEX_GSS_GRP1_SHA1:
Jakub Jelen 72514f
-		if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID))
Jakub Jelen 72514f
-			return GSS_C_NO_OID;
Jakub Jelen 72514f
-		name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1;
Jakub Jelen 72514f
-		break;
Jakub Jelen 72514f
-	case KEX_GSS_GRP14_SHA1:
Jakub Jelen 72514f
-		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID))
Jakub Jelen 72514f
-			return GSS_C_NO_OID;
Jakub Jelen 72514f
-		name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
Jakub Jelen 72514f
-		break;
Jakub Jelen 72514f
-	case KEX_GSS_GRP14_SHA256:
Jakub Jelen 72514f
-		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA256_ID))
Jakub Jelen 72514f
-			return GSS_C_NO_OID;
Jakub Jelen 72514f
-		name += sizeof(KEX_GSS_GRP14_SHA256_ID) - 1;
Jakub Jelen 72514f
-		break;
Jakub Jelen 72514f
-	case KEX_GSS_GRP16_SHA512:
Jakub Jelen 72514f
-		if (strlen(name) < sizeof(KEX_GSS_GRP16_SHA512_ID))
Jakub Jelen 72514f
-			return GSS_C_NO_OID;
Jakub Jelen 72514f
-		name += sizeof(KEX_GSS_GRP16_SHA512_ID) - 1;
Jakub Jelen 72514f
-		break;
Jakub Jelen 72514f
-	case KEX_GSS_GEX_SHA1:
Jakub Jelen 72514f
-		if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID))
Jakub Jelen 72514f
-			return GSS_C_NO_OID;
Jakub Jelen 72514f
-		name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
Jakub Jelen 72514f
-		break;
Jakub Jelen 72514f
-	case KEX_GSS_NISTP256_SHA256:
Jakub Jelen 72514f
-		if (strlen(name) < sizeof(KEX_GSS_NISTP256_SHA256_ID))
Jakub Jelen 72514f
-			return GSS_C_NO_OID;
Jakub Jelen 72514f
-		name += sizeof(KEX_GSS_NISTP256_SHA256_ID) - 1;
Jakub Jelen 72514f
-		break;
Jakub Jelen 72514f
-	case KEX_GSS_C25519_SHA256:
Jakub Jelen 72514f
-		if (strlen(name) < sizeof(KEX_GSS_C25519_SHA256_ID))
Jakub Jelen 72514f
-			return GSS_C_NO_OID;
Jakub Jelen 72514f
-		name += sizeof(KEX_GSS_C25519_SHA256_ID) - 1;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+#define SKIP_KEX_NAME(type) \
Jakub Jelen 72514f
+	case type: \
Jakub Jelen 72514f
+		if (strlen(name) < sizeof(type##_ID)) \
Jakub Jelen 72514f
+			return GSS_C_NO_OID; \
Jakub Jelen 72514f
+		name += sizeof(type##_ID) - 1; \
Jakub Jelen 72514f
 		break;
Jakub Jelen 72514f
+
Jakub Jelen 72514f
+	switch (kex_type) {
Jakub Jelen 72514f
+	SKIP_KEX_NAME(KEX_GSS_GRP1_SHA1)
Jakub Jelen 72514f
+	SKIP_KEX_NAME(KEX_GSS_GRP14_SHA1)
Jakub Jelen 72514f
+	SKIP_KEX_NAME(KEX_GSS_GRP14_SHA256)
Jakub Jelen 72514f
+	SKIP_KEX_NAME(KEX_GSS_GRP16_SHA512)
Jakub Jelen 72514f
+	SKIP_KEX_NAME(KEX_GSS_GEX_SHA1)
Jakub Jelen 72514f
+	SKIP_KEX_NAME(KEX_GSS_NISTP256_SHA256)
Jakub Jelen 72514f
+	SKIP_KEX_NAME(KEX_GSS_C25519_SHA256)
Jakub Jelen 72514f
 	default:
Jakub Jelen 72514f
 		return GSS_C_NO_OID;
Jakub Jelen 72514f
 	}
Jakub Jelen 72514f
 
Jakub Jelen 72514f
+#undef SKIP_KEX_NAME
Jakub Jelen 72514f
+
Jakub Jelen 72514f
 	while (gss_enc2oid[i].encoded != NULL &&
Jakub Jelen 72514f
 	    strcmp(name, gss_enc2oid[i].encoded) != 0)
Jakub Jelen 72514f
 		i++;
Jakub Jelen 72514f
diff --git a/regress/kextype.sh b/regress/kextype.sh
Jakub Jelen 72514f
index d5b4a713..6b4af28a 100644
Jakub Jelen 72514f
--- a/regress/kextype.sh
Jakub Jelen 72514f
+++ b/regress/kextype.sh
Jakub Jelen 72514f
@@ -14,12 +14,10 @@ echo "KexAlgorithms=$KEXOPT" >> $OBJ/sshd_proxy
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 tries="1 2 3 4"
Jakub Jelen 72514f
 for k in `${SSH} -Q kex`; do
Jakub Jelen 72514f
-	if [ $k = "gss-gex-sha1-" -o $k = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
-	    $k = "gss-nistp256-sha256-" -o $k = "gss-curve25519-sha256-" -o \
Jakub Jelen 72514f
-	    $k = "gss-group14-sha1-" -o $k = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
-	    $k = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
-		continue
Jakub Jelen 72514f
-	fi
Jakub Jelen 72514f
+	# ignore GSSAPI key exchange mechanisms (all of them start with gss-)
Jakub Jelen 72514f
+	case $k in
Jakub Jelen 72514f
+		gss-* ) continue ;;
Jakub Jelen 72514f
+	esac
Jakub Jelen 72514f
 	verbose "kex $k"
Jakub Jelen 72514f
 	for i in $tries; do
Jakub Jelen 72514f
 		${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true
Jakub Jelen 72514f
diff --git a/regress/rekey.sh b/regress/rekey.sh
Jakub Jelen 72514f
index b118c6c8..d6a8742f 100644
Jakub Jelen 72514f
--- a/regress/rekey.sh
Jakub Jelen 72514f
+++ b/regress/rekey.sh
Jakub Jelen 72514f
@@ -38,12 +38,10 @@ increase_datafile_size 300
Jakub Jelen 72514f
 
Jakub Jelen 72514f
 opts=""
Jakub Jelen 72514f
 for i in `${SSH} -Q kex`; do
Jakub Jelen 72514f
-	if [ $i = "gss-gex-sha1-" -o $i = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
-	    $i = "gss-nistp256-sha256-" -o $i = "gss-curve25519-sha256-" -o \
Jakub Jelen 72514f
-	    $i = "gss-group14-sha1-" -o $i = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
-	    $i = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
-		continue
Jakub Jelen 72514f
-	fi
Jakub Jelen 72514f
+	# ignore GSSAPI key exchange mechanisms (all of them start with gss-)
Jakub Jelen 72514f
+	case $i in
Jakub Jelen 72514f
+		gss-* ) continue ;;
Jakub Jelen 72514f
+	esac
Jakub Jelen 72514f
 	opts="$opts KexAlgorithms=$i"
Jakub Jelen 72514f
 done
Jakub Jelen 72514f
 for i in `${SSH} -Q cipher`; do
Jakub Jelen 72514f
@@ -62,12 +60,10 @@ done
Jakub Jelen 72514f
 if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then
Jakub Jelen 72514f
   for c in `${SSH} -Q cipher-auth`; do
Jakub Jelen 72514f
     for kex in `${SSH} -Q kex`; do
Jakub Jelen 72514f
-	if [ $kex = "gss-gex-sha1-" -o $kex = "gss-group1-sha1-" -o \
Jakub Jelen 72514f
-	    $kex = "gss-nistp256-sha256-" -o $kex = "gss-curve25519-sha256-" -o \
Jakub Jelen 72514f
-	    $kex = "gss-group14-sha1-" -o $kex = "gss-group14-sha256-" -o \
Jakub Jelen 72514f
-	    $kex = "gss-group16-sha512-" ]; then
Jakub Jelen 72514f
-		continue
Jakub Jelen 72514f
-	fi
Jakub Jelen 72514f
+	# ignore GSSAPI key exchange mechanisms (all of them start with gss-)
Jakub Jelen 72514f
+	case $kex in
Jakub Jelen 72514f
+		gss-* ) continue ;;
Jakub Jelen 72514f
+	esac
Jakub Jelen 72514f
 	verbose "client rekey $c $kex"
Jakub Jelen 72514f
 	ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c
Jakub Jelen 72514f
     done
Jakub Jelen 72514f
-- 
Jakub Jelen 72514f
2.13.5
Jakub Jelen 72514f