Commit Graph

9688 Commits

Author SHA1 Message Date
David Garske 6a3eb6f0a8 Merge pull request #10360 from gasbytes/cipher-init-dtls13-fix
dtls13: free and null the cipher slot on init failure in Dtls13InitAesCipher and ChaCha equivalent
2026-05-05 13:08:06 -07:00
David Garske e3a195d394 Merge pull request #10075 from josepho0918/mqx
Improve compatibility for XINET_PTON
2026-05-05 12:47:45 -07:00
David Garske e3285850f9 Merge pull request #10289 from julek-wolfssl/zd/21652
TLS 1.3: gate 0-RTT on a cache-backed resumption ticket
2026-05-05 12:46:26 -07:00
David Garske 3147a10f23 Merge pull request #10141 from sebastian-carpenter/tls-ech-downgrade
TLS ECH Compliance Fixes
2026-05-05 12:14:20 -07:00
David Garske da038c6d51 Merge pull request #10299 from Frauschi/pqc_key_share_fix
Fix PQC key exchange with multiple KEM key shares
2026-05-05 12:03:32 -07:00
David Garske c3cd71ea02 Merge pull request #9965 from kojo1/mldsa
Add ML-DSA to X509_get_pubkey and EVP_PKEY_base_id
2026-05-05 11:57:06 -07:00
David Garske 309ada27a7 Merge pull request #10370 from cconlon/setAKID
Fix malformed AKID extension from wolfSSL_X509_set_authority_key_id()
2026-05-05 11:55:38 -07:00
David Garske 644f6171ab Merge pull request #10290 from LinuxJedi/emnet
Fix emNET support and add tests
2026-05-05 11:46:15 -07:00
David Garske 8e46221428 Merge pull request #10336 from julek-wolfssl/wolfSSL_PEM_read_bio_X509_CRL-multi-crl-fix
src/x509.c: refactor wolfSSL_PEM_read_bio_X509_CRL onto the per-block reader
2026-05-05 11:42:00 -07:00
David Garske 3b7ac9fd25 Merge pull request #10327 from embhorn/zd21704
Hardening in TLSX_KeyShare_ProcessPqcHybridClient
2026-05-05 11:41:43 -07:00
David Garske 678ddd6c73 Merge pull request #10339 from embhorn/zd21707
Fix handling of otherName in ConfirmNameConstraints
2026-05-05 11:41:28 -07:00
David Garske b0fca9df10 Merge pull request #10276 from padelsbach/asn1-time-chars-check
Add checks for ascii digits in time decode functions
2026-05-05 11:38:47 -07:00
David Garske bc15131f60 Merge pull request #10338 from gasbytes/cert-ext-offered-list-fix
reject extensions in a TLS 1.3 Certificate message that were not offered in the prior ClientHello/CertificateRequest
2026-05-05 11:38:25 -07:00
David Garske 403f0fe637 Merge pull request #10230 from julek-wolfssl/fenrir/20260415
Fenrir fixes
2026-05-05 11:34:43 -07:00
David Garske 7e9635df19 Merge pull request #10208 from ColtonWilley/bio-io-negative-length-checks
Guard against negative length in BIO, I/O callbacks and PKCS12 PBKDF
2026-05-05 11:32:21 -07:00
David Garske c278b614dd Merge pull request #10337 from embhorn/zd21709
Fix DupSSL issue with Poly1305 auth
2026-05-05 11:26:29 -07:00
David Garske d793452264 Merge pull request #10353 from julek-wolfssl/dtls-13-client-only
DTLS 1.3 client-only minimum: WOLFSSL_DTLS_ONLY + autoconf cascade
2026-05-05 11:24:44 -07:00
David Garske 80c9d3f048 Merge pull request #10183 from douzzer/20260409-IsValidFQDN
20260409-IsValidFQDN
2026-05-05 11:22:51 -07:00
David Garske 6fb7cb3980 Merge pull request #10277 from kareem-wolfssl/zd21664_5
Add some missing length checks and fix length calculation.
2026-05-05 10:39:22 -07:00
sebastian-carpenter 61ba5378fe TLS ECH compliance fixes 2026-05-04 15:46:18 -06:00
Tobias Frauenschläger 3524ece54e Fix PQC key exchange with multiple KEM key shares 2026-05-04 10:32:45 +02:00
Takashi Kojo 1a6dee2bb3 Add ML-DSA to X509_get_pubkey and EVP_PKEY_base_id 2026-05-02 08:13:08 +09:00
Chris Conlon df8e2eedb3 x509: fix malformed AKID extension from wolfSSL_X509_set_authority_key_id 2026-05-01 10:04:31 -06:00
Daniel Pouzzner d8797f59c4 Merge pull request #10261 from Frauschi/slh-dsa
Replace liboqs SPHINCS+ with SLH-DSA in certificate layer
2026-04-30 23:52:36 -05:00
JacobBarthelmeh fc51a38094 Merge pull request #10135 from lealem47/nid_ED
Add Ed25519/Ed448 support to EVP layer
2026-04-30 14:16:05 -06:00
Andrew Hutchings 3720a9496c Restore IP_SOCK_getsockopt emNET error lookup
Merging TranslateReturnCode into wolfSSL_LastError dropped the
IP_SOCK_getsockopt(SO_ERROR) lookup emNET integrations need to retrieve
the canonical IP_ERR_* for a failed recv/send, leaving a broken branch
that returned the raw value and mishandled the POSIX-facade convention.

Restore the historic lookup (fixing the optlen pointer-vs-int typo
along the way) and add a CI test that builds wolfSSL with
-DWOLFSSL_EMNET against a clean-room shim providing an emNET-faithful
IP_SOCK_getsockopt (SO_ERROR-then-errno fallback, since Linux does not
stash EAGAIN in SO_ERROR); recv/send fall through to glibc.
2026-04-30 18:01:16 +01:00
Andrew Hutchings bf19d548bb Fix emNET support and add tests
The emNET `wolfSSL_LastError` branches were incorrect. The second one
was never hit and would never compile. The first one inverts error codes
that should not be inverted.

This fixes that code and adds a test with a shim layer to test emNET
calls without using emNET.
2026-04-30 18:01:16 +01:00
Tobias Frauenschläger 9393d62591 Replace liboqs SPHINCS+ with SLH-DSA in certificate layer
Replace the liboqs-based pre-standardization SPHINCS+ implementation
with the native FIPS 205 SLH-DSA implementation across the
certificate / ASN.1 / X.509 layers, and add SLH-DSA-rooted test
certificates plus TLS 1.3 .conf scenarios that exercise the new
verification path. All liboqs SPHINCS+ code is removed.

This enables SLH-DSA for certificate chain authentication: CA
certificates signed with SLH-DSA, certificate signature verification
against an SLH-DSA root. TLS 1.3 entity authentication via
CertificateVerify with SLH-DSA will be added in a follow-up PR.

Follows RFC 9909 (X.509 Algorithm Identifiers for SLH-DSA) and
NIST FIPS 205. Supports both SHAKE and SHA-2 parameter families
across all twelve standardized variants.

DER codec:
- New PrivateKeyDecode, PublicKeyDecode, KeyToDer, PrivateKeyToDer,
  PublicKeyToDer with RFC 9909 encoding (bare OCTET STRING containing
  4*n raw bytes = SK.seed || SK.prf || PK.seed || PK.root, no nested
  wrapper). OID auto-detection across all twelve SHAKE / SHA-2 variants.
- PublicKeyDecode raw-bytes fast path mirrors wc_Falcon_PublicKeyDecode
  and wc_Dilithium_PublicKeyDecode so callers (notably
  wolfssl_x509_make_der and ConfirmSignature, which pass the raw
  BIT STRING contents stashed by StoreKey) decode correctly. Honours
  the caller's *inOutIdx start offset.
- Error paths in Private/PublicKeyDecode preserve params/flags/
  inOutIdx and only ForceZero the buffer half each helper actually
  writes; skip the wipe entirely on BAD_LENGTH_E (no bytes touched).
- ImportPublic uses |= on flags so a Private-then-Public import
  sequence retains FLAG_PRIVATE.

OID dispatch:
- 12 standardized NIST OIDs (6 SHAKE + 6 SHA-2) per RFC 9909. The
  pre-standardization OID-collision mechanism is removed since NIST
  OIDs do not collide.
- wc_SlhDsaOidToParam / wc_SlhDsaOidToCertType return NOT_COMPILED_IN
  (rather than -1) for recognised SLH-DSA OIDs whose parameter set
  isn't built; wc_IsSlhDsaOid recognises both. The x509 dispatch
  surfaces this as a precise diagnostic instead of the generic
  "No public key found".
- wc_GetKeyOID picks a placeholder parameter from whatever variant is
  compiled in and #errors at compile time if none is.
- asn_orig.c EncodeCert / EncodeCertReq accept SHA-2 SLH-DSA keyTypes
  alongside SHAKE.

Tests and fixtures:
- Test cert chain in certs/slhdsa/: SLH-DSA-SHAKE-128s and
  SLH-DSA-SHA2-128s self-signed roots that sign reused ML-DSA-44
  entity keys (server + client), plus the gen script
  (gen-slhdsa-mldsa-certs.sh, OpenSSL >= 3.5).
- New TLS 1.3 .conf scenarios under tests/suites.c dispatch:
  test-tls13-slhdsa-shake.conf, test-tls13-slhdsa-sha2.conf, and a
  wrong-CA negative test test-tls13-slhdsa-fail.conf.
- DER round-trip and on-disk decode tests; bench_slhdsa_*_key.der
  fixtures regenerated with wolfSSL's own encoder so the codec is
  pinned to RFC 9909.
- New unit test test_wc_slhdsa_x509_i2d_roundtrip exercises the raw
  PublicKeyDecode entry point that wolfssl_x509_make_der relies on.
- test_wc_slhdsa_check_key now tests both Public-then-Private and
  Private-then-Public import orderings.

Build / ABI:
- DYNAMIC_TYPE_SPHINCS = 98 kept as RESERVED with a tombstone comment
  for ABI stability; new code should use DYNAMIC_TYPE_SLHDSA (107).
- All build system / IDE project files updated; SPHINCS+ sources,
  headers, and test data removed.
- Dead bench_slhdsa_*_key arrays removed from gencertbuf.pl and
  certs_test.h; the .der files on disk drive the decode tests.
2026-04-30 18:32:07 +02:00
Reda Chouk eace4f29b1 dtls13: free and null the cipher slot on init failure in Dtls13InitAesCipher and ChaCha equivalent 2026-04-30 16:59:42 +02:00
Daniel Pouzzner a057975347 Merge pull request #10293 from Frauschi/liboqs_removal
Remove liboqs for ML-KEM and ML-DSA, update for Falcon
2026-04-30 09:04:11 -05:00
Daniel Pouzzner 76080d0b19 Merge pull request #10292 from Frauschi/liblms_libxmss_removal
Remove deprecated liblms and libxmss
2026-04-30 09:01:24 -05:00
Juliusz Sosinowicz a012a8f3ec DTLS 1.3 client-only minimum: WOLFSSL_DTLS_ONLY + autoconf cascade
* configure.ac: --enable-dtls13 auto-enables --enable-dtls and TLS 1.3,
  with a targeted error if either is explicitly --disabled, plus a
  post-finalization sanity check that errors out if a later
  prerequisite test forces ENABLED_TLS13 back to "no" while
  ENABLED_DTLS13 is yes.
* src/internal.c, src/wolfio.c, wolfssl/wolfio.h: new WOLFSSL_DTLS_ONLY
  compile-time flag elides the EmbedReceive / EmbedSend default
  callbacks. The DTLS_MAJOR runtime check stays in SetSSL_CTX so a
  TLS-method ctx in a DTLS-only build doesn't get datagram callbacks
  by default, and WriteSEQ keeps its ssl->options.dtls branch. A
  #error in settings.h refuses WOLFSSL_DTLS_ONLY without WOLFSSL_DTLS.
* wolfcrypt/src/aes.c: add HAVE_AES_DECRYPT to the inv_col_mul
  definition gate to match its only caller; without it the function is
  emitted dead under WOLFSSL_AES_DIRECT && NO_AES_DECRYPT and
  -Werror=unused-function fails the build.
* .github/workflows/os-check.yml: matrix entry for a minimal DTLS 1.3
  client-only build.
2026-04-30 11:40:22 +00:00
Tobias Frauenschläger 7a2cf5b655 Remove liboqs for ML-KEM and ML-DSA, update for Falcon 2026-04-30 11:03:06 +02:00
Daniel Pouzzner c782db3cc9 Merge pull request #10158 from Roy-Carter/feature/libevent_integration
Libevent integration for OpenSSL compatibility layer
2026-04-29 18:22:07 -05:00
Tobias Frauenschläger e1fefcca4f Remove deprecated liblms and libxmss 2026-04-29 19:52:09 +02:00
David Garske 07ea48673a Merge pull request #10073 from anhu/certmgr
Ensure certificates are getting into cert manager
2026-04-29 09:58:45 -07:00
Eric Blankenhorn 60d6fbe3f5 Fix from review 2026-04-29 10:33:16 -05:00
Juliusz Sosinowicz b261ee6238 src/x509.c: handle streaming BIOs in PEM block reader
The CRL refactor broke nginx's ssl_cache.t (and the wolfSSL/wolfssl
nginx_check matrix on 1.24.0/1.25.0/1.28.1) because nginx loads the test
CRL through a FIFO. wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio() asks
wolfSSL_BIO_get_len() for the BIO size up front; for a FIFO the
underlying ftell() returns ESPIPE, wolfssl_file_len() reports
WOLFSSL_BAD_FILETYPE, and BIO_get_len() returns 0. The function then hit
the l <= pem_struct_min_sz guard and bailed with ASN_NO_PEM_HEADER
before reading a byte, so the caller's loop saw "no CRL" and nginx
emitted "PEM_read_bio_X509_CRL() failed".

Treat l == 0 as "streaming source, size unknown" and allocate up to
MAX_BIO_READ_BUFFER (the same cap ReadPemFromBioToBuffer used for this
case before the refactor). The existing byte-by-byte reader already
stops at the END marker or at EOF, so this is enough; if the upstream
short-reads we still surface ASN_NO_PEM_HEADER from the
pem_struct_min_sz read below. Keep rejecting tiny non-zero lengths
since those are real "buffer too small" cases.
2026-04-29 15:28:17 +00:00
Eric Blankenhorn e0f753c0d6 Fix wolfSSL_X509_verify_cert permissiveness with compat layer 2026-04-29 09:40:15 -05:00
Mattia Moffa bfd8834b31 Additional minor fixes 2026-04-28 18:34:32 +02:00
Colton Willey 37d66b8be9 Guard against negative length in BIO, I/O callbacks and PKCS12 PBKDF
- src/bio.c: Add BIO self-cycle UAF guard and negative nread/nwrite checks
- src/wolfio.c: Add negative sz guards to EmbedSend/EmbedReceive
- wolfcrypt/src/pwdbased.c: Add pLen/sLen/totalLen overflow checks in
  wc_PKCS12_PBKDF_ex
2026-04-28 18:34:32 +02:00
Reda Chouk 8d9af257ac reject extensions in a TLS 1.3 Certificate message that were not offered in the prior ClientHello/CertificateRequest
per rfc 8446 4.4.2
2026-04-28 17:50:09 +02:00
Eric Blankenhorn ba20e380bf Fix DupSSL issue with Poly1305 auth 2026-04-28 09:30:14 -05:00
Juliusz Sosinowicz 9d49f7f261 TLSX_GetSize: return error as soon as it happens 2026-04-28 14:54:20 +02:00
Juliusz Sosinowicz b0fdaa2a6d TLS 1.3: gate 0-RTT on a cache-backed resumption ticket
RFC 8446 section 8 requires any server instance to accept 0-RTT for a
given ClientHello at most once. Prior to this change wolfSSL's behaviour
diverged from that requirement in several ways:

  * ctx->maxEarlyDataSz defaulted to MAX_EARLY_DATA_SZ whenever the
    library was built with WOLFSSL_EARLY_DATA, so servers auto-
    advertised 0-RTT in NewSessionTicket without the application
    asking. RFC 8446 E.5 says 0-RTT MUST NOT be enabled unless
    specifically requested.
  * The post-accept eviction is compiled out under NO_SESSION_CACHE,
    so builds without the cache accepted 0-RTT with no replay defence.
  * Stateless self-encrypted tickets do not carry a session ID on the
    stateless DoClientTicket decrypt path, so wolfSSL_SSL_CTX_remove_
    session could not locate them to evict.
  * wolfSSL_SSL_CTX_remove_session always returned 0 on success
    regardless of whether the session was actually in the cache,
    diverging from OpenSSL's SSL_CTX_remove_session (1 on success,
    0 on not-found).

Changes:
  * src/internal.c: ctx->maxEarlyDataSz defaults to 0; applications
    must opt in with wolfSSL_CTX_set_max_early_data.
  * src/tls13.c: #error when WOLFSSL_EARLY_DATA is built with
    HAVE_SESSION_TICKET and NO_SESSION_CACHE. Escape hatch
    WOLFSSL_EARLY_DATA_NO_ANTI_REPLAY for deployments that take
    application-layer responsibility.
  * wolfssl/internal.h: imply WOLFSSL_TICKET_HAVE_ID from
    WOLFSSL_EARLY_DATA so stateless-ticket issuance populates the
    cache under an ID that eviction can find.
  * src/ssl_sess.c: wolfSSL_SSL_CTX_remove_session returns 1 when the
    session was found (internal-cache hit, or ctx->rem_sess_cb fired
    for an external cache), 0 otherwise. Matches OpenSSL semantics.
  * src/tls13.c: the 0-RTT acceptance condition in CheckPreSharedKeys
    now calls wolfSSL_SSL_CTX_remove_session and checks its return:
    the eviction is the check. If the session was in the cache, 0-RTT
    is accepted and the single-use requirement is satisfied. If not,
    the early_data extension is rejected through the normal path so
    the record layer correctly skips in-flight 0-RTT records.
    WOLFSSL_MSG at each rejection site.
  * doc/dox_comments/header_files/ssl.h: document runtime opt-in.
  * tests: four new tests —
    test_tls13_0rtt_default_off (fails without default-to-0 fix),
    test_tls13_0rtt_stateless_replay (fails without TICKET_HAVE_ID
    implication and remove_session gate),
    test_tls13_remove_session_return (fails without return-value fix),
    test_tls13_0rtt_ext_cache_eviction (fails without ext-cache
    counts-as-found fix).
    test_tls13_early_data explicitly opts in via
    wolfSSL_CTX_set_max_early_data.
    tests/api.c: two SSL_CTX_remove_session == 0 assertions updated
    to == 1.
2026-04-28 14:14:16 +02:00
Juliusz Sosinowicz 558c329571 fixup! fenrir: address review feedback on PR 10230 2026-04-28 13:22:53 +02:00
Juliusz Sosinowicz 4a85f00240 src/x509.c: refactor wolfSSL_PEM_read_bio_X509_CRL onto the per-block reader
ReadPemFromBioToBuffer slurps the entire BIO in one shot, so iterative
callers like wolfSSL_PEM_read_bio_X509_CRL (and by extension
wolfSSL_X509_load_crl_file's BIO branch) saw EOF after the first block
and silently dropped every CRL after the first in a multi-CRL bundle.

Refactor wolfSSL_PEM_read_bio_X509_CRL to delegate to
wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio, which already reads one
PEM BEGIN/END pair per call and leaves the BIO positioned just past the
END line. Loop over it so we skip past intervening cert/key blocks and
return the next CRL in the stream — matching OpenSSL's
PEM_read_bio_X509_CRL, verified against OpenSSL 3.0.13 with cases
{cert,CRL}, {CRL,cert}, {CRL,cert,CRL}, {key,CRL}, {CRL,key,CRL}: in
each case OpenSSL skips non-CRL blocks until EOF.

When the caller passes a non-NULL `x` whose `*x` is already populated,
free the previous CRL before overwriting the slot — matching the
d2i_X509_CRL reuse contract the old body relied on.

To keep both helpers visible at the new call site, drop their `static`
qualifier (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio for the per-block
read, wolfSSL_X509_PKEY_free to free defensively-allocated keys parsed
from intervening non-CRL blocks). Their definitions in src/x509.c and
declarations in wolfssl/internal.h are widened from OPENSSL_ALL to
OPENSSL_EXTRA || OPENSSL_ALL so the OPENSSL_EXTRA-only build (which
compiles wolfSSL_PEM_read_bio_X509_CRL) links cleanly. The unrelated
INFO_read_bio / INFO_read_bio_X509_INFO group below them keeps its
OPENSSL_ALL gate because it depends on wolfSSL_X509_INFO_new/free that
are still OPENSSL_ALL-only.

Also register the previously-orphaned test_wolfSSL_X509_load_crl_file
(its slot in TEST_OSSL_X509_LOOKUP_DECLS was a duplicated
test_wolfSSL_X509_LOOKUP_ctrl_hash_dir entry), update its assertion for
crl2.pem (which already contains two CRLs) to expect 2 instead of 1, and
add a multi-CRL bundle case that builds a memory BIO from
crl.pem + server-cert.pem + crl2.pem and asserts that the reader walks
past the cert and returns all 3 CRLs before NULL.
2026-04-28 10:06:47 +00:00
Eric Blankenhorn e37118bdfb Hardening in TLSX_KeyShare_ProcessPqcHybridClient 2026-04-27 15:37:32 -05:00
Juliusz Sosinowicz f3e183a338 fenrir: address review feedback on PR 10230
- tls.c: TLSX_CertWithExternPsk_GetSize takes word16*, but length was
  widened to word32 in TLSX_GetSize. Use the hsz staging variable like
  the other cases so WOLFSSL_CERT_WITH_EXTERN_PSK builds compile.
- tls.c: silence -Wunused-variable for hsz in builds where every case
  that consumes it (TLS 1.3, PSK, ETM, early data, PHA, cookie, cert
  with extern PSK) is compiled out, e.g. user_settings_tls12.h.
- test_tls_ext.c: assert session->ticketLen > 0 before mutating
  ticketAdd in the ticket-age out-of-window test so it fails loudly if
  no NewSessionTicket was received.
2026-04-27 14:03:31 +02:00
Juliusz Sosinowicz 0f9fb2fb1d tls: fix TLSX_CA_Names_GetSize word16 overflow (F-2927)
The CA Names extension size accumulator was a word16. With enough
CA entries (or large DER-encoded names) the running total can wrap
silently, leaving TLSX_CA_Names_Write to overflow an undersized
extension buffer. Match TLSX_SNI_GetSize: use a word32 accumulator
and return 0 when the total exceeds WOLFSSL_MAX_16BIT.
2026-04-27 14:03:13 +02:00