Repository navigation
pki: Fail sshsig_sign when no signature was produced - #19
Open
tiandiwonder wants to merge 1 commit into
Open
tiandiwonder wants to merge 1 commit into
tiandiwonder wants to merge 1 commit into
Conversation
`sshsig_sign` documents that it returns `SSH_OK` on success, and that on success the `signature` out parameter holds the allocated armored signature. Two paths break that contract. Both are reached after `rc` has been set to `SSH_OK` by `sshsig_prepare_data`, and both jump to the shared `cleanup` label without resetting it, so the single `return rc` reports success while `signature` is still the `NULL` it was initialised to: - the `#else` of `#ifdef WITH_FIDO2`, taken for an SK key type on a build without FIDO2 - `sig == NULL`, taken when the signing backend refused the key A caller that follows the documented contract and only checks the return code then dereferences `NULL`. This was found as a segfault in a consumer signing with a 1024-bit RSA key on an OpenSSL FIPS build, where the modulus is below the approved minimum, so `pki_sign_data` returns `NULL` and the second path reports success. Set `rc = SSH_ERROR` on both before `goto cleanup`, which is how the rest of the file already behaves: `ssh_pki_generate_key` returns `SSH_ERROR` directly from its equivalent `#else /* WITH_FIDO2 */` branch, and `sshsig_verify` assigns `rc = SSH_ERROR` before its own `goto cleanup`. The test signs with the public part of the fixture RSA key. `pki_sign_data` rejects a key without private material at its `!ssh_key_is_private(privkey)` guard and returns `NULL`, reaching the second path, so the defect reproduces without a FIPS build or FIDO2 hardware. Reverting only the `src/pki.c` change makes it fail with `0 != 0xffffffffffffffff`. The SK branch is not covered: that needs a build with FIDO2 where `pki_sk_do_sign` is unavailable, and the suite has no fixture for it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
sshsig_signdocuments a two-valued contract:Two paths break it. Both are reached after
rchas been set toSSH_OKbysshsig_prepare_data, and both jump to the sharedcleanuplabel without resetting it, so the singlereturn rcreports success whilesignatureis still theNULLit was initialised to:#elseof#ifdef WITH_FIDO2sig == NULLA caller that follows the documented contract and only checks the return code then dereferences
NULL.How it was found
A consumer segfaulted while signing with a 1024-bit RSA key on an OpenSSL FIPS build. The modulus is below the FIPS-approved minimum, so
pki_sign_datareturnedNULLand the second path reported success. The caller did exactly what the contract allows:Fix
Set
rc = SSH_ERRORon both paths beforegoto cleanup. This matches the rest of the file:ssh_pki_generate_keyreturnsSSH_ERRORdirectly from its equivalent#else /* WITH_FIDO2 */branch, andsshsig_verifyassignsrc = SSH_ERRORbefore its owngoto cleanup.Test
torture_sshsig_sign_error_leaves_no_signaturesigns with the public part of the fixture RSA key.pki_sign_datarejects a key without private material at its!ssh_key_is_private(privkey)guard and returnsNULL, which reaches thesig == NULLpath, so the defect reproduces with no FIPS build and no FIDO2 hardware.Verified both ways, built with
-DUNIT_TESTING=ON -DWITH_FIDO2=OFF:src/pki.creverted0 != 0xffffffffffffffffThe SK branch is not covered: it needs a build with FIDO2 where
pki_sk_do_signis unavailable, and the suite has no fixture for that. It is fixed because it is the same defect, in the same function, on the same variable.