Skip to content

x/crypto/ssh: add a specific error for algorithm negotiation issues/errors #61536

Open
@drakkan

Description

@drakkan

A common requirement for applications using x/crypto/ssh is to report some errors differently than others.
We currently have ServerAuthError and ErrNoAuth which are useful for authentication related errors.

If the client and the server cannot negotiate a common algorithm for host key, KEX, cipher, MAC we have a generic error and can only search for the error string.
New algorithms are added over time and old algorithms are deprecated and disabled by default, so a well defined error allows applications using the library to better report errors to end users and allow them to fix the issue (e.g by enabling an old algorithm).

An algorithm negotiation error is typically returned in the findCommon method, but the same error should also be returned in other places, for example if pickHostKey fails or in enterKeyExchange so searching for an error string is quite fragile.

We can add something very simple like this

// ErrAlgorithmNegotiation is the error returned if the client and the server cannot agree
// on an algorithm for host key, KEX, cipher, MAC or if an unsupported algorithm 
// is configured.
var ErrAlgorithmNegotiation = errors.New("ssh: algorithm negotiation error")

and wrap this error when needed, for example in findCommon we could use

return "", fmt.Errorf("%w: ssh: no common algorithm for %s; client offered: %v, server offered: %v", ErrAlgorithm, what, client, server)

instead of

return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server)

and the same in other places where there is an algorithm error.

If you see CL 508398, this error may also be returned if NewSignerWithAlgorithms fails for example.

We could also evaluate something more complex, such as an error structure with an exported error code for each error category.
This way we could, for example, have specific error codes for MAC, KEX or cipher negotiation errors, I'm not sure if it's worth the effort to implement and maintain, but if you prefer this approach I can try to propose an API for that as well.

cc @golang/security

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Accepted

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions