* Regenerate the CRL that expired in September 2025 * Refresh the expired certificates embedded in certloadverifybuffer * Return 0 from tls servers that returned a wolfSSL_write byte count * Send a client certificate from client-tls and client-tls13-resume * Return 0 from certverify instead of WOLFSSL_SUCCESS * Give the XTS demo key two different halves * Exit success after ml_dsa prints its parameter table * Report failure from the custom io file client and server * Latch failures across every ecc-params curve lookup * Ignore SIGPIPE in the btle fifo transport * Fix the dtls rw-threads certificate paths * Make runall.sh fail when an example fails * Make openssl-verify.sh actually verify and actually fail * Raise the generate_ssl.sh common name length limit * Port the PQ examples to the current wolfSSL API * Return 0 from csr_w_ed25519_example and rsa-public-decrypt-app * Build the x509_acert openssl example against the right headers * Give the examples Makefiles a consistent wolfSSL prefix * Fix the double free and NULL derefs in the custom io cleanup paths * Stop forcing the ESP32 examples to include a developer private config * Add the missing WiFi Kconfig to the DTLS13 station examples * Use XSTRLCPY in client-dtls13 since wolfSSL has no XSTRCPY * Make the DTLS13 example ctx static so it stops colliding with libnet80211 * Set SO_REUSEADDR on the tls servers that lacked it * Give puf the wolfSSL sources and stop building the IDF 4.4 only ENC28J60 examples * Set SO_REUSEADDR on server-tcp as well * Exit the can-bus client on EOF and give it real input in CI * Re-arm the select timeout each pass in the nonblocking dtls server * Keep the shared memory BIOs alive until both sides are done * Port the ebpf tracers to the libbpf 1.0 perf_buffer__new signature * Clone wolfSSL before make builds its graph so uefi-static builds from a clean tree * Raise wolfcryptjni compileSdk to 32 for the BigInteger API its submodule uses * Link wolfentropy.o and keep wc_port socket helpers out of the UEFI build * Track the wolfSSL dilithium.c to wc_mldsa.c rename and drop a stale java import * Move uefi-library to the wc_MlDsa API after the wolfSSL dilithium rename * Declare the launcher activity exported, required from API 31 * Configure wolfSSL before make in the fullstack setup script * Track the wolfSSL io.c to wolfio.c rename in the ndk sample * Keep glibc headers out of the freestanding uefi-library build * Track the wolfSSL mlkem.h rename and give RT1060 the SDK name it selects on * Track the wolfIP struct ll rename and pin wolfIP to its v1.0 release * Use getaddrinfo in the ndk sample since bionic does not declare gethostbyname * Cross compile RT1060 with arm-none-eabi and document the SDK value the Makefile matches * Enable wolfIP HTTP so its httpd.h actually declares the API the example calls * Define HAVE_NETDB_H so wolfio.c includes the header its getaddrinfo path needs * Link pkcs12.o, which RT1060 enables by default and wolfcrypt test calls * Port the ENC28J60 examples to the ESP-IDF 5.x ethernet API * Compile dtls.c in the ndk sample, which enables WOLFSSL_DTLS * Define the PHY identifier registers the removed IDF header supplied * Compile kdf.c in the ndk sample for the TLS PRF * Give RT1060 a current_time so the benchmark stops needing clock_gettime * Port the ENC28J60 PHY to the IDF 5.x autonego_ctrl vtable * Remove the ENC28J60 server's duplicate driver copy that main already builds * Return the DTLS server to accept on close_notify so a resume is heard * Run the C# pq client/server pair under mono * Define WOLFSSL_CERT_REQ so the ndk-gradle app links wolfssljni's X509_REQ calls * Refresh the expired client ECC DER certificate * Add CI that builds and runs every example against wolfSSL master and stable * Sign OCSP staples with a responder intermediate1 actually delegated * Report a failing PKCS#11 example instead of always exiting 0 * Link the PSA library the README's PSA_LIB_PATH names * Widen the mynewt pointer prints so they build on a 64 bit native BSP * Test RSA under UEFI with a 2048 bit key so it clears wolfSSL's minimum * Left pad the ECDSA r and s so a leading zero cannot shift the signature * Document the smime and indef flags the pkcs7 examples need * Fail ecc-verify when the signature does not verify * Fail ecc-sign when a round produces an invalid signature * Fail aesgcm-file-encrypt when its sanity test does not pass * Check that ML-KEM derives the same shared secret on both sides * Fail ecdh_gen_secret when the two sides derive different secrets * Return the DH key agreement error instead of always exiting 0 * Retry the fullstack HTTPS probe so a slow sim start does not fail it * Confirm the custom-io file transfer succeeded so CI can assert it * Print a success line from the silent file-encrypt and ecc-export examples * Add device-sims job running ATECC608 STSAFE and TROPIC01 sim wolfcrypt tests * Extend device-sims to STM32 and PIC32MZ for the full sim fleet * Mount wolfSSL for the STM32 and PIC32MZ sim wolfcrypt runs * Accept the zero success return from wolfSSL_CTX_set_max_early_data * Read the earlydata reply so the client processes the session ticket before resuming * Read the earlydata reply in the DTLS client so it processes the session ticket * Run the tls13 and dtls13 earlydata pairs now that the clients process the ticket * Let expect_fail clear on refs that carry the fix via a fixed_on marker * Retry the PSA TLS 1.3 handshake so an intermittent ECC reject does not fail CI * Retry network fetches across CI so a transient blip does not fail a job * Normalize do_ecc and do_25519 exit codes like do_448 so an error is never masked to 0 * Build and run the merged-in hsm dtls_client example in CI via a dedicated hsm.yml job * Add a make check target to each applicable example * Run only the example and lint smoke set on draft PRs * Only run a per-target workflow when its own example dir changes * Assert the real se050 wolfcrypt result instead of an early sub-test line * Size the RSA 2048 key export buffers so the UEFI test does not fail on BUFFER_E * Call the always-present MLDSA context API from the UEFI driver * Cross uefi-static and uefi-library with both wolfSSL refs in the matrix * Give each tpm matrix leg a ref-unique results file and artifact * Add a codespell spellcheck pass to the lint job * Run push CI on master only so a PR branch does not double-trigger * Select valgrind by caller_run_id since event_name is the caller under workflow_call * Make example check targets catch real failures with pipefail exit checks and inputs * Wire the harness to run make check for mode check examples starting with ecc * Migrate the single-entry exec examples to mode check and fold their inputs into the check targets * Fix four make check assertions that misfired under pipefail * Give the tpm manifest entry a run step so it asserts output * Skip uefi-static in the lint make -n loop so it does not clone * Assert the actual verify result in the pkcs7 and rsa-nb checks * Return nonzero from pkcs12-create-example on a failed create so the check is not a false pass * Return nonzero from rsa-kg on any key generate or write failure * Assert the static memory checks by exit code instead of a pipefail grep that BSD make lacks * Run pkcs7 signedData stream through make check so it asserts the real verify result * Check DER certificates and CRLs in the expiry canary too * Feed the wolfHSM client its stdin so run_client actually exchanges data * Assert every make check by exit code and captured output instead of a pipefail grep so they hold under BSD make |
||
|---|---|---|
| .. | ||
| Makefile | ||
| README.md | ||
| gen_dual_keysig_cert.c | ||
| gen_ecdsa_mldsa_dual_keysig_cert.c | ||
| gen_rsa_mldsa_dual_keysig_cert.c | ||
README.md
X9.146 Examples
This README file explains how to setup various demos for showing our X9.146 features in action. X9.146 is a specification of a certificate format that allows for dual public keys and signatures in a single certificate.
Traditionally, there are only public key, signature algorithm specifier and signature value. These are known as the native elements. The X9.146 scheme also allows for additional alternative public key, signature algorithm specifier and signature value as optional X.509 certificate extensions.
The X9.146 specification also specifies how to use these certificates in TLS 1.3. In the ClientHello message, a CKS extension is added. This extension specifies the ability and preference for which signature(s) is/are sent in the CertificateVerify message. The presence of the value specifies ability; the order of the values specifies preference. The following values are defined:
- NATIVE 0x01
- ALTERNATIVE 0x02
- BOTH 0x03
- EXTERNAL 0x04 (not supported)
The ServerHello message would have the extension and it would only have a single value which would be one of the ones in the list sent over by the client. That is going to specify what is sent in the CertificateVerify message. BOTH is simply the concatenation of the native and alternative signatures; native first.
Post-Quantum
Tested with these wolfSSL build options for MLDSA certificates:
./autogen.sh # If cloned from GitHub
./configure --enable-experimental --enable-dual-alg-certs --enable-dilithium --enable-debug
make
sudo make install
sudo ldconfig # required on some targets
And need to setup wolfCLU:
./autogen.sh # Cloned from GitHub
./configure
make
sudo make install
sudo ldconfig # required on some targets
In the directory where this README.md file is found, clean up previous build products and certificates and then build the applications.
make clean all
NOTE: clean removes certificates and keys in this directory.
What to Expect
There will be a lot of debug output going to stderr. On the client side, during
the call to DoTls13Certificate(), please search for the following messages to
confirm that the alternative signature was verified:
Alt signature has been verified!
Verified Peer's cert
These debug messages indicate that the client has verified the alternative post-quantum certificate chain. The second message indicates that normal verification was also successful.
On the client side, during the call to DoTls13CertificateVerify() look for
messages that indicate both conventional and post-quantum verification:
For example, if you are doing ECDSA with MLDSA, you will see the following:
Doing ECC peer cert verify
wolfSSL Entering EccVerify
wolfSSL Leaving EccVerify, return 0
Doing MLDSA peer cert verify
wolfSSL Leaving DoTls13CertificateVerify, return 0
ECDSA Demos
P-256 and MLDSA44 Demo
Generate the various conventional keys; the post-quantum key are pre-generated:
# CA
wolfssl genkey ecc -name secp256r1 -out ca-key -outform pem -output keypair
wolfssl pkey -in ca-key.priv -inform pem -out ca-key.der -outform der
wolfssl pkey -pubin -in ca-key.pub -inform pem -pubout -out ca-pubkey.der -outform der
mv ca-key.priv ca-key.pem
# Server
wolfssl genkey ecc -name secp256r1 -out server-key -outform pem -output keypair
wolfssl pkey -in server-key.priv -inform pem -out server-key.der -outform der
wolfssl pkey -in server-key.priv -inform pem -pubout -out server-pubkey.der -outform der
Generate the certificate chain:
./gen_ecdsa_mldsa_dual_keysig_root_cert 2
./gen_ecdsa_mldsa_dual_keysig_server_cert 2
Convert the DER encoded resulting certificates and keys into PEM:
wolfssl x509 -in ca-cert-pq.der -inform der -out ca-P256-mldsa44-cert.pem -outform pem
wolfssl x509 -in server-cert-pq.der -inform der -out server-P256-mldsa44-cert.pem -outform pem
mv server-key.priv server-P256-key.pem
cp ../certs/mldsa44_server_key.pem server-mldsa44-key-pq.pem
Then in wolfssl's source directory:
examples/server/server -d -v 4 -c ../wolfssl-examples/X9.146/server-P256-mldsa44-cert.pem -k ../wolfssl-examples/X9.146/server-P256-key.pem --altPrivKey ../wolfssl-examples/X9.146/server-mldsa44-key-pq.pem
examples/client/client -v 4 -A ../wolfssl-examples/X9.146/ca-P256-mldsa44-cert.pem
P-384 and MLDSA65 Demo
Generate the various conventional keys; the post-quantum key are pre-generated:
# CA
wolfssl genkey ecc -name secp384r1 -out ca-key -outform pem -output keypair
wolfssl pkey -in ca-key.priv -inform pem -out ca-key.der -outform der
wolfssl pkey -pubin -in ca-key.pub -inform pem -pubout -out ca-pubkey.der -outform der
mv ca-key.priv ca-key.pem
# Server
wolfssl genkey ecc -name secp384r1 -out server-key -outform pem -output keypair
wolfssl pkey -in server-key.priv -inform pem -out server-key.der -outform der
wolfssl pkey -in server-key.priv -inform pem -pubout -out server-pubkey.der -outform der
Generate the certificate chain:
./gen_ecdsa_mldsa_dual_keysig_root_cert 3
./gen_ecdsa_mldsa_dual_keysig_server_cert 3
Convert the DER encoded resulting certificates and keys into PEM:
wolfssl x509 -in ca-cert-pq.der -inform der -out ca-P384-mldsa65-cert.pem -outform pem
wolfssl x509 -in server-cert-pq.der -inform der -out server-P384-mldsa65-cert.pem -outform pem
mv server-key.priv server-P384-key.pem
cp ../certs/mldsa65_server_key.pem server-mldsa65-key-pq.pem
Then in wolfssl's source directory:
examples/server/server -d -v 4 -c ../wolfssl-examples/X9.146/server-P384-mldsa65-cert.pem -k ../wolfssl-examples/X9.146/server-P384-key.pem --altPrivKey ../wolfssl-examples/X9.146/server-mldsa65-key-pq.pem
examples/client/client -v 4 -A ../wolfssl-examples/X9.146/ca-P384-mldsa65-cert.pem
P-521 and MLDSA87 Demo
Generate the various conventional keys; the post-quantum key are pre-generated:
# CA
wolfssl genkey ecc -name secp521r1 -out ca-key -outform pem -output priv
wolfssl pkey -in ca-key.priv -inform pem -out ca-key.der -outform der
wolfssl pkey -in ca-key.priv -inform pem -pubout -out ca-pubkey.der -outform der
mv ca-key.priv ca-key.pem
# Server
wolfssl genkey ecc -name secp521r1 -out server-key -outform pem -output priv
wolfssl pkey -in server-key.priv -inform pem -out server-key.der -outform der
wolfssl pkey -in server-key.priv -inform pem -pubout -out server-pubkey.der -outform der
Generate the certificate chain:
./gen_ecdsa_mldsa_dual_keysig_root_cert 5
./gen_ecdsa_mldsa_dual_keysig_server_cert 5
Convert the DER encoded resulting certificates and keys into PEM:
wolfssl x509 -in ca-cert-pq.der -inform der -out ca-P521-mldsa87-cert.pem -outform pem
wolfssl x509 -in server-cert-pq.der -inform der -out server-P521-mldsa87-cert.pem -outform pem
mv server-key.priv server-P521-key.pem
cp ../certs/mldsa87_server_key.pem server-mldsa87-key-pq.pem
Then in wolfssl's source directory:
examples/server/server -d -v 4 -c ../wolfssl-examples/X9.146/server-P521-mldsa87-cert.pem -k ../wolfssl-examples/X9.146/server-P521-key.pem --altPrivKey ../wolfssl-examples/X9.146/server-mldsa87-key-pq.pem
examples/client/client -v 4 -A ../wolfssl-examples/X9.146/ca-P521-mldsa87-cert.pem
RSA Demos
RSA-3072 and MLDSA44 Demo
Generate the various conventional keys; the post-quantum key are pre-generated:
# CA
wolfssl -genkey rsa -size 3072 -out ca-key -outform der -output priv
mv ca-key.priv ca-key.der
# Server
wolfssl -genkey rsa -size 3072 -out server-key -outform der -output priv
mv server-key.priv server-key.der
Generate the certificate chain:
./gen_rsa_mldsa_dual_keysig_root_cert
./gen_rsa_mldsa_dual_keysig_server_cert
Convert the DER encoded resulting certificates and keys into PEM:
wolfssl x509 -in ca-cert-pq.der -inform der -out ca-rsa3072-mldsa44-cert.pem -outform pem
wolfssl x509 -in server-cert-pq.der -inform der -out server-rsa3072-mldsa44-cert.pem -outform pem
wolfssl pkey -in server-key.der -inform der -out server-rsa3072-key.pem -outform pem
cp ../certs/mldsa44_server_key.pem server-mldsa44-key-pq.pem
Then in wolfssl's source directory:
examples/server/server -d -v 4 -c ../wolfssl-examples/X9.146/server-rsa3072-mldsa44-cert.pem -k ../wolfssl-examples/X9.146/server-rsa3072-key.pem --altPrivKey ../wolfssl-examples/X9.146/server-mldsa44-key-pq.pem
examples/client/client -v 4 -A ../wolfssl-examples/X9.146/ca-rsa3072-mldsa44-cert.pem
Generating a Certificate Chain and Adding Alternative keys and Signatures
In the directory where this README.md file is found, build the applications:
make all
Generate the various keys:
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:3072 -out ca-key.der -outform der
openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:3072 -out server-key.der -outform der
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out alt-ca-key.der -outform der
openssl pkey -in alt-ca-key.der -inform der -pubout -out alt-ca-pub-key.der -outform der
openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out alt-server-key.der -outform der
openssl pkey -in alt-server-key.der -inform der -pubout -out alt-server-pub-key.der -outform der
Generate the certificate chain:
./gen_dual_keysig_root_cert
./gen_dual_keysig_server_cert
Convert the DER encoded resulting certificates and keys into PEM:
openssl x509 -in ./ca-cert.der -inform der -out ca-cert.pem -outform pem
openssl x509 -in ./server-cert.der -inform der -out server-cert.pem -outform pem
openssl pkey -in ./server-key.der -inform der -out server-key.pem -outform pem
openssl pkey -in ./alt-server-key.der -inform der -out alt-server-key.pem -outform pem
Note: These will not work with the TLS 1.3 demo.