Skip to content

Commit

Permalink
GH-445: OpenSSH "strict KEX" protocol extension
Browse files Browse the repository at this point in the history
Implements the OpenSSH "strict KEX" protocol extension.[1] If both
parties in a an SSH connection announce support for strict KEX in the
initial KEX_INIT message, strict KEX is active; otherwise it isn't.

With strict KEX active, there must be only KEX-related messages during
the initial key exchange (no IGNORE or DEBUG messages are allowed), and
the KEX_INIT message must be the first one to have been received after
the initial version exchange. If these conditions are violated, the
connection is terminated.

Strict KEX also resets message sequence numbers to zero after each
NEW_KEYS message sent or received.

[1] https://github.com/openssh/openssh-portable/blob/master/PROTOCOL
  • Loading branch information
tomaswolf committed Jan 5, 2024
1 parent 6f69e41 commit 6b0fd46
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 30 deletions.
11 changes: 11 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
## New Features

* [GH-429](https://github.com/apache/mina-sshd/issues/429) Support GIT protocol-v2
* [GH-445](https://github.com/apache/mina-sshd/issues/445) OpenSSH "strict key exchange" protocol extension ([CVE-2023-48795](https://nvd.nist.gov/vuln/detail/CVE-2023-48795) mitigation)

## Behavioral changes and enhancements

Expand All @@ -43,6 +44,16 @@ acknowledgements of a `receive` related command. The user is free to inspect the
to handle it - including even throwing an exception if OK status (if this makes sense for whatever reason). The default implementation checks for ERROR code and throws
an exception if so.

### OpenSSH protocol extension: strict key exchange

[GH-445](https://github.com/apache/mina-sshd/issues/445) implements an extension to the SSH protocol introduced
in OpenSSH 9.6. This ["strict key exchange" extension](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL)
hardens the SSH key exchange against the ["Terrapin attack"](https://www.terrapin-attack.com/)
([CVE-2023-48795](https://nvd.nist.gov/vuln/detail/CVE-2023-48795)). The extension is active if both parties
announce their support for it at the start of the initial key exchange. If only one party announces support,
it is not activated to ensure compatibility with SSH implementations that do not implement it. Apache MINA sshd
clients and servers always announce their support for strict key exchange.

## Potential compatibility issues

## Major Code Re-factoring
Expand Down
35 changes: 22 additions & 13 deletions docs/standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,32 @@
above mentioned hooks for [RFC 8308](https://tools.ietf.org/html/rfc8308).
* [RFC 8731 - Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448](https://tools.ietf.org/html/rfc8731)
* [Key Exchange (KEX) Method Updates and Recommendations for Secure Shell](https://tools.ietf.org/html/draft-ietf-curdle-ssh-kex-sha2-03)

### OpenSSH

* [OpenSSH support for U2F/FIDO security keys](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.u2f)
* **Note:** the server side supports these keys by default. The client side requires specific initialization
* [OpenSSH public-key certificate authentication system for use by SSH](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.certkeys)
* [OpenSSH strict key exchange extension](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL)

### SFTP version 3-6 + extensions

* `supported` - [DRAFT 05 - section 4.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-4.4)
* `supported2` - [DRAFT 13 section 5.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-5.4)
* `versions` - [DRAFT 09 Section 4.6](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-4.6)
* `vendor-id` - [DRAFT 09 - section 4.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-4.4)
* `acl-supported` - [DRAFT 11 - section 5.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-11#section-5.4)
* `newline` - [DRAFT 09 Section 4.3](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-4.3)
* `md5-hash`, `md5-hash-handle` - [DRAFT 09 - section 9.1.1](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-9.1.1)
* `check-file-handle`, `check-file-name` - [DRAFT 09 - section 9.1.2](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-9.1.2)
* `copy-file`, `copy-data` - [DRAFT 00 - sections 6, 7](https://tools.ietf.org/id/draft-ietf-secsh-filexfer-extensions-00.txt)
* `space-available` - [DRAFT 09 - section 9.2](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-9.2)
* `filename-charset`, `filename-translation-control` - [DRAFT 13 - section 6](https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-6) - only client side
* Several [OpenSSH SFTP extensions](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL)

### Miscellaneous

* [SSH proxy jumps](./internals.md#ssh-jumps)
* SFTP version 3-6 + extensions
* `supported` - [DRAFT 05 - section 4.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-4.4)
* `supported2` - [DRAFT 13 section 5.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-5.4)
* `versions` - [DRAFT 09 Section 4.6](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-4.6)
* `vendor-id` - [DRAFT 09 - section 4.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-4.4)
* `acl-supported` - [DRAFT 11 - section 5.4](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-11#section-5.4)
* `newline` - [DRAFT 09 Section 4.3](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-4.3)
* `md5-hash`, `md5-hash-handle` - [DRAFT 09 - section 9.1.1](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-9.1.1)
* `check-file-handle`, `check-file-name` - [DRAFT 09 - section 9.1.2](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-9.1.2)
* `copy-file`, `copy-data` - [DRAFT 00 - sections 6, 7](https://tools.ietf.org/id/draft-ietf-secsh-filexfer-extensions-00.txt)
* `space-available` - [DRAFT 09 - section 9.2](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-9.2)
* `filename-charset`, `filename-translation-control` - [DRAFT 13 - section 6](https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-6) - only client side
* Several [OpenSSH SFTP extensions](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL)
* [Endless tarpit](https://nullprogram.com/blog/2019/03/22/) - see [HOWTO(s)](./howto.md) section.

## Implemented/available support
Expand Down
15 changes: 15 additions & 0 deletions docs/technical/kex.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,18 @@ thread is not overrun by producers and actually can finish.
Again, "client" and "server" could also be inverted. For instance, a client uploading
files via SFTP might have an application thread pumping data through a channel, which
might be blocked during KEX.

### Strict Key Exchange

"Strict KEX" is an SSH protocol extension introduced in 2023 to harden the protocol against
a particular form of attack. For details, see ["Terrapin attack"](https://www.terrapin-attack.com/)
and [CVE-2023-48795](https://nvd.nist.gov/vuln/detail/CVE-2023-48795). The "strict KEX"
counter-measures are active if both peers indicate support for it at the start of the initial
key exchange. By default, Apache MINA sshd always supports "strict kex" and advertises it, and
thus it will always be active if the other party also supports it.

If for whatever reason you want to disable using "strict KEX", this can be achieved by setting
a custom session factory on the `SshClient` or `SshServer`. This custom session factory would create
custom sessions subclassed from `ClientSessionImpl`or `ServerSessionImpl` that do not do anything
in method `doStrictKexProposal()` (just return the proposal unchanged).

Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,23 @@ public final class KexExtensions {
public static final String CLIENT_KEX_EXTENSION = "ext-info-c";
public static final String SERVER_KEX_EXTENSION = "ext-info-s";

@SuppressWarnings("checkstyle:Indentation")
public static final Predicate<String> IS_KEX_EXTENSION_SIGNAL
= n -> CLIENT_KEX_EXTENSION.equalsIgnoreCase(n) || SERVER_KEX_EXTENSION.equalsIgnoreCase(n);
public static final Predicate<String> IS_KEX_EXTENSION_SIGNAL = //
n -> CLIENT_KEX_EXTENSION.equalsIgnoreCase(n) || SERVER_KEX_EXTENSION.equalsIgnoreCase(n);

/**
* Reminder:
*
* These pseudo-algorithms are only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored if they are present in
* subsequent SSH2_MSG_KEXINIT packets.
*
* <B>Note:</B> these values are <U>appended</U> to the initial proposals and removed if received before proceeding
* with the standard KEX proposals negotiation.
*
* @see <A HREF="https://github.com/openssh/openssh-portable/blob/master/PROTOCOL">OpenSSH PROTOCOL - 1.9 transport:
* strict key exchange extension</A>
*/
public static final String STRICT_KEX_CLIENT_EXTENSION = "[email protected]";
public static final String STRICT_KEX_SERVER_EXTENSION = "[email protected]";

/**
* A case <U>insensitive</U> map of all the default known {@link KexExtensionParser} where key=the extension name
Expand Down
Loading

0 comments on commit 6b0fd46

Please sign in to comment.