Skip to content

Validate ECC curve in user auth, document auth callback contracts - #1141

Open
ejohnstown wants to merge 4 commits into
wolfSSL:masterfrom
ejohnstown:sf15
Open

Validate ECC curve in user auth, document auth callback contracts#1141
ejohnstown wants to merge 4 commits into
wolfSSL:masterfrom
ejohnstown:sf15

Conversation

@ejohnstown

Copy link
Copy Markdown
Contributor
  • ssh.h: document the WS_CallbackUserAuth contract (F-6815) -- WOLFSSH_USERAUTH_SUCCESS is 0, so a stub returning 0 authenticates everyone. Say the callback must fail closed, and that publickey auth requires it to check the key against the user's authorized keys.
  • ssh.h: document the WS_CallbackPublicKeyCheck contract (F-6976) -- 0 accepts the host key, so a "return 0" stub trusts any server. Require a trust store check, point at ClientPublicKeyCheck(), note that no callback means WS_PUBKEY_REJECTED_E.
  • internal: validate the ECC curve name in user auth (F-6979) -- DoUserAuthRequestEcc() skipped the blob's curve name and let wc_ecc_import_x963() infer the curve from the point length, so the key need not be on the curve the algorithm names. Pin the import to the curve from pk->publicKeyType and require the name to match. Also scope the import's error check so parse errors keep their own codes. Adds test_EccUserAuthCurveMismatch.
  • tests: add test_ByteHighwater (F-6978) -- Covers the byte-count branch of HighwaterCheck(): the mark boundary, the once-per-epoch flag, the receive side, and a mark of 0.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This pull request tightens authentication safety and clarifies callback contracts in wolfSSH, specifically addressing ECC public key algorithm/curve binding during user authentication and documenting “fail-closed” expectations for authentication-related callbacks.

Changes:

  • Documented WS_CallbackUserAuth and WS_CallbackPublicKeyCheck contracts to prevent insecure “return 0” stubs from silently accepting users/host keys.
  • Hardened ECDSA publickey userauth parsing by requiring the curve name inside the key blob to match the declared algorithm and by importing points pinned to the declared curve.
  • Added unit tests covering the byte-count highwater rekey trigger and ECC curve-mismatch userauth cases.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
wolfssh/ssh.h Adds explicit, security-focused callback contract documentation to prevent fail-open stubs (userauth + host key verification).
src/internal.c Binds ECDSA userauth curve name and point import to the declared algorithm/curve to prevent curve-mismatch acceptance.
tests/unit.c Adds unit coverage for byte-based highwater behavior and for ECC userauth curve/name/point mismatch rejection.

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

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot 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.

Fenrir Automated Review — PR #1141

Scan targets checked: wolfssh-bugs, wolfssh-src

No new issues found in the changed files. ✅

- WOLFSSH_USERAUTH_SUCCESS is 0, the same value as WS_SUCCESS and the
  C "no error" idiom, so a bare "return 0", a forwarded WS_SUCCESS, or
  a fall-through default of 0 silently authenticates the client.
- Spell out that the callback must fail closed: return
  WOLFSSH_USERAUTH_FAILURE for any authType or code path it does not
  explicitly handle.
- Note that for WOLFSSH_USERAUTH_PUBLICKEY the library verifies the
  signature but not the key's authorization, so the callback has to
  check the offered key against the user's authorized keys.

Issue: F-6815
- The callback is the client's only defense against a man in the
  middle, and 0 accepts the server host key, so a stub that defaults
  to "return 0" trusts whatever key is presented.
- State that the callback must match the key against a trust store,
  and point at ClientPublicKeyCheck() in the examples.
- Record that with no callback registered the host key is rejected
  with WS_PUBKEY_REJECTED_E.

Issue: F-6976
- DoUserAuthRequestEcc() skipped the curve name in the public key blob
  and imported the point with wc_ecc_import_x963(), which picks the
  curve from the point length, so the key did not have to be on the
  curve the declared algorithm names.
- Derive the curve from pk->publicKeyType with NameToId() and
  wcPrimeForId(), require the blob's curve name to equal
  PrimeNameForId() for that id, and import with
  wc_ecc_import_x963_ex() pinned to that curve.
- The import's error check sat outside the success guard, so it
  rewrote any earlier error as WS_CRYPTO_FAILED. Scope it to the
  import itself so the parse and algorithm-match errors keep their
  own codes.
- Add test_EccUserAuthCurveMismatch, which offers a blob naming one
  curve under another algorithm and expects the request to fail.

Issue: F-6979
- The byte-count branch of HighwaterCheck() had no coverage. Exercise
  the boundary at the mark, the once-per-epoch flag that keeps the
  callback from firing a second time, the receive side, and a mark of
  0 disabling the check.

Issue: F-6978
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.

3 participants