Skip to content

Add secure file I/O utilities, memory wiping, and tests - #278

Open
stenslae wants to merge 4 commits into
wolfSSL:mainfrom
stenslae:pr-secure-io
Open

Add secure file I/O utilities, memory wiping, and tests#278
stenslae wants to merge 4 commits into
wolfSSL:mainfrom
stenslae:pr-secure-io

Conversation

@stenslae

@stenslae stenslae commented Aug 5, 2026

Copy link
Copy Markdown
Member

Added helper functions to remove races in file ops, and refactored sites to call helper functions, and added test coverage. Also fixed CI for no_filesystem builds.

@stenslae stenslae self-assigned this Aug 5, 2026

@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 #278

Scan targets checked: wolfclu-bugs, wolfclu-src

No new issues found in the changed files. ✅

@stenslae
stenslae marked this pull request as ready for review August 5, 2026 22:39
@stenslae stenslae assigned wolfSSL-Bot and stenslae and unassigned stenslae and wolfSSL-Bot Aug 5, 2026
@stenslae
stenslae requested review from wolfSSL-Fenrir-bot and removed request for wolfSSL-Fenrir-bot August 6, 2026 17:05

@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 #278

Scan targets checked: wolfclu-bugs, wolfclu-src

Findings: 9
9 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread src/pkey/clu_rsa.c Outdated
Comment thread src/tools/clu_funcs.c Outdated
Comment thread src/tools/clu_funcs.c Outdated
Comment thread src/tools/clu_funcs.c Outdated
Comment thread tests/tools/tools_unit_test.c
Comment thread src/tools/clu_funcs.c
Comment thread src/tools/clu_funcs.c Outdated
Comment thread tests/tools/tools_unit_test.c
Comment thread tests/tools/tools_unit_test.c Outdated
Comment thread src/pkey/clu_rsa.c Outdated
Comment thread src/tools/clu_funcs.c Outdated
Comment thread src/tools/clu_funcs.c Outdated
Comment thread src/tools/clu_funcs.c Outdated
Comment thread tests/tools/tools_unit_test.c
Comment thread src/tools/clu_funcs.c
Comment thread src/tools/clu_funcs.c Outdated
Comment thread tests/tools/tools_unit_test.c
Comment thread tests/tools/tools_unit_test.c Outdated

@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 #278

Scan targets checked: wolfclu-bugs, wolfclu-src
Findings: 6
5 finding(s) posted as inline comments (see file-level comments below)

Critical (1)

Unbalanced #endif in clu_sign.c breaks every build

File: src/sign-verify/clu_sign.c:1244
Function: file scope
Category: Incorrect macro expansion

The PR deleted the file's opening #ifndef WOLFCLU_NO_FILESYSTEM (replacing it with the WOLFCLU_MAX_FILE_SIZE define) but left the closing #endif at line 1244. WOLFCLU_NO_FILESYSTEM appears nowhere else in the file, and the 18 #if* directives are matched by 19 #endifs, so the preprocessor errors with "#endif without #if" in all configurations.

Recommendation: Restore #ifndef WOLFCLU_NO_FILESYSTEM after the WOLFCLU_MAX_FILE_SIZE define so it pairs with the trailing #endif.

Referenced code: src/sign-verify/clu_sign.c:1244-1247 (4 lines)


This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread src/genkey/clu_genkey.c
finalOutFNm = NULL;
}
if (derBuf != NULL) {
wolfCLU_ForceZero(derBuf, derSz);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 [High] Negative derSz passed to wolfCLU_ForceZero in ED25519 keygen cleanup · Incorrect sizeof/type usage

derSz holds the signed return of wc_Ed25519PrivateKeyToDer/wc_Ed25519PublicKeyToDer (lines 169-172, 274-279); on a negative return the switch breaks with derBuf still allocated, and the new cleanup converts that negative int to unsigned int len, making wc_ForceZero write ~4 GiB past the buffer. The sibling RSA cleanup guards with derBufSz > 0. Adjacent to known finding #1116, which is the inverse (zeroing absent) and would not be fixed by this guard.

Related known finding #1116 (similar but distinct): Both affect ED25519 cleanup buffers in wolfCLU_genKey_ED25519. #1116 is missing zeroization before free, while this finding is an unsafe zeroization length after a negative DER-conversion result; fixing #1116 requires adding wipes, whereas this requires positive-size guards.

Fix: Guard both cleanup wipes with derSz > 0 / pemSz > 0, matching wolfCLU_genKey_RSA.

runFixture("testKeyFileRefusalsWin", testKeyFileRefusalsWin);
runFixture("testOpenExistingSecureFileWin", testOpenExistingSecureFileWin);
#endif
runFixture("testSecureFileBios", testSecureFileBios);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] New secure-file helpers with documented error paths have no unit coverage · Missing edge-case coverage on a function the PR also changed

The suite exercises the read/open/BIO/DER helpers but never calls wolfCLU_CloseOutFile (NULL no-op and OUTPUT_FILE_ERROR flush path), wolfCLU_RejectSamePath (SAME vs UNDETERMINED), wolfCLU_OpenPairedOutFile, wolfCLU_OpenSecureFileForUpdate (ENOENT create-fallback used by the XMSS write callback), or wolfCLU_LogKeyOpenFailure — all added by this PR.

Fix: Add fixtures for wolfCLU_CloseOutFile(NULL, ...), wolfCLU_RejectSamePath on both non-distinct results, and wolfCLU_OpenSecureFileForUpdate on missing/existing/symlink paths.

Comment thread src/genkey/clu_genkey.c
finalOutFNm = NULL;
}
if (derBuf != NULL) {
wolfCLU_ForceZero(derBuf, derSz);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 [Medium] Negative derSz passed as unsigned length to wolfCLU_ForceZero in ED25519 keygen cleanup · Buffer overflows

The new cleanup wipe passes derSz directly to wolfCLU_ForceZero()'s unsigned int length. When wc_Ed25519PrivateKeyToDer() (line 169) or wc_Ed25519PublicKeyToDer() (line 275) fails on its second, encoding call, derSz holds a negative error code while derBuf is allocated, so the wipe writes ~4 GB past the allocation. Adjacent to known finding #38, which is the inverse defect (wipe absent entirely).

Related known finding #1116 (similar but distinct): Both affect ED25519 DER cleanup in wolfCLU_genKey_ED25519, but #1116 omits zeroization before free, whereas this finding invokes zeroization with a negative size converted to unsigned. The root causes and required patches differ.

Fix: Guard with if (derSz > 0) before the wipe, matching the derBufSz > 0 guard already used in wolfCLU_genKey_RSA().

Comment thread src/tools/clu_base64.c

case WOLFCLU_OUTFILE:
bioOut = wolfSSL_BIO_new_file(optarg, "wb");
bioOut = wolfCLU_OpenOutFileBio(optarg);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] base64 command left without the new -in/-out same-file guard · File handling vulnerabilities

This call site was switched to the new helper but is still a truncating open performed during option parsing, with no wolfCLU_RejectSamePath() check like the one the PR added to enc, dgst, hash, pkcs7, pkcs8, pkey and rsa. base64 -in f -out f therefore truncates f before it is read, and the command silently succeeds on empty input.

Fix: Defer the -out open until after -in has been read and gate it on wolfCLU_RejectSamePath(inPath, outPath).

runFixture("testOpenExistingSecureFileWin", testOpenExistingSecureFileWin);
#endif
runFixture("testSecureFileBios", testSecureFileBios);
runFixture("testDerSetLength", testDerSetLength);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] New secure-file helpers with security-relevant refusal paths have no unit coverage · Missing edge-case coverage on a function the PR also changed

The suite covers wolfCLU_ReadFileToBuffer, wolfCLU_PathsRefEqual, wolfCLU_CreateSecureFile, wolfCLU_OpenExistingSecureFile, wolfCLU_OpenOutFileDistinctFrom and the BIO wrappers, but never exercises wolfCLU_OpenSecureFileForUpdate() (the XMSS private-key rewrite path and its ENOENT-only create fallback), wolfCLU_RejectSamePath(), wolfCLU_OpenPairedOutFile(), or wolfCLU_CloseOutFile()'s failure branch.

Fix: Add fixtures asserting the create/no-truncate/refusal behavior of wolfCLU_OpenSecureFileForUpdate() and the SAME/UNDETERMINED refusals of wolfCLU_RejectSamePath() and wolfCLU_OpenPairedOutFile().

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