Skip to content

GSSAPI KEX#856

Open
elric1 wants to merge 4 commits into
PowerShell:latestw_allfrom
chapeltech:gssapi-kex
Open

GSSAPI KEX#856
elric1 wants to merge 4 commits into
PowerShell:latestw_allfrom
chapeltech:gssapi-kex

Conversation

@elric1

@elric1 elric1 commented Jun 22, 2026

Copy link
Copy Markdown

PR Summary

Add GSSAPI KEX.

PR Context

In an environment which uses GSS, this patch will use GSS to authenticate the remote server which eliminates the need to use SSH host keys.

GSS KEX is defined by RFC 4462.

The base GSSAPI key exchange implementation comes from Simon Wilkinson's patch, carried and maintained by Debian for OpenSSH. We add the Windows build and SSPI shim adaptations needed.

Fixes 15..

SimonWilkinson and others added 2 commits June 19, 2026 10:43
This patch has been rejected upstream: "None of the OpenSSH developers are
in favour of adding this, and this situation has not changed for several
years.  This is not a slight on Simon's patch, which is of fine quality, but
just that a) we don't trust GSSAPI implementations that much and b) we don't
like adding new KEX since they are pre-auth attack surface.  This one is
particularly scary, since it requires hooks out to typically root-owned
system resources."

However, quite a lot of people rely on this in Debian, and it's better to
have it merged into the main openssh package rather than having separate
-krb5 packages (as we used to have).  It seems to have a generally good
security history.

Author: Simon Wilkinson <simon@sxw.org.uk>
Author: Colin Watson <cjwatson@debian.org>
Author: Jakub Jelen <jjelen@redhat.com>
Origin: other, openssh-gsskex/openssh-gsskex#23
Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242
Last-Updated: 2026-03-27

Patch-Name: gssapi.patch
Copilot AI review requested due to automatic review settings June 22, 2026 14:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds RFC 4462 GSSAPI-based key exchange (GSS KEX) support to OpenSSH portable, including a “null” hostkey algorithm to allow server authentication via GSSAPI without requiring traditional SSH host keys, plus the required configuration/options, monitor/privsep plumbing, and Windows/SSPI shim updates.

Changes:

  • Implement GSSAPI key exchange (client + server) and wire it into kex negotiation, proposals, and rekey credential updates.
  • Introduce a null hostkey algorithm (KEY_NULL) and adjust hostkey handling to support hostkey-less operation when GSS KEX is enabled.
  • Add client/server config options + manpage documentation, and update build systems (Makefile + Win32 .vcxproj) to compile the new sources.

Reviewed changes

Copilot reviewed 51 out of 51 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
sshkey.h Add KEY_NULL key type for the “null” hostkey algorithm.
sshkey.c Register sshkey_null_impl; hide null from key algorithm listings.
sshd.c Allow starting sshd without hostkeys when GSSAPIKeyExchange is enabled.
sshd-session.c Don’t fatal when no hostkeys exist (needed for hostkey-less GSS KEX).
sshd-auth.c Server-side proposal/kex wiring for GSS KEX and null hostkey mode.
sshd_config.5 Document GSSAPIKeyExchange, GSSAPIStoreCredentialsOnRekey, GSSAPIKexAlgorithms.
sshd_config Add commented example lines for new GSS-related sshd options.
sshconnect2.c Client-side proposal/kex wiring for GSS KEX and null hostkey fallback.
ssh.c Add ssh -Q kex-gss query support.
ssh.1 Document kex-gss query and new GSS-related ssh options in the option index.
ssh-null.c Implement “null” sshkey backend for the null hostkey algorithm.
ssh-gss.h Add GSS KEX constants, defaults, and new GSS helper prototypes/state.
ssh_config.5 Document client-side GSSAPIKeyExchange and related options.
ssh_config Add commented example lines for new GSS-related ssh client options.
session.c Run Kerberos/GSS credential cleanup under the authenticated user’s UID.
servconf.h Add server options: gss_keyex, gss_store_rekey, gss_kex_algorithms.
servconf.c Parse/dump new server options and set defaults (incl. default GSS KEX list).
readconf.h Add client options: gss_keyex, trust-dns, renewal-rekey, identities, kex alg list.
readconf.c Parse/dump new client options and set defaults (incl. default GSS KEX list).
monitor.h Add monitor request/answer IDs for GSS signing and credential update.
monitor.c Permit and implement GSS signing + credential update requests across privsep.
monitor_wrap.h Extend monitor wrapper APIs for GSS userok/sign/updatecreds.
monitor_wrap.c Implement wrapper calls for GSS sign/updatecreds; extend gss userok args.
Makefile.in Build/link new objects: ssh-null.o, kexgssc.o, kexgsss.o.
kexgsss.c Add server-side GSS KEX implementations (DH/ECDH/C25519 + GEX variants).
kexgssc.c Add client-side GSS KEX implementations (DH/ECDH/C25519 + GEX variants).
kexgen.c Export kex_gen_hash() for reuse by GSS KEX implementations.
kexdh.c Allow DH group selection for GSS KEX DH-based variants.
kex.h Add GSS KEX enum values, kex->gss* fields, and new GSS kex helper prototypes.
kex.c Free kex->gss_host during kex teardown.
kex-names.c Add GSS KEX algorithm list + validation helpers and a kex_gss_alg_list() API.
gss-serv.c Add server-side GSS KEX mechanism advertising/checking and rekey cred plumbing.
gss-serv-krb5.c Add/update Kerberos ccache storage and implement credential update on rekey.
gss-genr.c Add client mechanism enumeration/encoding for GSS KEX, OID mapping, renew detection.
contrib/win32/win32compat/inc/gssapi.h Extend SSPI shim API surface for new GSS calls/types.
contrib/win32/win32compat/gss-sspi.c Implement SSPI shims for name compare and cred inquiry; improve lifetime handling.
contrib/win32/openssh/sshd.vcxproj.filters Adjust Win32 project filters (source list changes).
contrib/win32/openssh/sshd.vcxproj Update Win32 sshd project compilation units (remove gss-serv sources here).
contrib/win32/openssh/sshd-session.vcxproj.filters Add kexgsss.c to sshd-session project filters.
contrib/win32/openssh/sshd-session.vcxproj Compile kexgsss.c in sshd-session Win32 project.
contrib/win32/openssh/sshd-auth.vcxproj.filters Add kexgsss.c to sshd-auth project filters.
contrib/win32/openssh/sshd-auth.vcxproj Compile kexgsss.c in sshd-auth Win32 project.
contrib/win32/openssh/libssh.vcxproj.filters Add kexgssc.c and ssh-null.c to libssh project filters.
contrib/win32/openssh/libssh.vcxproj Compile kexgssc.c and ssh-null.c in libssh Win32 project.
configure.ac Add Apple Security Session / CCAPI detection (for credential cache handling).
clientloop.c Force rekey when credentials renew (if configured) outside of active rekeying.
auth2.c Register gssapi-keyex auth method on the server.
auth2-methods.c Add gssapi-keyex method configuration wiring.
auth2-gss.c Implement server-side gssapi-keyex userauth method and adjust gss userok calls.
auth.c Permit root login via gssapi-keyex when configured similarly to other strong methods.
README.md Add a GSS KEX-focused header section ahead of the upstream README content.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sshd-auth.c
Comment on lines +883 to +889
if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";

if (newstr)
myproposal[PROPOSAL_KEX_ALGS] = newstr;
else
fatal("No supported key exchange algorithms");
Comment thread sshconnect2.c
Comment on lines +289 to +301
gss = ssh_gssapi_client_mechanisms(gss_host,
options.gss_client_identity, options.gss_kex_algorithms);
if (gss) {
debug("Offering GSSAPI proposal: %s", gss);
xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
"%s,%s", gss, orig);

/* If we've got GSSAPI algorithms, then we also support the
* 'null' hostkey, as a last resort */
orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
"%s,null", orig);
}
Comment thread kexgssc.c
Comment on lines +248 to +252
case KEX_GSS_C25519_SHA256:
if (sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] & 0x80)
fatal("The received key has MSB of last octet set!");
r = kex_c25519_dec(kex, server_blob, &shared_secret);
break;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw this, but I am preparing a patch for upstream which we can then bring over to this repo. So, in short: this is not the correct place to fix this, it should be fixed upstream and then the pulled over.

Comment thread kexgsss.c
Comment on lines +74 to +82
struct sshbuf *empty = sshbuf_new();
int type = 0;
gss_OID oid;
char *mechs;
u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t hashlen;
int r;

/* Initialise GSSAPI */
Comment thread kexgsss.c
Comment on lines +277 to +280
struct sshbuf *empty = sshbuf_new();
int r;

/* Initialise GSSAPI */
Comment thread sshd_config.5
Comment on lines +762 to +764
Controls whether the user's GSSAPI credentials should be updated following a
successful connection rekeying. This option can be used to accepted renewed
or updated credentials from a compatible client. The default is

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this is a minor suggestion to an upstream patch which should be fixed upstream.

@elric1

elric1 commented Jun 22, 2026

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree company="The Old Chapel Technology, Ltd"

elric1 added 2 commits June 24, 2026 15:41
The GSS Curve25519 client path checked
sshbuf_ptr(server_blob)[sshbuf_len(server_blob)] when rejecting public
keys with the high bit set. That indexes one byte past the end of the
sshbuf payload.

The byte after Q_S is the first byte of the following MIC string length,
encoded in network byte order. With OpenSSH's packet size limit this
byte is normally zero, so the bug usually made the intended high-bit
rejection a no-op rather than causing random failures.

A peer can send a high-bit-set Q_S, but it still has to produce the
GSS MIC over the exchange hash for the exact values used. This does
not appear to provide key compromise or authentication bypass; it is a
correctness fix for the validation policy carried by the GSS KEX patch.

Reject an empty server blob explicitly, then test the last payload byte at
sshbuf_len(server_blob) - 1 before passing the blob to kex_c25519_dec().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for GSSAPIKeyExchange

3 participants