Compare commits

...

10 Commits

Author SHA1 Message Date
Todd Short 39cfdcb1ee
Merge 4cc70c2732 into 296f1f6dd8 2025-07-31 01:41:08 +08:00
Michael Baentsch 296f1f6dd8 Remove unnecessary OPENSSL_NO_RSA remnants
GitHub CI / check_update (push) Waiting to run Details
GitHub CI / check_docs (push) Waiting to run Details
GitHub CI / check-c99 (push) Waiting to run Details
GitHub CI / basic_gcc (push) Waiting to run Details
GitHub CI / basic_clang (push) Waiting to run Details
GitHub CI / linux-arm64 (push) Waiting to run Details
GitHub CI / freebsd-x86_64 (push) Waiting to run Details
GitHub CI / minimal (push) Waiting to run Details
GitHub CI / no-deprecated (push) Waiting to run Details
GitHub CI / no-shared-ubuntu (push) Waiting to run Details
GitHub CI / no-shared-macos (macos-13) (push) Waiting to run Details
GitHub CI / no-shared-macos (macos-14) (push) Waiting to run Details
GitHub CI / non-caching (push) Waiting to run Details
GitHub CI / address_ub_sanitizer (push) Waiting to run Details
GitHub CI / fuzz_tests (push) Waiting to run Details
GitHub CI / memory_sanitizer (push) Waiting to run Details
GitHub CI / threads_sanitizer (push) Waiting to run Details
GitHub CI / enable_non-default_options (push) Waiting to run Details
GitHub CI / full_featured (push) Waiting to run Details
GitHub CI / no-legacy (push) Waiting to run Details
GitHub CI / legacy (push) Waiting to run Details
GitHub CI / out-of-readonly-source-and-install-ubuntu (push) Waiting to run Details
GitHub CI / out-of-readonly-source-and-install-macos (macos-13) (push) Waiting to run Details
GitHub CI / out-of-readonly-source-and-install-macos (macos-14) (push) Waiting to run Details
GitHub CI / external-tests-misc (push) Waiting to run Details
GitHub CI / external-tests-oqs-provider (push) Waiting to run Details
GitHub CI / external-tests-pkcs11-provider (push) Waiting to run Details
GitHub CI / external-tests-pyca (3.9) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-11 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-12 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-13 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-14 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-15 distro:ubuntu-22.04 llvm-ppa-name:jammy]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-16 distro:ubuntu-22.04 llvm-ppa-name:jammy]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-17 distro:ubuntu-22.04 llvm-ppa-name:jammy]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-10 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-11 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-12 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-13 distro:ubuntu-22.04 gcc-ppa-name:ubuntu-toolchain-r/test]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-9 distro:ubuntu-22.04]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:aarch64-linux-gnu fips:no libs:libc6-dev-arm64-cross target:linux-aarch64]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:alpha-linux-gnu fips:no libs:libc6.1-dev-alpha-cross target:linux-alpha-gcc]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:arm-linux-gnueabi fips:no libs:libc6-dev-armel-cross target:linux-armv4 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:arm-linux-gnueabihf fips:no libs:libc6-dev-armhf-cross target:linux-armv4 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:hppa-linux-gnu fips:no libs:libc6-dev-hppa-cross target:-static -O1 linux-generic32 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:hppa-linux-gnu libs:libc6-dev-hppa-cross target:linux-generic32 tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:i386-pc-msdosdjgpp libs:libc-djgpp-dev libwatt-djgpp-dev djgpp-utils ppa:jwt27/djgpp-toolchain target:no-threads 386 DJGPP tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:m68k-linux-gnu fips:no libs:libc6-dev-m68k-cross target:-static -m68040 linux-latomic -Wno-stringop-overflow tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:m68k-linux-gnu libs:libc6-dev-m68k-cross target:-mcfv4e -mxgot linux-latomic -Wno-stringop-overflow no-quic tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips-linux-gnu fips:no libs:libc6-dev-mips-cross target:-static linux-mips32 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips-linux-gnu libs:libc6-dev-mips-cross target:linux-mips32 tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips64-linux-gnuabi64 fips:no libs:libc6-dev-mips64-cross target:-static linux64-mips64]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips64-linux-gnuabi64 libs:libc6-dev-mips64-cross target:linux64-mips64 tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mipsel-linux-gnu fips:no libs:libc6-dev-mipsel-cross target:linux-mips32 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:powerpc64le-linux-gnu fips:no libs:libc6-dev-ppc64el-cross target:linux-ppc64le]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:riscv64-linux-gnu fips:no libs:libc6-dev-riscv64-cross target:linux64-riscv64]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:s390x-linux-gnu fips:no libs:libc6-dev-s390x-cross target:linux64-s390x]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:sh4-linux-gnu fips:no libs:libc6-dev-sh4-cross target:no-async linux-latomic tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:sparc64-linux-gnu libs:libc6-dev-sparc64-cross target:linux64-sparcv9 tests:none]) (push) Waiting to run Details
Fuzz-checker CI / fuzz-checker (map[cc:afl-clang-fast config:enable-fuzz-afl no-module install:afl++ name:AFL]) (push) Waiting to run Details
Fuzz-checker CI / fuzz-checker (map[cc:clang-18 config:enable-fuzz-libfuzzer enable-asan enable-ubsan -fno-sanitize=function -fsanitize-coverage=trace-cmp -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION extra:enable-fips enable-lms enable-ec_nistp_64_gcc_128 -fno-sanitize=al… (push) Waiting to run Details
Fuzz-checker CI / fuzz-checker (map[cc:clang-18 config:enable-fuzz-libfuzzer enable-asan enable-ubsan -fno-sanitize=function install:libfuzzer-18-dev libs:--with-fuzzer-lib=/usr/lib/llvm-18/lib/libFuzzer.a --with-fuzzer-include=/usr/include/clang/18/include/fuzzer linke… (push) Waiting to run Details
CIFuzz / Fuzzing (push) Waiting to run Details
Perl-minimal-checker CI / perl-minimal-checker (push) Waiting to run Details
Run-checker CI / run-checker (enable-trace enable-fips) (push) Waiting to run Details
Run-checker CI / run-checker (no-cmp) (push) Waiting to run Details
Run-checker CI / run-checker (no-cms) (push) Waiting to run Details
Run-checker CI / run-checker (no-default-thread-pool) (push) Waiting to run Details
Run-checker CI / run-checker (no-dgram) (push) Waiting to run Details
Run-checker CI / run-checker (no-dh) (push) Waiting to run Details
Run-checker CI / run-checker (no-dtls) (push) Waiting to run Details
Run-checker CI / run-checker (no-ec) (push) Waiting to run Details
Run-checker CI / run-checker (no-ecx) (push) Waiting to run Details
Run-checker CI / run-checker (no-http) (push) Waiting to run Details
Run-checker CI / run-checker (no-legacy) (push) Waiting to run Details
Run-checker CI / run-checker (no-ml-dsa) (push) Waiting to run Details
Run-checker CI / run-checker (no-ml-kem) (push) Waiting to run Details
Run-checker CI / run-checker (no-quic) (push) Waiting to run Details
Run-checker CI / run-checker (no-sm2) (push) Waiting to run Details
Run-checker CI / run-checker (no-sock) (push) Waiting to run Details
Run-checker CI / run-checker (no-stdio) (push) Waiting to run Details
Run-checker CI / run-checker (no-thread-pool) (push) Waiting to run Details
Run-checker CI / run-checker (no-threads) (push) Waiting to run Details
Run-checker CI / run-checker (no-tls) (push) Waiting to run Details
Run-checker CI / run-checker (no-tls1_2) (push) Waiting to run Details
Run-checker CI / run-checker (no-tls1_3) (push) Waiting to run Details
Run-checker CI / run-checker (no-ui) (push) Waiting to run Details
Run-checker merge / run-checker (enable-asan enable-ubsan no-shared no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Waiting to run Details
Run-checker merge / run-checker (enable-pie) (push) Waiting to run Details
Run-checker merge / run-checker (enable-ubsan no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Waiting to run Details
Run-checker merge / run-checker (enable-weak-ssl-ciphers) (push) Waiting to run Details
Run-checker merge / run-checker (enable-zlib) (push) Waiting to run Details
Run-checker merge / run-checker (no-dso) (push) Waiting to run Details
Run-checker merge / run-checker (no-dynamic-engine) (push) Waiting to run Details
Run-checker merge / run-checker (no-ec2m enable-fips) (push) Waiting to run Details
Run-checker merge / run-checker (no-engine no-shared) (push) Waiting to run Details
Run-checker merge / run-checker (no-err) (push) Waiting to run Details
Run-checker merge / run-checker (no-filenames) (push) Waiting to run Details
Run-checker merge / run-checker (no-integrity-only-ciphers) (push) Waiting to run Details
Run-checker merge / run-checker (no-module) (push) Waiting to run Details
Run-checker merge / run-checker (no-ocsp) (push) Waiting to run Details
Run-checker merge / run-checker (no-pinshared) (push) Waiting to run Details
Run-checker merge / run-checker (no-srp) (push) Waiting to run Details
Run-checker merge / run-checker (no-srtp) (push) Waiting to run Details
Run-checker merge / run-checker (no-ts) (push) Waiting to run Details
Run-checker merge / jitter (push) Waiting to run Details
Run-checker merge / threads_sanitizer_atomic_fallback (push) Waiting to run Details
Windows GitHub CI / shared (map[arch:amd64 config:enable-lms enable-fips no-thread-pool no-quic os:windows-2025 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat]) (push) Waiting to run Details
Windows GitHub CI / shared (map[arch:amd64 config:enable-lms enable-fips os:windows-2022 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat]) (push) Waiting to run Details
Windows GitHub CI / shared (map[arch:x86 config:--strict-warnings no-fips enable-lms os:windows-2022 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat]) (push) Waiting to run Details
Windows GitHub CI / plain (push) Waiting to run Details
Windows GitHub CI / minimal (push) Waiting to run Details
Windows GitHub CI / cygwin (windows-2022, map[arch:win64 config:-DCMAKE_C_COMPILER=gcc --strict-warnings enable-demos no-fips]) (push) Waiting to run Details
Trigger docs.openssl.org deployment / trigger (push) Has been cancelled Details
Windows Compression GitHub CI / zstd (push) Has been cancelled Details
Windows Compression GitHub CI / brotli (push) Has been cancelled Details
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28113)
2025-07-30 18:36:26 +02:00
Michael Baentsch fd7fc90346 fuzz/dtlsserver.c: Remove incorrect ifdef guard
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28102)
2025-07-30 18:31:47 +02:00
Tomas Mraz fcb5e20ac7 test_tlsext_status_type(): Avoid leaking of previously allocated data
Fixes Coverity 1659226, 1659224, 1659223

Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28105)
2025-07-30 18:29:33 +02:00
Ingo Franzki b9ff440dd6 Only report generic error if provider did not put an error on the error queue
Commit 72351b0d18 added code to unconditionally
put a generic error onto the error stack, if key generation, encryption,
decryption, sign, or verify fails to ensure that there is an error entry
on the error queue, even if the provider did not itself put a specific error
onto the queue.

However, this can hide error details if an application just looks at the very
last error entry and checks for specific errors. Now, the generic error is
always the last entry, and the application won't find the expected error
entry, although it would be there as second last entry. This can lead to
different application behavior in error situations than before this change.

To fix this, only add the generic error entry if the provider did not itself
add an error entry onto the queue. That way, there always is an error on the
error queue in case of a failure, but no behavior change in case the provider
emitted the error entry itself.

Closes: https://github.com/openssl/openssl/issues/27992

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28073)
2025-07-30 18:27:08 +02:00
Ingo Franzki f77fafd16e Make ERR_count_to_mark() available to providers via 'in' dispatch array
Functions like ERR_set_mark(), ERR_clear_last_mark(), and ERR_pop_to_mark()
are already passed to the a provider via the 'in' dispatch array of the
provider initialization function (although the documentation did not
mention them).

Also pass ERR_count_to_mark() to the provider the same way, and update
the documentation to mention all four functions.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28073)
2025-07-30 18:27:08 +02:00
Eugene Syromiatnikov f12f8cc035 Fix hanging of test_external_cf_quiche
GitHub CI / check_update (push) Waiting to run Details
GitHub CI / check_docs (push) Waiting to run Details
GitHub CI / check-c99 (push) Waiting to run Details
GitHub CI / basic_gcc (push) Waiting to run Details
GitHub CI / basic_clang (push) Waiting to run Details
GitHub CI / linux-arm64 (push) Waiting to run Details
GitHub CI / freebsd-x86_64 (push) Waiting to run Details
GitHub CI / minimal (push) Waiting to run Details
GitHub CI / no-deprecated (push) Waiting to run Details
GitHub CI / no-shared-ubuntu (push) Waiting to run Details
GitHub CI / no-shared-macos (macos-13) (push) Waiting to run Details
GitHub CI / no-shared-macos (macos-14) (push) Waiting to run Details
GitHub CI / non-caching (push) Waiting to run Details
GitHub CI / address_ub_sanitizer (push) Waiting to run Details
GitHub CI / fuzz_tests (push) Waiting to run Details
GitHub CI / memory_sanitizer (push) Waiting to run Details
GitHub CI / threads_sanitizer (push) Waiting to run Details
GitHub CI / enable_non-default_options (push) Waiting to run Details
GitHub CI / full_featured (push) Waiting to run Details
GitHub CI / no-legacy (push) Waiting to run Details
GitHub CI / legacy (push) Waiting to run Details
GitHub CI / out-of-readonly-source-and-install-ubuntu (push) Waiting to run Details
GitHub CI / out-of-readonly-source-and-install-macos (macos-13) (push) Waiting to run Details
GitHub CI / out-of-readonly-source-and-install-macos (macos-14) (push) Waiting to run Details
GitHub CI / external-tests-misc (push) Waiting to run Details
GitHub CI / external-tests-oqs-provider (push) Waiting to run Details
GitHub CI / external-tests-pkcs11-provider (push) Waiting to run Details
GitHub CI / external-tests-pyca (3.9) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-11 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-12 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-13 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-14 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-15 distro:ubuntu-22.04 llvm-ppa-name:jammy]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-16 distro:ubuntu-22.04 llvm-ppa-name:jammy]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:clang-17 distro:ubuntu-22.04 llvm-ppa-name:jammy]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-10 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-11 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-12 distro:ubuntu-22.04]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-13 distro:ubuntu-22.04 gcc-ppa-name:ubuntu-toolchain-r/test]) (push) Waiting to run Details
Compiler Zoo CI / compiler (map[cc:gcc-9 distro:ubuntu-22.04]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:aarch64-linux-gnu fips:no libs:libc6-dev-arm64-cross target:linux-aarch64]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:alpha-linux-gnu fips:no libs:libc6.1-dev-alpha-cross target:linux-alpha-gcc]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:arm-linux-gnueabi fips:no libs:libc6-dev-armel-cross target:linux-armv4 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:arm-linux-gnueabihf fips:no libs:libc6-dev-armhf-cross target:linux-armv4 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:hppa-linux-gnu fips:no libs:libc6-dev-hppa-cross target:-static -O1 linux-generic32 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:hppa-linux-gnu libs:libc6-dev-hppa-cross target:linux-generic32 tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:i386-pc-msdosdjgpp libs:libc-djgpp-dev libwatt-djgpp-dev djgpp-utils ppa:jwt27/djgpp-toolchain target:no-threads 386 DJGPP tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:m68k-linux-gnu fips:no libs:libc6-dev-m68k-cross target:-static -m68040 linux-latomic -Wno-stringop-overflow tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:m68k-linux-gnu libs:libc6-dev-m68k-cross target:-mcfv4e -mxgot linux-latomic -Wno-stringop-overflow no-quic tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips-linux-gnu fips:no libs:libc6-dev-mips-cross target:-static linux-mips32 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips-linux-gnu libs:libc6-dev-mips-cross target:linux-mips32 tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips64-linux-gnuabi64 fips:no libs:libc6-dev-mips64-cross target:-static linux64-mips64]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mips64-linux-gnuabi64 libs:libc6-dev-mips64-cross target:linux64-mips64 tests:none]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:mipsel-linux-gnu fips:no libs:libc6-dev-mipsel-cross target:linux-mips32 tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:powerpc64le-linux-gnu fips:no libs:libc6-dev-ppc64el-cross target:linux-ppc64le]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:riscv64-linux-gnu fips:no libs:libc6-dev-riscv64-cross target:linux64-riscv64]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:s390x-linux-gnu fips:no libs:libc6-dev-s390x-cross target:linux64-s390x]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:sh4-linux-gnu fips:no libs:libc6-dev-sh4-cross target:no-async linux-latomic tests:-test_includes -test_store -test_x509_store]) (push) Waiting to run Details
Cross Compile / cross-compilation (map[arch:sparc64-linux-gnu libs:libc6-dev-sparc64-cross target:linux64-sparcv9 tests:none]) (push) Waiting to run Details
Trigger docs.openssl.org deployment / trigger (push) Waiting to run Details
Fuzz-checker CI / fuzz-checker (map[cc:afl-clang-fast config:enable-fuzz-afl no-module install:afl++ name:AFL]) (push) Waiting to run Details
Fuzz-checker CI / fuzz-checker (map[cc:clang-18 config:enable-fuzz-libfuzzer enable-asan enable-ubsan -fno-sanitize=function -fsanitize-coverage=trace-cmp -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION extra:enable-fips enable-lms enable-ec_nistp_64_gcc_128 -fno-sanitize=al… (push) Waiting to run Details
Fuzz-checker CI / fuzz-checker (map[cc:clang-18 config:enable-fuzz-libfuzzer enable-asan enable-ubsan -fno-sanitize=function install:libfuzzer-18-dev libs:--with-fuzzer-lib=/usr/lib/llvm-18/lib/libFuzzer.a --with-fuzzer-include=/usr/include/clang/18/include/fuzzer linke… (push) Waiting to run Details
CIFuzz / Fuzzing (push) Waiting to run Details
Perl-minimal-checker CI / perl-minimal-checker (push) Waiting to run Details
Run-checker CI / run-checker (enable-trace enable-fips) (push) Waiting to run Details
Run-checker CI / run-checker (no-cmp) (push) Waiting to run Details
Run-checker CI / run-checker (no-cms) (push) Waiting to run Details
Run-checker CI / run-checker (no-default-thread-pool) (push) Waiting to run Details
Run-checker CI / run-checker (no-dgram) (push) Waiting to run Details
Run-checker CI / run-checker (no-dh) (push) Waiting to run Details
Run-checker CI / run-checker (no-dtls) (push) Waiting to run Details
Run-checker CI / run-checker (no-ec) (push) Waiting to run Details
Run-checker CI / run-checker (no-ecx) (push) Waiting to run Details
Run-checker CI / run-checker (no-http) (push) Waiting to run Details
Run-checker CI / run-checker (no-legacy) (push) Waiting to run Details
Run-checker CI / run-checker (no-ml-dsa) (push) Waiting to run Details
Run-checker CI / run-checker (no-ml-kem) (push) Waiting to run Details
Run-checker CI / run-checker (no-quic) (push) Waiting to run Details
Run-checker CI / run-checker (no-sm2) (push) Waiting to run Details
Run-checker CI / run-checker (no-sock) (push) Waiting to run Details
Run-checker CI / run-checker (no-stdio) (push) Waiting to run Details
Run-checker CI / run-checker (no-thread-pool) (push) Waiting to run Details
Run-checker CI / run-checker (no-threads) (push) Waiting to run Details
Run-checker CI / run-checker (no-tls) (push) Waiting to run Details
Run-checker CI / run-checker (no-tls1_2) (push) Waiting to run Details
Run-checker CI / run-checker (no-tls1_3) (push) Waiting to run Details
Run-checker CI / run-checker (no-ui) (push) Waiting to run Details
Run-checker merge / run-checker (enable-asan enable-ubsan no-shared no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Waiting to run Details
Run-checker merge / run-checker (enable-pie) (push) Waiting to run Details
Run-checker merge / run-checker (enable-ubsan no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Waiting to run Details
Run-checker merge / run-checker (enable-weak-ssl-ciphers) (push) Waiting to run Details
Run-checker merge / run-checker (enable-zlib) (push) Waiting to run Details
Run-checker merge / run-checker (no-dso) (push) Waiting to run Details
Run-checker merge / run-checker (no-dynamic-engine) (push) Waiting to run Details
Run-checker merge / run-checker (no-ec2m enable-fips) (push) Waiting to run Details
Run-checker merge / run-checker (no-engine no-shared) (push) Waiting to run Details
Run-checker merge / run-checker (no-err) (push) Waiting to run Details
Run-checker merge / run-checker (no-filenames) (push) Waiting to run Details
Run-checker merge / run-checker (no-integrity-only-ciphers) (push) Waiting to run Details
Run-checker merge / run-checker (no-module) (push) Waiting to run Details
Run-checker merge / run-checker (no-ocsp) (push) Waiting to run Details
Run-checker merge / run-checker (no-pinshared) (push) Waiting to run Details
Run-checker merge / run-checker (no-srp) (push) Waiting to run Details
Run-checker merge / run-checker (no-srtp) (push) Waiting to run Details
Run-checker merge / run-checker (no-ts) (push) Waiting to run Details
Run-checker merge / jitter (push) Waiting to run Details
Run-checker merge / threads_sanitizer_atomic_fallback (push) Waiting to run Details
Windows GitHub CI / shared (map[arch:amd64 config:enable-lms enable-fips no-thread-pool no-quic os:windows-2025 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat]) (push) Waiting to run Details
Windows GitHub CI / shared (map[arch:amd64 config:enable-lms enable-fips os:windows-2022 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat]) (push) Waiting to run Details
Windows GitHub CI / shared (map[arch:x86 config:--strict-warnings no-fips enable-lms os:windows-2022 vcvars:C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat]) (push) Waiting to run Details
Windows GitHub CI / plain (push) Waiting to run Details
Windows GitHub CI / minimal (push) Waiting to run Details
Windows GitHub CI / cygwin (windows-2022, map[arch:win64 config:-DCMAKE_C_COMPILER=gcc --strict-warnings enable-demos no-fips]) (push) Waiting to run Details
Windows Compression GitHub CI / zstd (push) Waiting to run Details
Windows Compression GitHub CI / brotli (push) Waiting to run Details
The commit "Remove HARNESS_OSSL_PREFIX manipulation in the test harness"
forced all the output to be processed by the test harness, which means
that any process that keeps the stdout FD open prevents the run() call
from finishing, as was the case in the test_external_cf_quiche test that
ran quiche server in the background, but retaining the std{in,out,err}
descriptors.  Avoid that by explicitly redirecting them to a log file.

Reported-by: Tomas Mraz <tomas@openssl.org>
Fixes: 70c05fcde5 "Remove HARNESS_OSSL_PREFIX manipulation in the test harness"
Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org>

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28125)
2025-07-30 16:04:55 +02:00
Todd Short 4cc70c2732
fixup! Add client-side session caching 2025-03-28 11:06:02 -04:00
Todd Short 5623de77bb
fixup! Add client-side session caching 2025-03-27 18:59:08 -04:00
Todd Short 8cca50ce54
Add client-side session caching
Add support for client-side caching.
Uses an application defined "cache_id" to identify a connection.
This cache_id may be an IP address, DNS name or anything else the
client wishes to use.
2025-03-25 11:21:45 -04:00
30 changed files with 841 additions and 41 deletions

View File

@ -93,7 +93,6 @@ EOF
my %cmd_disabler = (
ciphers => "sock",
genrsa => "rsa",
gendsa => "dsa",
dsaparam => "dsa",
gendh => "dh",
@ -107,7 +106,7 @@ EOF
# [2] = preprocessor conditional for excluding irrespective of deprecation
# rsa => [ "pkey", "3_0", "rsa" ],
# genrsa => [ "genpkey", "3_0", "rsa" ],
rsautl => [ "pkeyutl", "3_0", "rsa" ],
rsautl => [ "pkeyutl", "3_0", "" ],
# dhparam => [ "pkeyparam", "3_0", "dh" ],
# dsaparam => [ "pkeyparam", "3_0", "dsa" ],
# dsa => [ "pkey", "3_0", "dsa" ],

View File

@ -1355,6 +1355,7 @@ SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT:272:\
attempt to reuse session in different context
SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE:158:\
at least (D)TLS 1.2 needed in Suite B mode
SSL_R_BAD_CACHE_MODE:424:bad cache mode
SSL_R_BAD_CERTIFICATE:348:bad certificate
SSL_R_BAD_CHANGE_CIPHER_SPEC:103:bad change cipher spec
SSL_R_BAD_CIPHER:186:bad cipher
@ -1526,6 +1527,7 @@ SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate
SSL_R_NOT_SERVER:284:not server
SSL_R_NO_APPLICATION_PROTOCOL:235:no application protocol
SSL_R_NO_CACHE_ID_ON_SERVER:425:no cache id on server
SSL_R_NO_CERTIFICATES_RETURNED:176:no certificates returned
SSL_R_NO_CERTIFICATE_ASSIGNED:177:no certificate assigned
SSL_R_NO_CERTIFICATE_SET:179:no certificate set
@ -1599,6 +1601,8 @@ SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING:345:scsv received when renegotiating
SSL_R_SCT_VERIFICATION_FAILED:208:sct verification failed
SSL_R_SEQUENCE_CTR_WRAPPED:327:sequence ctr wrapped
SSL_R_SERVERHELLO_TLSEXT:275:serverhello tlsext
SSL_R_SESSION_ALREADY_IN_CACHE:426:session already in cache
SSL_R_SESSION_ALREADY_SET:427:session already set
SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED:277:session id context uninitialized
SSL_R_SHUTDOWN_WHILE_IN_INIT:407:shutdown while in init
SSL_R_SIGNATURE_ALGORITHMS_ERROR:360:signature algorithms error

View File

@ -261,10 +261,12 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
cipher = ctx->op.ciph.cipher;
desc = cipher->description != NULL ? cipher->description : "";
ERR_set_mark();
ret = cipher->encrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
if (ret <= 0)
if (ret <= 0 && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
"%s encrypt:%s", cipher->type_name, desc);
ERR_clear_last_mark();
return ret;
legacy:
@ -309,10 +311,12 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
cipher = ctx->op.ciph.cipher;
desc = cipher->description != NULL ? cipher->description : "";
ERR_set_mark();
ret = cipher->decrypt(ctx->op.ciph.algctx, out, outlen, (out == NULL ? 0 : *outlen), in, inlen);
if (ret <= 0)
if (ret <= 0 && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE,
"%s decrypt:%s", cipher->type_name, desc);
ERR_clear_last_mark();
return ret;

View File

@ -460,10 +460,12 @@ void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
return NULL;
}
ERR_set_mark();
ret = keymgmt->gen(genctx, cb, cbarg);
if (ret == NULL)
if (ret == NULL && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_KEYMGMT_FAILURE,
"%s key generation:%s", keymgmt->type_name, desc);
ERR_clear_last_mark();
return ret;
}

View File

@ -426,10 +426,12 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
return 0;
}
ERR_set_mark();
ret = signature->digest_sign_update(pctx->op.sig.algctx, data, dsize);
if (ret <= 0)
if (ret <= 0 && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_sign_update:%s", signature->type_name, desc);
ERR_clear_last_mark();
return ret;
legacy:
@ -474,10 +476,12 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
return 0;
}
ERR_set_mark();
ret = signature->digest_verify_update(pctx->op.sig.algctx, data, dsize);
if (ret <= 0)
if (ret <= 0 && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_verify_update:%s", signature->type_name, desc);
ERR_clear_last_mark();
return ret;
legacy:
@ -527,11 +531,13 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
pctx = dctx;
}
ERR_set_mark();
r = signature->digest_sign_final(pctx->op.sig.algctx, sigret, siglen,
sigret == NULL ? 0 : *siglen);
if (!r)
if (!r && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_sign_final:%s", signature->type_name, desc);
ERR_clear_last_mark();
if (dctx == NULL && sigret != NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@ -638,11 +644,13 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
if (sigret != NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
ERR_set_mark();
ret = signature->digest_sign(pctx->op.sig.algctx, sigret, siglen,
sigret == NULL ? 0 : *siglen, tbs, tbslen);
if (ret <= 0)
if (ret <= 0 && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_sign:%s", signature->type_name, desc);
ERR_clear_last_mark();
return ret;
}
} else {
@ -693,10 +701,12 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
pctx = dctx;
}
ERR_set_mark();
r = signature->digest_verify_final(pctx->op.sig.algctx, sig, siglen);
if (!r)
if (!r && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_verify_final:%s", signature->type_name, desc);
ERR_clear_last_mark();
if (dctx == NULL)
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
else
@ -769,10 +779,12 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
int ret;
ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
ERR_set_mark();
ret = signature->digest_verify(pctx->op.sig.algctx, sigret, siglen, tbs, tbslen);
if (ret <= 0)
if (ret <= 0 && ERR_count_to_mark() == 0)
ERR_raise_data(ERR_LIB_EVP, EVP_R_PROVIDER_SIGNATURE_FAILURE,
"%s digest_verify:%s", signature->type_name, desc);
ERR_clear_last_mark();
return ret;
}
} else {

View File

@ -2419,6 +2419,11 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle)
return ERR_pop_to_mark();
}
static int core_count_to_mark(const OSSL_CORE_HANDLE *handle)
{
return ERR_count_to_mark();
}
static void core_indicator_get_callback(OPENSSL_CORE_CTX *libctx,
OSSL_INDICATOR_CALLBACK **cb)
{
@ -2600,6 +2605,7 @@ static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK,
(void (*)(void))core_clear_last_error_mark },
{ OSSL_FUNC_CORE_POP_ERROR_TO_MARK, (void (*)(void))core_pop_error_to_mark },
{ OSSL_FUNC_CORE_COUNT_TO_MARK, (void (*)(void))core_count_to_mark },
{ OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))ossl_core_bio_new_file },
{ OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))ossl_core_bio_new_mem_buf },
{ OSSL_FUNC_BIO_READ_EX, (void (*)(void))ossl_core_bio_read_ex },

View File

@ -23,6 +23,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
"attempt to reuse session in different context"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE),
"at least (D)TLS 1.2 needed in Suite B mode"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CACHE_MODE), "bad cache mode"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CERTIFICATE), "bad certificate"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CHANGE_CIPHER_SPEC),
"bad change cipher spec"},
@ -292,6 +293,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_SERVER), "not server"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_APPLICATION_PROTOCOL),
"no application protocol"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CACHE_ID_ON_SERVER),
"no cache id on server"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATES_RETURNED),
"no certificates returned"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATE_ASSIGNED),
@ -407,6 +410,10 @@ static const ERR_STRING_DATA SSL_str_reasons[] = {
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SEQUENCE_CTR_WRAPPED),
"sequence ctr wrapped"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ALREADY_IN_CACHE),
"session already in cache"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ALREADY_SET),
"session already set"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),
"session id context uninitialized"},
{ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHUTDOWN_WHILE_IN_INIT),

View File

@ -2783,6 +2783,10 @@ DEPEND[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod
GENERATE[html/man3/SSL_session_reused.html]=man3/SSL_session_reused.pod
DEPEND[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod
GENERATE[man/man3/SSL_session_reused.3]=man3/SSL_session_reused.pod
DEPEND[html/man3/SSL_set1_cache_id.html]=man3/SSL_set1_cache_id.pod
GENERATE[html/man3/SSL_set1_cache_id.html]=man3/SSL_set1_cache_id.pod
DEPEND[man/man3/SSL_set1_cache_id.3]=man3/SSL_set1_cache_id.pod
GENERATE[man/man3/SSL_set1_cache_id.3]=man3/SSL_set1_cache_id.pod
DEPEND[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod
GENERATE[html/man3/SSL_set1_host.html]=man3/SSL_set1_host.pod
DEPEND[man/man3/SSL_set1_host.3]=man3/SSL_set1_host.pod
@ -3747,6 +3751,7 @@ html/man3/SSL_read.html \
html/man3/SSL_read_early_data.html \
html/man3/SSL_rstate_string.html \
html/man3/SSL_session_reused.html \
html/man3/SSL_set1_cache_id.html \
html/man3/SSL_set1_host.html \
html/man3/SSL_set1_initial_peer_addr.html \
html/man3/SSL_set1_server_cert_type.html \
@ -4419,6 +4424,7 @@ man/man3/SSL_read.3 \
man/man3/SSL_read_early_data.3 \
man/man3/SSL_rstate_string.3 \
man/man3/SSL_session_reused.3 \
man/man3/SSL_set1_cache_id.3 \
man/man3/SSL_set1_host.3 \
man/man3/SSL_set1_initial_peer_addr.3 \
man/man3/SSL_set1_server_cert_type.3 \

View File

@ -14,9 +14,9 @@ SSL_CTX_sess_set_new_cb, SSL_CTX_sess_set_remove_cb, SSL_CTX_sess_set_get_cb, SS
void (*remove_session_cb)(SSL_CTX *ctx,
SSL_SESSION *));
void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
SSL_SESSION (*get_session_cb)(SSL *,
const unsigned char *,
int, int *));
SSL_SESSION (*get_session_cb)(SSL *ssl,
const unsigned char *data,
int len, int *copy));
int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl,
SSL_SESSION *sess);
@ -86,7 +86,7 @@ for all sessions in the internal session cache when
L<SSL_CTX_free(3)> is called. The remove_session_cb() is passed
the B<ctx> and the ssl session B<sess>. It does not provide any feedback.
The get_session_cb() is only called on SSL/TLS servers, and is given
The get_session_cb() is called on SSL/TLS servers, and is given
the session id
proposed by the client. The get_session_cb() is always called, even when
session caching was disabled. The get_session_cb() is passed the
@ -98,6 +98,16 @@ If the get_session_cb() does not write to B<copy>, the reference count
is incremented and the session must be explicitly freed with
L<SSL_SESSION_free(3)>.
The get_session_cb() is called on SSL/TLS clients with the application-defined
cache identifier set by the client. The get_session_cb() is always called when
session caching is disabled. The get_session_cb() is passed the
B<ssl> connection, the cache identifier of length B<length> at the memory location
B<data>. With the parameter B<copy> the callback can require the
library to increment the reference count of the SSL_SESSION object,
Normally the reference count is not incremented and therefore the
session must not be explicitly freed with
L<SSL_SESSION_free(3)>.
=head1 RETURN VALUES
SSL_CTX_sess_get_new_cb(), SSL_CTX_sess_get_remove_cb() and SSL_CTX_sess_get_get_cb()
@ -109,11 +119,13 @@ L<ssl(7)>, L<d2i_SSL_SESSION(3)>,
L<SSL_CTX_set_session_cache_mode(3)>,
L<SSL_CTX_flush_sessions(3)>,
L<SSL_SESSION_free(3)>,
L<SSL_CTX_free(3)>
L<SSL_CTX_free(3)>,
L<SSL_get1_previous_client_session(3)>,
L<SSL_set1_cache_id(3)>
=head1 COPYRIGHT
Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy

View File

@ -49,12 +49,16 @@ No session caching for client or server takes place.
=item SSL_SESS_CACHE_CLIENT
Client sessions are added to the session cache. As there is no reliable way
for the OpenSSL library to know whether a session should be reused or which
session to choose (due to the abstract BIO layer the SSL engine does not
have details about the connection), the application must select the session
to be reused by using the L<SSL_set_session(3)>
function. This option is not activated by default.
Client sessions are added to the session cache. Sessions are identified by their
cache identifier set via L<SSL_set1_cache_id(3)> when they are created by an SSL.
This cache identifier must be set before calling L<SSL_connect(3)>.
The application then can retrieve prior sessions via L<SSL_get1_previous_client_session(3)>.
After the session has been retrieved, it may be examined to determine whether
it can (or should) be used. The session must then be applied to the SSL object via the
L<SSL_set_session(3)> before it can be used during L<SSL_connect(3)>.
This option is not activated by default.
=item SSL_SESS_CACHE_SERVER
@ -64,10 +68,19 @@ the internal session cache (unless SSL_SESS_CACHE_NO_INTERNAL_LOOKUP is set),
then (second) in the external cache if available. If the session is found, the
server will try to reuse the session. This is the default.
Servers must not use L<SSL_set1_cache_id(3)>, otherwise, the session will not be
found in the cache.
=item SSL_SESS_CACHE_BOTH
Enable both SSL_SESS_CACHE_CLIENT and SSL_SESS_CACHE_SERVER at the same time.
Servers must not use L<SSL_set1_cache_id(3)>, otherwise, the session will not be
found in the cache.
Clients must use L<SSL_set1_cache_id(3)> in order for sessions to be found in the cache
via L<SSL_get1_previous_client_session(3)>.
=item SSL_SESS_CACHE_NO_AUTO_CLEAR
Normally the session cache is checked for expired sessions every
@ -121,22 +134,25 @@ SSL_CTX_set_session_cache_mode() returns the previously set cache mode.
SSL_CTX_get_session_cache_mode() returns the currently set cache mode.
=head1 SEE ALSO
L<ssl(7)>, L<SSL_set_session(3)>,
L<SSL_session_reused(3)>,
L<SSL_get0_cache_id(3)>,
L<SSL_set1_cache_id(3)>,
L<SSL_get1_previous_client_session(3)>,
L<SSL_CTX_add_session(3)>,
L<SSL_CTX_sess_number(3)>,
L<SSL_CTX_sess_set_cache_size(3)>,
L<SSL_CTX_sess_set_get_cb(3)>,
L<SSL_CTX_set_session_id_context(3)>,
L<SSL_CTX_set_timeout(3)>,
L<SSL_CTX_flush_sessions(3)>
L<SSL_CTX_flush_sessions(3)>,
L<SSL_connect(3)>
=head1 COPYRIGHT
Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy

View File

@ -2,7 +2,8 @@
=head1 NAME
SSL_CTX_set_session_id_context, SSL_set_session_id_context - set context within which session can be reused (server side only)
SSL_CTX_set_session_id_context, SSL_set_session_id_context
- set context within which session can be reused (server side only)
=head1 SYNOPSIS
@ -82,7 +83,7 @@ L<ssl(7)>
=head1 COPYRIGHT
Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy

View File

@ -0,0 +1,117 @@
=pod
=head1 NAME
SSL_set1_cache_id,
SSL_get1_cache_id,
SSL_SESSION_set1_cache_id,
SSL_SESSION_get1_cache_id,
SSL_get1_previous_client_session - use application-defined cache identifier for session caching
=head1 SYNOPSIS
#include <openssl/ssl.h>
int SSL_set1_cache_id(SSL *s, const unsigned char *data, size_t len);
int SSL_get1_cache_id(const SSL *s, const unsigned char **data, size_t *len);
int SSL_SESSION_set1_cache_id(SSL_SESSION *ss, const unsigned char *data, size_t len);
int SSL_SESSION_get1_cache_id(const SSL_SESSION *ss, const unsigned char **data, size_t *len);
int SSL_get1_previous_client_session(SSL *s, int flags);
=head1 DESCRIPTION
SSL_set1_cache_id() sets the cache identifier specified by B<data> and B<len>
into B<s>. This cache identifier is application-defined, and can be a domain
name, IP address, port or other identifier.
SSL_get1_cache_id() returns the cache identifier of B<s> into the B<data> and
B<len> variables. The cache identifier is application-defined.
SSL_SESSION_set1_cache_id() sets the cache identifier specified by B<data> and B<len>
into B<ss>. This cache identifier is application-defined.
SSL_SESSION_get1_cache_id() returns the cache identifier of B<ss> into the B<data> and
B<len> variables. The cache identifier is application-defined.
SSL_get1_previous_client_session() is used to search for and return a
SSL_SESSION in the session cache. A cache identifier must first be set
via SSL_set1_cache_id().
=head1 NOTES
The OpenSSL library can store/retrieve SSL/TLS sessions for later reuse.
The sessions can be held in memory for each B<ctx>; if more than one
SSL_CTX object is being maintained, the sessions are unique for each SSL_CTX
object. The cache mode must be set to SSL_SESS_CACHE_CLIENT via
L<SSL_CTX_set_session_cache_mode(3)> in order to use application-defined
cache identifiers. When the cache mode is set to SSL_SESSION_CACHE_SERVER or
SSL_SESSION_CACHE_BOTH, session IDs are used as the cache identifier.
To reuse a client session, use the SSL_set1_cache_id() function to specify the
cache identifier of the server that the client is attempting to connect to. Set the
optional session ID context via L<SSL_CTX_set_session_id_context(3)> or
L<SSL_set_session_id_context(3)> before calling SSL_get1_previous_client_session().
After the session has been retrieved, it may be examined to determine whether
it can (or should) be used. The session must then be applied to the SSL object via the
L<SSL_set_session(3)> before it can be used during L<SSL_connect(3)>.
The session cache that is searched is specified by the SSL_CTX used in
L<SSL_new(3)>. The SSL_CTX set via L<SSL_set_SSL_CTX(3)> is not used
for the session cache.
SSL_SESSION_set1_cache_id() will fail if the B<ss> is already in a cache. This
function can only be used on non-cached SSL_SESSIONs.
SSL_set1_cache_id() and SSL_SESSION_set1_cache_id() should not be used by servers,
the functions will fail.
The memory returned by SSL_get1_cache_id() and SSL_SESSION_get1_cache_id() must be freed.
=head1 RETURN VALUES
The SSL_set1_cache_id(), SSL_get1_cache_id(), SSL_SESSION_set1_cache_id() and
SSL_SESSION_get1_cache_id() functions return 1 on success, 0 on failure.
The SSL_get1_cache_id() function fills in the B<data> and B<len> parameters
with the data from the B<s>.
The SSL_get_previous_client_session() returns an SSL_SESSION on success, or NULL on
failure. The error stack should be checked on error.
=head1 SEE ALSO
L<SSL_set_session(3)>
L<SSL_session_reused(3)>
L<SSL_CTX_add_session(3)>
L<SSL_CTX_sess_number(3)>
L<SSL_CTX_sess_set_cache_size(3)>
L<SSL_CTX_sess_set_get_cb(3)>
L<SSL_CTX_set_session_id_context(3)>
L<SSL_CTX_set_timeout(3)>
L<SSL_CTX_flush_sessions(3)>
L<SSL_CTX_set_session_cache_mode(3)>,
L<SSL_connect(3)>,
L<SSL_new(3)>,
L<SSL_set_SSL_CTX(3)>,
=head1 HISTORY
The SSL_set1_cache_id(),
SSL_get1_cache_id(),
SSL_SESSION_set1_cache_id(),
SSL_SESSION_get1_cache_id(), and
SSL_get1_previous_client_session() functions were added in OpenSSL 3.5.
=head1 COPYRIGHT
Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -154,6 +154,10 @@ provider):
core_new_error OSSL_FUNC_CORE_NEW_ERROR
core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG
core_vset_error OSSL_FUNC_CORE_VSET_ERROR
core_set_error_mark OSSL_FUNC_CORE_SET_ERROR_MARK
core_clear_last_error_mark OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK
core_pop_error_to_mark OSSL_FUNC_CORE_POP_ERROR_TO_MARK
core_count_to_mark OSSL_FUNC_CORE_COUNT_TO_MARK
core_obj_add_sigid OSSL_FUNC_CORE_OBJ_ADD_SIGID
core_obj_create OSSL_FUNC_CORE_OBJ_CREATE
CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC
@ -270,6 +274,33 @@ error occurred or was reported.
This corresponds to the OpenSSL function L<ERR_vset_error(3)>.
=item core_set_error_mark()
sets a mark on the current topmost error record if there is one.
This corresponds to the OpenSSL function L<ERR_set_mark(3)>.
=item core_clear_last_error_mark()
removes the last mark added if there is one.
This corresponds to the OpenSSL function L<ERR_clear_last_mark(3)>.
=item core_pop_error_to_mark()
pops the top of the error stack until a mark is found. The mark is then removed.
If there is no mark, the whole stack is removed.
This corresponds to the OpenSSL function L<ERR_pop_to_mark(3)>.
=item core_count_to_mark()
returns the number of entries on the error stack above the most recently
marked entry, not including that entry. If there is no mark in the error stack,
the number of entries in the error stack is returned.
This corresponds to the OpenSSL function L<ERR_count_to_mark(3)>.
=back
The core_obj_create() function registers a new OID and associated short name

View File

@ -590,10 +590,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)
SSL *server;
BIO *in;
BIO *out;
#if !defined(OPENSSL_NO_EC) \
|| (!defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0))
BIO *bio_buf;
#endif
SSL_CTX *ctx;
int ret;
#ifndef OPENSSL_NO_DEPRECATED_3_0

View File

@ -253,6 +253,10 @@ OSSL_CORE_MAKE_FUNC(int, provider_up_ref,
OSSL_CORE_MAKE_FUNC(int, provider_free,
(const OSSL_CORE_HANDLE *prov, int deactivate))
/* Additional error functions provided by the core */
# define OSSL_FUNC_CORE_COUNT_TO_MARK 120
OSSL_CORE_MAKE_FUNC(int, core_count_to_mark, (const OSSL_CORE_HANDLE *prov))
/* Functions provided by the provider to the Core, reserved numbers 1024-1535 */
# define OSSL_FUNC_PROVIDER_TEARDOWN 1024
OSSL_CORE_MAKE_FUNC(void, provider_teardown, (void *provctx))

View File

@ -1828,6 +1828,7 @@ int SSL_up_ref(SSL *s);
int SSL_is_dtls(const SSL *s);
int SSL_is_tls(const SSL *s);
int SSL_is_quic(const SSL *s);
__owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
unsigned int sid_ctx_len);
@ -2829,7 +2830,6 @@ typedef unsigned int (*DTLS_timer_cb)(SSL *s, unsigned int timer_us);
void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb);
typedef int (*SSL_allow_early_data_cb_fn)(SSL *s, void *arg);
void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx,
SSL_allow_early_data_cb_fn cb,
@ -2887,6 +2887,14 @@ int SSL_set_quic_tls_transport_params(SSL *s,
int SSL_set_quic_tls_early_data_enabled(SSL *s, int enabled);
/* Client cache implementation */
__owur SSL_SESSION *SSL_get1_previous_client_session(SSL *s);
__owur int SSL_set1_cache_id(SSL *s, const unsigned char *data, size_t len);
__owur int SSL_get1_cache_id(const SSL *s, unsigned char **data, size_t *len);
__owur int SSL_SESSION_set1_cache_id(SSL_SESSION *ss, const unsigned char *data, size_t len);
__owur int SSL_SESSION_get1_cache_id(const SSL_SESSION *ss, unsigned char **data,
size_t *len);
# ifdef __cplusplus
}
# endif

View File

@ -25,6 +25,7 @@
# define SSL_R_APP_DATA_IN_HANDSHAKE 100
# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
# define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158
# define SSL_R_BAD_CACHE_MODE 424
# define SSL_R_BAD_CERTIFICATE 348
# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103
# define SSL_R_BAD_CIPHER 186
@ -190,6 +191,7 @@
# define SSL_R_NOT_REPLACING_CERTIFICATE 289
# define SSL_R_NOT_SERVER 284
# define SSL_R_NO_APPLICATION_PROTOCOL 235
# define SSL_R_NO_CACHE_ID_ON_SERVER 425
# define SSL_R_NO_CERTIFICATES_RETURNED 176
# define SSL_R_NO_CERTIFICATE_ASSIGNED 177
# define SSL_R_NO_CERTIFICATE_SET 179
@ -260,6 +262,8 @@
# define SSL_R_SCT_VERIFICATION_FAILED 208
# define SSL_R_SEQUENCE_CTR_WRAPPED 327
# define SSL_R_SERVERHELLO_TLSEXT 275
# define SSL_R_SESSION_ALREADY_IN_CACHE 426
# define SSL_R_SESSION_ALREADY_SET 427
# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407
# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360

View File

@ -65,6 +65,7 @@ static OSSL_FUNC_core_vset_error_fn *c_vset_error;
static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark;
static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark;
static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark;
static OSSL_FUNC_core_count_to_mark_fn *c_count_to_mark;
static OSSL_FUNC_CRYPTO_malloc_fn *c_CRYPTO_malloc;
static OSSL_FUNC_CRYPTO_zalloc_fn *c_CRYPTO_zalloc;
static OSSL_FUNC_CRYPTO_free_fn *c_CRYPTO_free;
@ -834,6 +835,9 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
case OSSL_FUNC_CORE_POP_ERROR_TO_MARK:
set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(in));
break;
case OSSL_FUNC_CORE_COUNT_TO_MARK:
set_func(c_count_to_mark, OSSL_FUNC_core_count_to_mark(in));
break;
case OSSL_FUNC_CRYPTO_MALLOC:
set_func(c_CRYPTO_malloc, OSSL_FUNC_CRYPTO_malloc(in));
break;
@ -1072,6 +1076,11 @@ int ERR_pop_to_mark(void)
return c_pop_error_to_mark(NULL);
}
int ERR_count_to_mark(void)
{
return c_count_to_mark != NULL ? c_count_to_mark(NULL) : 0;
}
/*
* This must take a library context, since it's called from the depths
* of crypto/initthread.c code, where it's (correctly) assumed that the

View File

@ -48,6 +48,7 @@ static OSSL_FUNC_core_vset_error_fn *c_vset_error;
static OSSL_FUNC_core_set_error_mark_fn *c_set_error_mark;
static OSSL_FUNC_core_clear_last_error_mark_fn *c_clear_last_error_mark;
static OSSL_FUNC_core_pop_error_to_mark_fn *c_pop_error_to_mark;
static OSSL_FUNC_core_count_to_mark_fn *c_count_to_mark;
#endif
/* Parameters we provide to the core */
@ -234,6 +235,9 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
case OSSL_FUNC_CORE_POP_ERROR_TO_MARK:
set_func(c_pop_error_to_mark, OSSL_FUNC_core_pop_error_to_mark(tmp));
break;
case OSSL_FUNC_CORE_COUNT_TO_MARK:
set_func(c_count_to_mark, OSSL_FUNC_core_count_to_mark(in));
break;
}
}
#endif
@ -301,4 +305,9 @@ int ERR_pop_to_mark(void)
{
return c_pop_error_to_mark(NULL);
}
int ERR_count_to_mark(void)
{
return c_count_to_mark != NULL ? c_count_to_mark(NULL) : 0;
}
#endif

View File

@ -1102,6 +1102,7 @@ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
if (sc == NULL || id_len > sizeof(r.session_id))
return 0;
r.cache_id = NULL;
r.ssl_version = sc->version;
r.session_id_length = id_len;
memcpy(r.session_id, id, id_len);
@ -1518,6 +1519,7 @@ void ossl_ssl_connection_free(SSL *ssl)
OPENSSL_free(s->clienthello->pre_proc_exts);
OPENSSL_free(s->clienthello);
OPENSSL_free(s->pha_context);
OPENSSL_free(s->cache_id);
EVP_MD_CTX_free(s->pha_dgst);
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
@ -2233,6 +2235,8 @@ int SSL_accept(SSL *s)
int SSL_connect(SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
SSL_SESSION *sess;
int ret;
#ifndef OPENSSL_NO_QUIC
if (IS_QUIC(s))
@ -2247,6 +2251,24 @@ int SSL_connect(SSL *s)
SSL_set_connect_state(s);
}
/*
* If a client session has not been set, and there's a previous session
* that matches the cache_id, use it.
* If the cache is not set to client mode, an error will be raised, so
* pop off as necessary.
*/
if (sc->session == NULL && sc->cache_id != NULL) {
ERR_set_mark();
sess = SSL_get1_previous_client_session(s);
ERR_pop_to_mark();
if (sess != NULL) {
ret = SSL_set_session(s, sess);
SSL_SESSION_free(sess);
if (!ret)
return ret;
}
}
return SSL_do_handshake(s);
}
@ -3886,9 +3908,24 @@ int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
const unsigned char *session_id = a->session_id;
unsigned long l;
unsigned long l = 0;
unsigned char tmp_storage[4];
size_t i;
/* if cache_id set, use that (assume client-side cache) */
if (a->cache_id != NULL) {
/* Hash the session id context */
for (i = 0; i < a->sid_ctx_length; i++)
l ^= (long)a->sid_ctx[i] << ((i & (sizeof(l)-1)) * 8);
/* hash the cache id */
for (i = 0; i < a->cache_id_len; i++)
l ^= (long)a->cache_id[i] << ((i & (sizeof(l)-1)) * 8);
return l;
}
/* hash session id (assume server-side cache) */
if (a->session_id_length < sizeof(tmp_storage)) {
memset(tmp_storage, 0, sizeof(tmp_storage));
memcpy(tmp_storage, a->session_id, a->session_id_length);
@ -3906,12 +3943,29 @@ static unsigned long ssl_session_hash(const SSL_SESSION *a)
/*
* NB: If this function (or indeed the hash function which uses a sort of
* coarser function than this one) is changed, ensure
* SSL_CTX_has_matching_session_id() is checked accordingly. It relies on
* SSL_has_matching_session_id() is checked accordingly. It relies on
* being able to construct an SSL_SESSION that will collide with any existing
* session with a matching session ID.
*/
static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
{
/* if both have cache_id set, use that (assume client-side cache) */
if (a->cache_id != NULL && b->cache_id != NULL) {
if (a->cache_id_len != b->cache_id_len
|| memcmp(a->cache_id, b->cache_id, a->cache_id_len) != 0)
return 1;
if (a->sid_ctx_length != b->sid_ctx_length)
return 1;
if (a->sid_ctx_length > 0
&& memcmp(a->sid_ctx, b->sid_ctx, a->sid_ctx_length) != 0)
return 1;
return 0;
}
/* if only one has a cache_id, it's not a match */
if (a->cache_id != NULL || b->cache_id != NULL)
return 1;
/* compare session id (assume server-side cache) */
if (a->ssl_version != b->ssl_version)
return 1;
if (a->session_id_length != b->session_id_length)
@ -5031,6 +5085,10 @@ void SSL_set_accept_state(SSL *s)
#endif
sc->server = 1;
/* Don't use cache_id with servers */
OPENSSL_free(sc->cache_id);
sc->cache_id = NULL;
sc->cache_id_len = 0;
sc->shutdown = 0;
ossl_statem_clear(sc);
sc->handshake_func = s->method->ssl_accept;
@ -5268,6 +5326,10 @@ SSL *SSL_dup(SSL *s)
|| !dup_ca_names(&retsc->client_ca_names, sc->client_ca_names))
goto err;
if (sc->cache_id != NULL)
if ((retsc->cache_id = OPENSSL_memdup(sc->cache_id, sc->cache_id_len)) == NULL)
goto err;
return ret;
err:

View File

@ -551,6 +551,8 @@ struct ssl_session_st {
# ifndef OPENSSL_NO_SRP
char *srp_username;
# endif
unsigned char *cache_id;
size_t cache_id_len;
unsigned char *ticket_appdata;
size_t ticket_appdata_len;
uint32_t flags;
@ -1845,6 +1847,9 @@ struct ssl_connection_st {
SSL_async_callback_fn async_cb;
void *async_cb_arg;
/* Client cache data */
unsigned char *cache_id;
size_t cache_id_len;
/*
* Signature algorithms shared by client and server: cached because these
* are used most often.

View File

@ -165,6 +165,7 @@ static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
dest->peer = NULL;
dest->peer_rpk = NULL;
dest->ticket_appdata = NULL;
dest->cache_id = NULL;
memset(&dest->ex_data, 0, sizeof(dest->ex_data));
/* As the copy is not in the cache, we remove the associated pointers */
@ -261,6 +262,13 @@ static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
goto err;
}
if (src->cache_id != NULL) {
dest->cache_id =
OPENSSL_memdup(src->cache_id, src->cache_id_len);
if (dest->cache_id == NULL)
goto err;
}
return dest;
err:
SSL_SESSION_free(dest);
@ -480,6 +488,10 @@ int ssl_get_new_session(SSL_CONNECTION *s, int session)
}
memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
ss->sid_ctx_length = s->sid_ctx_length;
if (s->cache_id != NULL && s->cache_id_len > 0) {
ss->cache_id = OPENSSL_memdup(s->cache_id, s->cache_id_len);
ss->cache_id_len = s->cache_id_len;
}
s->session = ss;
ss->ssl_version = s->version;
ss->verify_result = X509_V_OK;
@ -501,6 +513,7 @@ SSL_SESSION *lookup_sess_in_cache(SSL_CONNECTION *s,
& SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) {
SSL_SESSION data;
data.cache_id = NULL;
data.ssl_version = s->version;
if (!ossl_assert(sess_id_len <= SSL_MAX_SSL_SESSION_ID_LENGTH))
return NULL;
@ -875,6 +888,7 @@ void SSL_SESSION_free(SSL_SESSION *ss)
#endif
OPENSSL_free(ss->ext.alpn_selected);
OPENSSL_free(ss->ticket_appdata);
OPENSSL_free(ss->cache_id);
CRYPTO_FREE_REF(&ss->references);
OPENSSL_clear_free(ss, sizeof(*ss));
}
@ -1469,4 +1483,163 @@ void SSL_CTX_set_stateless_cookie_verify_cb(
ctx->verify_stateless_cookie_cb = cb;
}
SSL_SESSION *SSL_get1_previous_client_session(SSL *s)
{
SSL_SESSION *ret = NULL;
SSL_SESSION data;
uint32_t mode;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL)
return 0;
mode = sc->session_ctx->session_cache_mode;
/* Must have client mode enabled. */
if ((mode & SSL_SESS_CACHE_CLIENT) != SSL_SESS_CACHE_CLIENT) {
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_CACHE_MODE);
return NULL;
}
if ((mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) == 0) {
/* Set up the search parameters */
memset(&data, 0, sizeof(data));
data.cache_id = sc->cache_id;
data.cache_id_len = sc->cache_id_len;
data.sid_ctx_length = sc->sid_ctx_length;
if (sc->sid_ctx_length > 0)
memcpy(data.sid_ctx, sc->sid_ctx, sc->sid_ctx_length);
/* search */
if (!CRYPTO_THREAD_read_lock(sc->session_ctx->lock))
return NULL;
ret = lh_SSL_SESSION_retrieve(sc->session_ctx->sessions, &data);
if (ret != NULL)
SSL_SESSION_up_ref(ret);
CRYPTO_THREAD_unlock(sc->session_ctx->lock);
if (ret == NULL) {
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_miss);
} else if (sess_timedout(ossl_time_now(), ret)) {
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_timeout);
SSL_CTX_remove_session(sc->session_ctx, ret);
SSL_SESSION_free(ret);
ret = NULL;
} else {
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_hit);
}
}
if (ret == NULL && sc->session_ctx->get_session_cb != NULL) {
int copy = 1;
ret = sc->session_ctx->get_session_cb(s, sc->cache_id,
sc->cache_id_len,
&copy);
if (ret != NULL) {
ssl_tsan_counter(sc->session_ctx, &sc->session_ctx->stats.sess_hit);
/*
* Increment reference count now if the session callback asks us
* to do so (note that if the session structures returned by the
* callback are shared between threads, it must handle the
* reference count itself [i.e. copy == 0], or things won't be
* thread-safe).
*/
if (copy)
SSL_SESSION_up_ref(ret);
/*
* Add the externally cached session to the internal cache as
* well if and only if we are supposed to.
*/
if ((mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0) {
/*
* Either return value of SSL_CTX_add_session should not
* interrupt the session resumption process. The return
* value is intentionally ignored.
*/
SSL_CTX_add_session(sc->session_ctx, ret);
}
}
}
return ret;
}
int SSL_set1_cache_id(SSL *s, const unsigned char *data, size_t len)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL)
return 0;
if (sc->session != NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_SESSION_ALREADY_SET);
return 0;
}
if (sc->server) {
ERR_raise(ERR_LIB_SSL, SSL_R_NO_CACHE_ID_ON_SERVER);
return 0;
}
OPENSSL_free(sc->cache_id);
sc->cache_id_len = 0;
if (data == NULL) {
sc->cache_id = NULL;
} else {
sc->cache_id = OPENSSL_memdup(data, len);
if (sc->cache_id == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
sc->cache_id_len = len;
}
return 1;
}
int SSL_get1_cache_id(const SSL *s, unsigned char **data, size_t *len)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL || sc->server || sc->cache_id == NULL)
return 0;
if ((*data = OPENSSL_memdup(sc->cache_id, sc->cache_id_len)) == NULL)
return 0;
*len = sc->cache_id_len;
return 1;
}
int SSL_SESSION_set1_cache_id(SSL_SESSION *ss, const unsigned char *data, size_t len)
{
if (ss->next != NULL || ss->prev != NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_SESSION_ALREADY_IN_CACHE);
return 0;
}
OPENSSL_free(ss->cache_id);
ss->cache_id_len = 0;
if (data == NULL) {
ss->cache_id = NULL;
} else {
ss->cache_id = OPENSSL_memdup(data, len);
if (ss->cache_id == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
ss->cache_id_len = len;
}
return 1;
}
int SSL_SESSION_get1_cache_id(const SSL_SESSION *ss, unsigned char **data, size_t *len)
{
if (ss == NULL || ss->cache_id == NULL)
return 0;
if ((*data = OPENSSL_memdup(ss->cache_id, ss->cache_id_len)) == NULL)
return 0;
*len = ss->cache_id_len;
return 1;
}
IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)

View File

@ -877,7 +877,8 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt,
if (psksess == NULL
|| !SSL_SESSION_set1_master_key(psksess, psk, psklen)
|| !SSL_SESSION_set_cipher(psksess, cipher)
|| !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) {
|| !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)
|| !SSL_SESSION_set1_cache_id(psksess, s->cache_id, s->cache_id_len)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
OPENSSL_cleanse(psk, psklen);
return EXT_RETURN_FAIL;

View File

@ -69,7 +69,8 @@ IF[{- !$disabled{tests} -}]
ca_internals_test bio_tfo_test membio_test bio_dgram_test list_test \
fips_version_test x509_test hpke_test pairwise_fail_test \
nodefltctxtest evp_xof_test x509_load_cert_file_test bio_meth_test \
x509_acert_test x509_req_test strtoultest bio_pw_callback_test
x509_acert_test x509_req_test strtoultest bio_pw_callback_test \
client_cache_test
IF[{- !$disabled{'rpk'} -}]
PROGRAMS{noinst}=rpktest
@ -590,6 +591,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[rpktest]=../include ../apps/include ..
DEPEND[rpktest]=../libcrypto ../libssl libtestutil.a
SOURCE[client_cache_test]=client_cache_test.c helpers/ssltestlib.c
INCLUDE[client_cache_test]=../include ../apps/include ..
DEPEND[client_cache_test]=../libcrypto ../libssl libtestutil.a
SOURCE[defltfips_test]=defltfips_test.c
INCLUDE[defltfips_test]=../include ../apps/include
DEPEND[defltfips_test]=../libcrypto libtestutil.a

244
test/client_cache_test.c Normal file
View File

@ -0,0 +1,244 @@
/*
* Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/ssl.h>
#include "helpers/ssltestlib.h"
#include "internal/dane.h"
#include "testutil.h"
static char *certsdir = NULL;
static char *cert = NULL;
static char *privkey = NULL;
static OSSL_LIB_CTX *libctx = NULL;
static const unsigned char sid_ctx[] = "sid";
static const unsigned char cache_id[] = "this is a test";
static const unsigned char cache_id2[] = "different";
static SSL_SESSION *external_cache = NULL;
static SSL_SESSION *session_get_cb(SSL *ssl, const unsigned char *data, int len, int *copy)
{
unsigned char *cid;
size_t cid_len;
if (!SSL_SESSION_get1_cache_id(external_cache, &cid, &cid_len))
return NULL;
if (len != (int)cid_len || memcmp(cid, data, len) != 0) {
OPENSSL_free(cid);
return NULL;
}
OPENSSL_free(cid);
*copy = 1;
return external_cache;
}
static int test_client_cache_external(void)
{
int ret = 0;
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *cssl = NULL, *sssl = NULL;
uint32_t mode;
SSL_SESSION *sess1 = NULL;
if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
TLS_client_method(), TLS1_VERSION, TLS1_2_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;
mode = SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;
if (!TEST_true(SSL_CTX_set_session_cache_mode(cctx, mode))
|| !TEST_true(SSL_CTX_set_session_id_context(sctx, sid_ctx, sizeof(sid_ctx)))
|| !TEST_true(SSL_CTX_set_session_id_context(cctx, sid_ctx, sizeof(sid_ctx))))
goto end;
SSL_CTX_sess_set_get_cb(cctx, session_get_cb);
/* Initial connection - establishes external_cache */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_ptr(external_cache = SSL_get1_session(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Test automatic assignment of session when client has cache_id set */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_true(SSL_session_reused(cssl))
|| !TEST_ptr(sess1 = SSL_get1_session(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Ensure client is resumed when no cache_id is set, but session is assigned */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set_session(cssl, sess1))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_true(SSL_session_reused(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Ensure client is not resumed when no cache_id is set */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_false(SSL_session_reused(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Ensure client is not resumed when a different cache_id is set */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id2, sizeof(cache_id2)))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_false(SSL_session_reused(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
ret = 1;
end:
SSL_free(sssl);
SSL_free(cssl);
SSL_SESSION_free(external_cache);
external_cache = NULL;
SSL_SESSION_free(sess1);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return ret;
}
static int test_client_cache(void)
{
int ret = 0;
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *cssl = NULL, *sssl = NULL;
SSL_SESSION *sess1 = NULL, *sess2 = NULL, *sess3 = NULL;
if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
TLS_client_method(), TLS1_VERSION, TLS1_2_VERSION,
&sctx, &cctx, cert, privkey)))
return 0;
if (!TEST_true(SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT))
|| !TEST_true(SSL_CTX_set_session_id_context(sctx, sid_ctx, sizeof(sid_ctx)))
|| !TEST_true(SSL_CTX_set_session_id_context(cctx, sid_ctx, sizeof(sid_ctx))))
goto end;
/* Initial connection */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_ptr(sess1 = SSL_get1_session(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Test automatic assignment of session when client has cache_id set */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id, sizeof(cache_id)))
|| !TEST_ptr(sess2 = SSL_get1_previous_client_session(cssl))
|| !TEST_ptr_eq(sess1, sess2)
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_true(SSL_session_reused(cssl))
|| !TEST_ptr(sess3 = SSL_get1_session(cssl))
|| !TEST_ptr_eq(sess2, sess3))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Ensure client is resumed when no cache_id is set, but session is assigned */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set_session(cssl, sess3))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_true(SSL_session_reused(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Ensure client is not resumed when no cache_id is set */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_false(SSL_session_reused(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
/* Ensure client is not resumed when a different cache_id is set */
if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|| !TEST_true(SSL_set1_cache_id(cssl, cache_id2, sizeof(cache_id2)))
|| !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))
|| !TEST_false(SSL_session_reused(cssl)))
goto end;
shutdown_ssl_connection(sssl, cssl);
sssl = cssl = NULL;
ret = 1;
end:
SSL_free(sssl);
SSL_free(cssl);
SSL_SESSION_free(sess1);
SSL_SESSION_free(sess2);
SSL_SESSION_free(sess3);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return ret;
}
OPT_TEST_DECLARE_USAGE("certdir\n")
int setup_tests(void)
{
if (!test_skip_common_options()) {
TEST_error("Error parsing test options\n");
return 0;
}
if (!TEST_ptr(certsdir = test_get_argument(0)))
return 0;
cert = test_mk_file_path(certsdir, "servercert.pem");
if (cert == NULL)
goto err;
privkey = test_mk_file_path(certsdir, "serverkey.pem");
if (privkey == NULL)
goto err;
libctx = OSSL_LIB_CTX_new();
if (libctx == NULL)
goto err;
ADD_TEST(test_client_cache);
ADD_TEST(test_client_cache_external);
return 1;
err:
return 0;
}
void cleanup_tests(void)
{
OPENSSL_free(cert);
OPENSSL_free(privkey);
OSSL_LIB_CTX_free(libctx);
}

View File

@ -23,9 +23,19 @@ print <<"_____";
#ifndef OPENSSL_NO_STDIO
# include <stdio.h>
#endif
_____
if (${name_uc} eq "RSA") {
print("#include <openssl/rsa.h>");
}
else {
print <<"_____";
#ifndef OPENSSL_NO_${name_uc}
# include <openssl/$name.h>
#endif
_____
}
print <<"_____";
int main(void)
{

View File

@ -0,0 +1,23 @@
#! /usr/bin/env perl
# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
use OpenSSL::Test::Utils;
use OpenSSL::Test qw/:DEFAULT srctop_dir bldtop_dir/;
BEGIN {
setup("test_client_cache");
}
use lib srctop_dir('Configurations');
use lib bldtop_dir('.');
plan skip_all => "TLS is disabled in this OpenSSL build" if disabled("tls1") && disabled("tls1_1") && disabled("tls1_2");
plan tests => 1;
ok(run(test(["client_cache_test", srctop_dir("test", "certs")])), "running client_cache_test");

View File

@ -24,6 +24,6 @@ test -d "$QUICHE_TARGET_PATH" || exit 1
"$QUICHE_TARGET_PATH/debug/quiche-server" --cert "$SRCTOP/test/certs/servercert.pem" \
--key "$SRCTOP/test/certs/serverkey.pem" --disable-gso \
--http-version HTTP/0.9 --root "$SRCTOP" --no-grease --disable-hystart &
--http-version HTTP/0.9 --root "$SRCTOP" --no-grease --disable-hystart > quiche_server_log 2>&1 &
echo $! >server.pid

View File

@ -1984,7 +1984,7 @@ static int test_tlsext_status_type(void)
if (!create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(),
TLS1_VERSION, 0,
&sctx, &cctx, leaf, skey))
return 0;
goto end;
if (SSL_CTX_use_certificate_chain_file(sctx, leaf_chain) <= 0)
goto end;
if (SSL_CTX_get_tlsext_status_type(cctx) != -1)
@ -2481,8 +2481,12 @@ static int execute_test_session(int maxprot, int use_int_cache,
# ifndef OPENSSL_NO_TLS1_1
SSL *serverssl3 = NULL, *clientssl3 = NULL;
# endif
SSL_SESSION *sess1 = NULL, *sess2 = NULL;
SSL_SESSION *sess1 = NULL, *sess2 = NULL, *sess3 = NULL;
int testresult = 0, numnewsesstick = 1;
const unsigned char cache_id[] = "this is a test";
size_t cache_id_len = sizeof("this is a test");
unsigned char *new_cache_id = NULL;
size_t new_cache_id_len;
new_called = remove_called = 0;
@ -2522,11 +2526,29 @@ static int execute_test_session(int maxprot, int use_int_cache,
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1,
NULL, NULL))
|| !TEST_true(create_ssl_connection(serverssl1, clientssl1,
SSL_ERROR_NONE))
|| !TEST_true(SSL_set1_cache_id(clientssl1, cache_id, cache_id_len))
|| !TEST_true(SSL_get1_cache_id(clientssl1, &new_cache_id, &new_cache_id_len))
|| !TEST_mem_eq(cache_id, cache_id_len, new_cache_id, new_cache_id_len)
|| !TEST_true(create_ssl_connection(serverssl1, clientssl1, SSL_ERROR_NONE))
|| !TEST_false(SSL_set1_cache_id(clientssl1, cache_id, cache_id_len))
|| !TEST_ptr(sess1 = SSL_get1_session(clientssl1)))
goto end;
OPENSSL_free(new_cache_id);
new_cache_id = NULL;
if (use_int_cache
&& (!TEST_true(SSL_SESSION_get1_cache_id(sess1, &new_cache_id, &new_cache_id_len))
|| !TEST_mem_eq(cache_id, cache_id_len, new_cache_id, new_cache_id_len)
|| !TEST_ptr(sess3 = SSL_get1_previous_client_session(clientssl1))
|| !TEST_ptr_eq(sess1, sess3)
|| !TEST_false(SSL_SESSION_set1_cache_id(sess1, cache_id, cache_id_len))))
goto end;
/* no longer used */
SSL_SESSION_free(sess3);
sess3 = NULL;
/* Should fail because it should already be in the cache */
if (use_int_cache && !TEST_false(SSL_CTX_add_session(cctx, sess1)))
goto end;
@ -2782,8 +2804,10 @@ static int execute_test_session(int maxprot, int use_int_cache,
# endif
SSL_SESSION_free(sess1);
SSL_SESSION_free(sess2);
SSL_SESSION_free(sess3);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
OPENSSL_free(new_cache_id);
return testresult;
}

View File

@ -606,3 +606,8 @@ SSL_CTX_set_domain_flags ? 3_5_0 EXIST::FUNCTION:
SSL_CTX_get_domain_flags ? 3_5_0 EXIST::FUNCTION:
SSL_get_domain_flags ? 3_5_0 EXIST::FUNCTION:
SSL_CTX_set_new_pending_conn_cb ? 3_5_0 EXIST::FUNCTION:
SSL_get1_previous_client_session ? 3_5_0 EXIST::FUNCTION:
SSL_set1_cache_id ? 3_5_0 EXIST::FUNCTION:
SSL_get1_cache_id ? 3_5_0 EXIST::FUNCTION:
SSL_SESSION_set1_cache_id ? 3_5_0 EXIST::FUNCTION:
SSL_SESSION_get1_cache_id ? 3_5_0 EXIST::FUNCTION: