- Add wolfIO_OcspDestAllowed(); block internal-range responder hosts
- Call it in EmbedOcspLookup before connect (CWE-918)
- Gate on WOLFSSL_OCSP_SCREEN_RESPONDER (off by default)
- Add unit tests and CI for both resolver paths
CMake accepted -DWOLFSSL_XMSS=1 but never emitted WOLFSSL_HAVE_XMSS, so
wc_xmss.c compiled empty and options.h advertised no XMSS support. Add the
missing definition block (mirroring LMS) plus WOLFSSL_XMSSVERIFYONLY and
WOLFSSL_XMSSSMALL sub-options for parity with autotools --enable-xmss=
verify-only,small, and expose all three in the generated options.h.
Also enable WOLFSSL_XMSS in the cmake.yml CI build, which tested LMS but
not XMSS -- the blind spot that let this regression through.
- *_wire_sni test is now more efficient
- openssl-ech workflow now does interop with ECH rejection
extra improvements:
- tested TLSX_EchSwapExtensions
- added ctx level SNI to padding calculation
- Improvement of SNI handling for ECH
- Changed EchSwapExtensions to append instead of prepend
- Reworked ECH testing
Address review feedback (dgarske):
- Restore SECURITY-POLICY.md instead of deleting it. The full policy
(severity rubric, scope, coordinated disclosure, credit) stays in-repo;
the canonical website URL is now presented as a mirror of it, not a
replacement, so other repos can still reference one copy.
- SECURITY.md: prefer support@wolfssl.com, offer secure@wolfssl.com with
the PGP key as an option, and drop the phone number.
- Restore the mandatory report-template requirement and the "keep the
vulnerability private until a fix is released" guidance, resolving the
contradiction between the intro and the template section.
Add ML-DSA signing and verification for CMS/PKCS#7 SignedData, following
RFC 9882. ML-DSA is used in CMS "pure" mode: the signature is computed
over the complete message (the DER SET OF signed attributes, or the
eContent when none are present) with an empty context string and absent
signatureAlgorithm parameters, rather than over a pre-computed DigestInfo
as with RSA/ECDSA.
wolfcrypt/src/pkcs7.c:
- New ML-DSA helpers: wc_PKCS7_MlDsaLevelFromOID, wc_PKCS7_BuildPureSigMessage,
wc_PKCS7_MlDsaSign and wc_PKCS7_MlDsaVerify, wired into the per-algorithm
switch sites (GetSignSize, SignedDataGetEncAlgoId, SetPublicKeyOID,
CheckPublicKeyDer) and the sign/verify dispatchers. Only the final FIPS 204
ML-DSA OIDs are accepted; pre-standard draft Dilithium OIDs are not.
- GetSignSize derives the ML-DSA signature length from the parameter set.
- InitWithCert copies the signer public key into the RSA-sized publicKey buffer
only for RSA/ECC certs (the raw-sign callback consumers); large PQC keys such
as ML-DSA would overflow it and are never read back, so publicKeySz stays 0.
- wc_MlDsaKey is always heap allocated (it embeds multi-KB key buffers); the
accompanying DecodedCert uses the WC_DECLARE_VAR/WC_ALLOC_VAR_EX macros for
stack-vs-heap handling under WOLFSSL_SMALL_STACK.
- wc_PKCS7_SignedDataBuildSignature skips building the DigestInfo for ML-DSA,
which signs the full message in pure mode and never consumes it.
- wc_PKCS7_MlDsaSign wraps the ML-DSA private-key decode in
PRIVATE_KEY_UNLOCK/PRIVATE_KEY_LOCK. Unlike RSA/ECC, the FIPS module gates
wc_MlDsaKey_PrivateKeyDecode behind the private-key read lock, so signing
would otherwise fail with FIPS_PRIVATE_KEY_LOCKED_E under --enable-fips. The
macros are no-ops in non-FIPS builds.
wolfssl/wolfcrypt/pkcs7.h:
- Document that the fixed-size signer public key buffer (publicKey/publicKeySz)
holds only RSA/ECC keys; it stays RSA-sized.
wolfcrypt/src/hash.c:
- Map the SHAKE128/SHAKE256 OIDs to their hash types in wc_OidGetHash().
certs/mldsa:
- Add expanded-only PKCS#8 DER private keys (mldsa44/65/87-key.der) matching
the self-signed ML-DSA certificates, with README and include.am updates.
The expanded-only shape (no seed) decodes via wc_MlDsaKey_ImportPrivRaw
without keygen-from-seed or the ASN template, so pkcs7signed_mldsa_test also
passes in WOLFSSL_MLDSA_NO_MAKE_KEY and non-WOLFSSL_ASN_TEMPLATE builds.
certs/renewcerts.sh:
- Generate the mldsa<N>-key.der files from the matching mldsa<N>-key.pem in the
expanded-only shape (openssl pkey -provparam ml-dsa.output_formats=priv), so
a regeneration keeps the DER key in step with the cert. The OpenSSL detection
probe now requires both ML-DSA keygen and that conversion across all three
levels, so the block runs fully (matched cert+key) or is skipped entirely
rather than aborting mid-way.
wolfcrypt/test/test.c:
- Add pkcs7signed_mldsa_test(): round-trip encode/verify of SignedData across
ML-DSA-44/65/87, with and without signed attributes, including a check that
the digest algorithm parameters are encoded as expected. The message-digest
OID is selected from the enabled hash set (SHA-512, else SHA-256, else SHA-1)
so the test builds when SHA-512 is disabled. A negative case confirms ML-DSA
rejects a caller-supplied pre-computed content hash with BAD_FUNC_ARG.
For each product (wolfSSH, wolfCLU, wolfTPM, wolfMQTT, wolfPKCS11, wolfProvider) this builds wolfSSL and then builds the product against it, at both the product's latest release tag and its master branch. It only checks that they compile, it does not run any tests. If a wolfSSL change breaks a product's latest release on purpose, you say so in a commit message with breaks-<product>=<tag>. A break on a product's master is not allowed and has to be fixed.
breaks-wolfssh=v1.5.0-stable
Note: wolfSSH v1.5.0-stable does not currently compile against wolfSSL. This commit did not break it, it adds the cross-library check that discovered the break. The token above declares it so the new check tracks it as a known break instead of failing red, until wolfSSH ships a fixed release.
Server-side PKCS#7 encode improvements that let downstream EST/SCEP enrollment
code (wolfCert) drive the existing encoder through the public API rather than
hand-rolling DER. Everything is gated under the existing HAVE_PKCS7 — no new
build options and no new public functions; the convenience wrappers live
caller-side.
Allow degenerate (certs-only) SignedData encode
Relax the hashOID != 0 requirement in PKCS7_EncodeSigned() when
sidType == DEGENERATE_SID, so a caller can produce a certs-only bundle (no
signer, attributes, or eContent — the form used by EST /cacerts and SCEP
GetCACert) by selecting DEGENERATE_SID via wc_PKCS7_SetSignerIdentifierType()
and calling wc_PKCS7_EncodeSignedData(). The output round-trips through
wc_PKCS7_VerifySignedData().
Size the signed-attribute array to the actual count
The SignerInfo attribute working array is now sized to the real attribute
count instead of a fixed [7] array. An inline buffer (sized
MAX_SIGNED_ATTRIBS_SZ, the historical footprint) covers the common
allocation-free case; a heap buffer is used only when the count exceeds it.
The default-attribute count comes from a single helper
(wc_PKCS7_GetDefaultSignedAttribCount) so the sizing matches the emission
logic exactly, and the canned-attribute write is bound-checked against the
array capacity. This also fixes a latent overflow where the backing array was
hardcoded [7] while the bound check used MAX_SIGNED_ATTRIBS_SZ. The macro is
retained for source compatibility but no longer caps the count.
Document the decoded-attribute value shape
Documented the stable shape of PKCS7DecodedAttrib.value (the contents of the
SET OF AttributeValue, outer SET tag stripped) so callers can rely on it. No
behavior change.
Fix multi-certificate decode in non-streaming builds
Bound the additional-certificate loop in wc_PKCS7_VerifySignedData against the
absolute end of the certificate set (idx + length) rather than the relative
length. In NO_PKCS7_STREAM builds the old bound dropped trailing certificates
(all but the first when a large eContent preceded the set), failing
verification when the signer cert was among those dropped. Streaming builds
were unaffected.
Tests
Added coverage in pkcs7signed_test: degenerate certs-only encode via the
public API, nine-attribute encode (beyond the inline capacity), decoded
attribute value shape for PrintableString and OCTET STRING, and a
multi-certificate decode regression with large content that triggers the
bound bug under NO_PKCS7_STREAM. Added a signed-attribute selection
round-trip covering a messageDigest-only subset and the no-attributes case
via wc_PKCS7_SetDefaultSignedAttribs/wc_PKCS7_NoDefaultSignedAttribs, a
WOLFSSL_NO_MALLOC over-capacity case that must return BUFFER_E instead of
overrunning the inline buffer, and a malformed certificate-set length that
exercises the certSetEnd clamp in the verifier. Config-sensitive cases are
guarded.
The summary table is printed to plain stdout (the Actions console log and
local terminals) in addition to the GitHub step summary. GitHub emoji
:shortcodes: like ➖ only expand on GitHub's Markdown
surfaces, so in the console log they appeared as literal text. Emit the
Unicode emoji directly, via \N{...} escapes so the source stays ASCII; the
glyphs match what the shortcodes mapped to, leaving the step summary
unchanged.
netns needs bwrap; without it commands silently share the host network
namespace and parallel network tests collide on ports. Skip the check for
--list (it inspects configs, runs nothing), hard-fail on CI so a missing-
bubblewrap misconfig can't silently degrade, and locally just warn and fall
back to the shared namespace.