** Description changed:
Note: This bug report, analysis of the issue, and the potential fix were
created using the assistance of an LLM.
[ Impact ]
- Users on Ubuntu 24.04 noble who attempt to sign files via a PKCS#11
- token using the OpenSSL PKCS#11 engine (libengine-pkcs11-openssl)
- experience a segfault. This affects any tool that uses the engine for
- signing, including sbsign (used for UEFI Secure Boot binary signing) and
- osslsigncode. The crash occurs unconditionally on the affected OpenSSL
- versions — there is no workaround available to users without replacing
- the library.
+ OpenSSL 3.0.12 and 3.0.13 carry commit 2b74e75 ("Improved detection of
+ engine-provided private classic keys"), which runs a get1/set1 round-
+ trip on the key returned by ENGINE_load_private_key(). That round-trip
+ calls ENGINE_finish() on the key's engine and clears the binding,
+ dropping the functional reference the engine took for itself.
- The root cause is a regression introduced in OpenSSL commit 2b74e75
- (shipped in 3.0.12) and fixed in OpenSSL commit 39ea783 (not backported
- to the 3.0.x series in noble). libp11 0.4.13 (in plucky 25.04+) carries
- a runtime workaround that detects the affected OpenSSL versions and
- reroutes signing through PKEY_CRYPTO, avoiding the broken code path.
- Noble ships 0.4.12 which does not have this workaround.
+ Applications that then release their own engine reference before using
+ the key take the reference count to zero, so the PKCS#11 context is torn
+ down while the key is still in use, and signing dereferences freed
+ memory. sbsign, sbvarsign, osslsigncode and Apache mod_ssl all follow
+ that pattern. Applications that hold their reference until teardown,
+ such as the openssl CLI, wpa_supplicant, libcurl, nginx and libpq, are
+ unaffected, which is why this does not reproduce with "openssl pkeyutl".
+
+ Reported in Ubuntu here and in LP #2119094 (Google Cloud KMS and
+ DigiCert KeyLocker code signing), LP #2067163 and LP #2097330, and
+ upstream as mtrojnar/osslsigncode#410 and #316.
+
+ Upstream reverted 2b74e75 in commit
+ ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6 on the openssl-3.0 branch,
+ which is 39ea78379826fa98e8dc8c0d2b07e2c17cd68380 on master. It was
+ released in 3.0.14 and has been carried in every 3.0.x since. noble is
+ the only supported Ubuntu series still carrying the defect. jammy has
+ 3.0.2-0ubuntu1.30, which predates the change, and resolute and stonking
+ are both past the revert.
+
+ This upload backports that revert as a single patch deleting 42 lines
+ from crypto/engine/eng_pkey.c. No other patch in noble's 86-patch stack
+ touches crypto/engine/, so it applies with no fuzz or offset.
+
+ This bug was previously fixed in libp11 rather than openssl, by
+ backporting a workaround that registers the PKCS#11 engine as the
+ process-wide default for RSA and EC. That caused its own regression, LP
+ #2163152, and has been reverted in libp11 0.4.12-1.1ubuntu2, currently
+ in noble-proposed. libp11's upstream maintainer declined to fix the side
+ effect in libp11 and recommended this backport instead, saying "The
+ clean solution for affected distributions is to backport
+ openssl/openssl#23063 and disable this libp11 workaround for that
+ patched OpenSSL build. If the distribution retains the runtime version
+ number 3.0.13, both changes are necessary because OpenSSL_version_num()
+ cannot distinguish the backport." Debian reached the same conclusion
+ independently. The intention is to release the libp11 revert and this
+ openssl upload together, so that noble never spends time in the crashing
+ state.
[ Test Plan ]
- Requires a PKCS#11 token. Tested with a YubiHSM2 device; any PKCS#11
- token with an RSA key should reproduce the issue.
+ Reproducible with SoftHSM2 and no hardware. libp11 must be
+ 0.4.12-1.1build2 or 0.4.12-1.1ubuntu2, because the workaround in
+ 0.4.12-1.1ubuntu1 masks the crash.
- 1. On a fresh noble system, install dependencies:
- sudo apt install libengine-pkcs11-openssl sbsigntool opensc
- # Also install yubihsm-connector, yubihsm-shell, yubihsm-pkcs11 from the
Yubico SDK
+ 1. sudo apt install softhsm2 opensc libengine-pkcs11-openssl sbsigntool
+ shim-signed
- 2. Start yubihsm-connector and confirm device is reachable:
- curl -s http://127.0.0.1:12345/connector/status # expect status=OK
+ 2. Create a token, import an RSA key and a certificate.
- 3. Generate a test RSA-2048 key and self-signed certificate:
- openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out test.key
- openssl req -new -x509 -key test.key -out test.crt -days 365 -subj
"/CN=Test"
+ openssl req -x509 -newkey rsa:2048 -keyout k.pem -out c.pem -days 365
-nodes -subj "/CN=Test"
+ softhsm2-util --init-token --free --label test --so-pin 1234 --pin 1234
+ softhsm2-util --import k.pem --token test --label testkey --id 01 --pin
1234
- 4. Load the key into the token (YubiHSM2 factory defaults):
- yubihsm-shell --connector http://127.0.0.1:12345 -p password --authkey 1 \
- -a put-asymmetric-key --object-id 257 --label "test-key" \
- --domains 1 --capabilities sign-pkcs --algorithm rsa2048 --in test.key
+ 3. Sign a PE binary through the engine.
- 5. Create PKCS#11 connector config:
- echo "connector = http://127.0.0.1:12345" > yubihsm_pkcs11.conf
+ sbsign --engine pkcs11 --key
+ 'pkcs11:token=test;object=testkey;type=private;pin-value=1234' --cert
+ c.pem --output /dev/null /usr/lib/shim/shimx64.efi
- 6. Attempt to sign an EFI binary:
- YUBIHSM_PKCS11_CONF=$(pwd)/yubihsm_pkcs11.conf \
- sbsign --engine pkcs11 \
- --key "pkcs11:id=%01%01;type=private;pin-value=0001password" \
- --cert test.crt --output test-output.efi /boot/efi/EFI/ubuntu/grubx64.efi
+ Before fix, Segmentation fault, exit 139.
+ After fix, "Signing Unsigned original image", exit 0.
- Before fix: Segmentation fault (core dumped)
- After fix: signed binary produced; sbverify --cert test.crt
test-output.efi returns OK. stderr will print "Workaround for OpenSSL 3.0.13
enabled" — this is expected.
+ Any PKCS#11 token works, substituting its own key URI. Verified with
+ SoftHSM2 and with a YubiHSM 2.
[ Where problems could occur ]
- The patch adds a call to ENGINE_set_default_string(engine,
- "PKEY_CRYPTO") inside load_privkey() when an affected OpenSSL version is
- detected. This reroutes all PKEY_CRYPTO operations for the engine
- instance through the EVP_PKEY path rather than the legacy RSA_sign path.
+ - openssl is in main and on every Ubuntu system, and 1397 binary
+ packages in noble depend on libssl3t64, so any defect introduced here
+ has an unusually large blast radius. That alone justifies caution
+ regardless of how small the change is. What bounds the risk is
+ reachability rather than popularity. The reverted code sits in
+ ENGINE_load_private_key(), part of the deprecated ENGINE API, and runs
+ only when an application explicitly loads a private key through an
+ engine. Nothing on a default install does that, since it needs an engine
+ to be configured and a token or HSM to be present. The patch deletes 42
+ lines and adds none, changes no header, no symbol and no struct layout,
+ so the ABI is untouched and nothing needs rebuilding.
- Possible failure modes:
+ - The patch restores crypto/engine/eng_pkey.c to its 3.0.11 form, so any
+ OpenSSL ENGINE that relied on OpenSSL coercing its returned key to
+ legacy will behave differently. Upstream named the two regressions this
+ revert would cause before merging it, openssl#17092 and openssl#17286.
+ Both came from the out-of-tree e_nss engine, which upstream judged to be
+ engine-side bugs already worked around there. Both issues are closed,
+ neither has had activity since 2023-10-04, and e_nss is not packaged in
+ Ubuntu.
- - Deployments using foreign keys from multiple engines simultaneously:
- ENGINE_set_default_string sets the default engine for PKEY_CRYPTO
- globally for that engine instance. If an application loads private keys
- from multiple engines and relies on per-key engine dispatch, this could
- interfere. Such deployments are uncommon and would already be non-
- functional on affected OpenSSL versions (the bug causes a segfault
- regardless). The upstream comment in libp11 0.4.13 explicitly
- acknowledges this trade-off.
+ - The engines shipped in noble on amd64, taken from the release and
+ updates Contents indexes, are afalg, loader_attic and padlock from
+ libssl3t64 itself, plus pkcs11 from libengine-pkcs11-openssl, tpm2tss
+ from libengine-tpm2-tss-openssl, gost from libengine-gost-openssl, and
+ qatengine. Only libp11 changes behaviour, in the intended direction.
+ tpm2tss already builds legacy keys, so the round-trip was a no-op for
+ it. The qatengine KPT path was not exercised, since it needs QAT
+ hardware.
- - ENGINE_set_default_string failure: if the call fails on an affected
- OpenSSL version, the patch logs "Failed to set PKEY_CRYPTO default
- engine" to stderr and continues. The behaviour is then identical to the
- unpatched package — a segfault on signing. This is not worse than the
- current state but means the fix silently did not apply.
+ - The reverted code is only reachable via ENGINE_load_private_key(), so
+ TLS handshakes, certificate verification, FIPS mode and provider-only
+ stacks are untouched.
- - The workaround emits "Workaround for OpenSSL X.Y.Z enabled" to stderr
- on every key load on affected versions. Applications that parse or
- suppress stderr output may be affected by this unexpected message.
+ - Engine teardown moves from key-load time back to EVP_PKEY_free time.
+ That is the pre-3.0.12 ordering, but it is still a change for every
+ consumer of the engine path.
+
+ - OpenSSL's own test suite cannot detect this, because no test signs
+ with an engine-loaded key. The suite passing says the patch applies
+ cleanly and nothing more, so verification has to be manual.
+
+ - On the field record, the revert has been in Debian bookworm since
+ openssl 3.0.13-1~deb12u2 in July 2024 and in every upstream 3.0.x since
+ 3.0.14, with no report anywhere of a regression caused by it.
+ openssl#23137 is open and labelled a regression against engine-backed DH
+ keys, but it was filed on 2023-12-22, six weeks before the revert
+ landed, against 3.0.12, and its root cause is in crypto/dh/dh_backend.c.
+
+ Measured with SoftHSM2 and a YubiHSM 2, signing with sbsign against an
+ RSA-2048 token key.
+
+ openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1build2 sbsign
exits 139
+ openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1ubuntu1 sbsign
exits 0, engine left as process-wide default
+ openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1build2 sbsign
exits 0, engine not left as default
+ openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1ubuntu2~ppa1 sbsign
exits 0, engine not left as default
+
+ The last two rows used PPA builds based on 3.0.13-0ubuntu3.15, before
+ the 3.0.13-0ubuntu3.16 security update. This upload rebases the revert
+ onto that security update and will be re-verified against the -proposed
+ package.
[ Other Info ]
- - Upstream fix: https://github.com/OpenSC/libp11/pull/554 (landed in libp11
0.4.13)
- - OpenSSL regression: openssl/openssl@2b74e75, fixed in
openssl/openssl@39ea783
- - The fix is present in plucky (0.4.13) and questing (0.4.16) without
reported regressions.
- - autopkgtest results: TODO
+ - This SRU was invited in 2024. LP #2062167
+ (https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/2062167)
+ proposed exactly this commit for noble before release, saying "The
+ bigger one is ad6cbe4b...: Revert "Improved detection of engine-provided
+ private "classic" keys" ... All look safe to me." It was deferred with
+ "it's too late for this right now, considering we're in Final Freeze for
+ 24.04 ... Let's revisit as an SRU", and never filed.
+
+ - Christian Ehrhardt identified the same commit independently on LP
+ #2119094, comment #6,
+ https://bugs.launchpad.net/ubuntu/+source/libp11/+bug/2119094/comments/6
+
+ - Upstream libp11 declined to fix the workaround's side effect in libp11
+ and recommended that distributions backport the OpenSSL revert and drop
+ the workaround. OpenSC/libp11#676 is the discussion and
+ https://github.com/OpenSC/libp11/issues/676#issuecomment-5341749942 is
+ the specific recommendation.
+
+ - Debian hit the same defect and fixed it in openssl rather than libp11.
+ https://bugs.debian.org/1074764 was reported on 2024-07-02 against
+ libssl3, and openssl 3.0.13-1~deb12u2 shipped to bookworm on 2024-07-05
+ with the changelog entry "Revert "Improved detection of engine-provided
+ private "classic" keys" (Closes: #1074764)", three days later. It has
+ been carried in bookworm ever since.
+
+ - Upstream OpenSSL references.
+ - the defect,
https://github.com/openssl/openssl/commit/2b74e75331a27fc89cad9c8ea6a26c70019300b5
+ - the revert on openssl-3.0,
https://github.com/openssl/openssl/commit/ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6
+ - the revert on master,
https://github.com/openssl/openssl/commit/39ea78379826fa98e8dc8c0d2b07e2c17cd68380
+ - the pull request it was merged under,
https://github.com/openssl/openssl/pull/23063
+ - the regressions upstream expected,
https://github.com/openssl/openssl/issues/17092 and
https://github.com/openssl/openssl/issues/17286
+ - the open engine issue that predates the revert,
https://github.com/openssl/openssl/issues/23137
+
+ - Downstream reports of the same crash,
+ https://github.com/mtrojnar/osslsigncode/issues/410 from the PuTTY
+ maintainer signing releases with a SafeNet token, and
+ https://github.com/mtrojnar/osslsigncode/issues/316
+
+ - Related Ubuntu bugs. LP #2163152 is the regression caused by the
+ libp11 workaround, reverted in 0.4.12-1.1ubuntu2. LP #2119094, LP
+ #2067163 and LP #2097330 are further reports of this crash.
+
+ - The previous description of this bug was the SRU template for the
+ libp11 workaround, which is now being reverted. You can find the old SRU
+ template description from this SRU bug's activity history.
** Description changed:
Note: This bug report, analysis of the issue, and the potential fix were
created using the assistance of an LLM.
[ Impact ]
OpenSSL 3.0.12 and 3.0.13 carry commit 2b74e75 ("Improved detection of
engine-provided private classic keys"), which runs a get1/set1 round-
trip on the key returned by ENGINE_load_private_key(). That round-trip
calls ENGINE_finish() on the key's engine and clears the binding,
dropping the functional reference the engine took for itself.
Applications that then release their own engine reference before using
the key take the reference count to zero, so the PKCS#11 context is torn
down while the key is still in use, and signing dereferences freed
memory. sbsign, sbvarsign, osslsigncode and Apache mod_ssl all follow
that pattern. Applications that hold their reference until teardown,
such as the openssl CLI, wpa_supplicant, libcurl, nginx and libpq, are
unaffected, which is why this does not reproduce with "openssl pkeyutl".
Reported in Ubuntu here and in LP #2119094 (Google Cloud KMS and
- DigiCert KeyLocker code signing), LP #2067163 and LP #2097330, and
+ DigiCert KeyLocker code signing), LP: #2067163 and LP: #2097330, and
upstream as mtrojnar/osslsigncode#410 and #316.
Upstream reverted 2b74e75 in commit
ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6 on the openssl-3.0 branch,
which is 39ea78379826fa98e8dc8c0d2b07e2c17cd68380 on master. It was
released in 3.0.14 and has been carried in every 3.0.x since. noble is
the only supported Ubuntu series still carrying the defect. jammy has
3.0.2-0ubuntu1.30, which predates the change, and resolute and stonking
are both past the revert.
This upload backports that revert as a single patch deleting 42 lines
from crypto/engine/eng_pkey.c. No other patch in noble's 86-patch stack
touches crypto/engine/, so it applies with no fuzz or offset.
This bug was previously fixed in libp11 rather than openssl, by
backporting a workaround that registers the PKCS#11 engine as the
process-wide default for RSA and EC. That caused its own regression, LP
#2163152, and has been reverted in libp11 0.4.12-1.1ubuntu2, currently
in noble-proposed. libp11's upstream maintainer declined to fix the side
effect in libp11 and recommended this backport instead, saying "The
clean solution for affected distributions is to backport
openssl/openssl#23063 and disable this libp11 workaround for that
patched OpenSSL build. If the distribution retains the runtime version
number 3.0.13, both changes are necessary because OpenSSL_version_num()
cannot distinguish the backport." Debian reached the same conclusion
independently. The intention is to release the libp11 revert and this
openssl upload together, so that noble never spends time in the crashing
state.
[ Test Plan ]
Reproducible with SoftHSM2 and no hardware. libp11 must be
0.4.12-1.1build2 or 0.4.12-1.1ubuntu2, because the workaround in
0.4.12-1.1ubuntu1 masks the crash.
1. sudo apt install softhsm2 opensc libengine-pkcs11-openssl sbsigntool
shim-signed
2. Create a token, import an RSA key and a certificate.
- openssl req -x509 -newkey rsa:2048 -keyout k.pem -out c.pem -days 365
-nodes -subj "/CN=Test"
- softhsm2-util --init-token --free --label test --so-pin 1234 --pin 1234
- softhsm2-util --import k.pem --token test --label testkey --id 01 --pin
1234
+ openssl req -x509 -newkey rsa:2048 -keyout k.pem -out c.pem -days 365
-nodes -subj "/CN=Test"
+ softhsm2-util --init-token --free --label test --so-pin 1234 --pin 1234
+ softhsm2-util --import k.pem --token test --label testkey --id 01 --pin
1234
3. Sign a PE binary through the engine.
- sbsign --engine pkcs11 --key
+ sbsign --engine pkcs11 --key
'pkcs11:token=test;object=testkey;type=private;pin-value=1234' --cert
c.pem --output /dev/null /usr/lib/shim/shimx64.efi
- Before fix, Segmentation fault, exit 139.
- After fix, "Signing Unsigned original image", exit 0.
+ Before fix, Segmentation fault, exit 139.
+ After fix, "Signing Unsigned original image", exit 0.
Any PKCS#11 token works, substituting its own key URI. Verified with
SoftHSM2 and with a YubiHSM 2.
[ Where problems could occur ]
- openssl is in main and on every Ubuntu system, and 1397 binary
packages in noble depend on libssl3t64, so any defect introduced here
has an unusually large blast radius. That alone justifies caution
regardless of how small the change is. What bounds the risk is
reachability rather than popularity. The reverted code sits in
ENGINE_load_private_key(), part of the deprecated ENGINE API, and runs
only when an application explicitly loads a private key through an
engine. Nothing on a default install does that, since it needs an engine
to be configured and a token or HSM to be present. The patch deletes 42
lines and adds none, changes no header, no symbol and no struct layout,
so the ABI is untouched and nothing needs rebuilding.
- The patch restores crypto/engine/eng_pkey.c to its 3.0.11 form, so any
OpenSSL ENGINE that relied on OpenSSL coercing its returned key to
legacy will behave differently. Upstream named the two regressions this
revert would cause before merging it, openssl#17092 and openssl#17286.
Both came from the out-of-tree e_nss engine, which upstream judged to be
engine-side bugs already worked around there. Both issues are closed,
neither has had activity since 2023-10-04, and e_nss is not packaged in
Ubuntu.
- The engines shipped in noble on amd64, taken from the release and
updates Contents indexes, are afalg, loader_attic and padlock from
libssl3t64 itself, plus pkcs11 from libengine-pkcs11-openssl, tpm2tss
from libengine-tpm2-tss-openssl, gost from libengine-gost-openssl, and
qatengine. Only libp11 changes behaviour, in the intended direction.
tpm2tss already builds legacy keys, so the round-trip was a no-op for
it. The qatengine KPT path was not exercised, since it needs QAT
hardware.
- The reverted code is only reachable via ENGINE_load_private_key(), so
TLS handshakes, certificate verification, FIPS mode and provider-only
stacks are untouched.
- Engine teardown moves from key-load time back to EVP_PKEY_free time.
That is the pre-3.0.12 ordering, but it is still a change for every
consumer of the engine path.
- OpenSSL's own test suite cannot detect this, because no test signs
with an engine-loaded key. The suite passing says the patch applies
cleanly and nothing more, so verification has to be manual.
- On the field record, the revert has been in Debian bookworm since
openssl 3.0.13-1~deb12u2 in July 2024 and in every upstream 3.0.x since
3.0.14, with no report anywhere of a regression caused by it.
openssl#23137 is open and labelled a regression against engine-backed DH
keys, but it was filed on 2023-12-22, six weeks before the revert
landed, against 3.0.12, and its root cause is in crypto/dh/dh_backend.c.
Measured with SoftHSM2 and a YubiHSM 2, signing with sbsign against an
RSA-2048 token key.
- openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1build2 sbsign
exits 139
- openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1ubuntu1 sbsign
exits 0, engine left as process-wide default
- openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1build2 sbsign
exits 0, engine not left as default
- openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1ubuntu2~ppa1 sbsign
exits 0, engine not left as default
+ openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1build2 sbsign
exits 139
+ openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1ubuntu1 sbsign
exits 0, engine left as process-wide default
+ openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1build2 sbsign
exits 0, engine not left as default
+ openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1ubuntu2~ppa1 sbsign
exits 0, engine not left as default
The last two rows used PPA builds based on 3.0.13-0ubuntu3.15, before
the 3.0.13-0ubuntu3.16 security update. This upload rebases the revert
onto that security update and will be re-verified against the -proposed
package.
[ Other Info ]
- This SRU was invited in 2024. LP #2062167
(https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/2062167)
proposed exactly this commit for noble before release, saying "The
bigger one is ad6cbe4b...: Revert "Improved detection of engine-provided
private "classic" keys" ... All look safe to me." It was deferred with
"it's too late for this right now, considering we're in Final Freeze for
24.04 ... Let's revisit as an SRU", and never filed.
- Christian Ehrhardt identified the same commit independently on LP
#2119094, comment #6,
https://bugs.launchpad.net/ubuntu/+source/libp11/+bug/2119094/comments/6
- Upstream libp11 declined to fix the workaround's side effect in libp11
and recommended that distributions backport the OpenSSL revert and drop
the workaround. OpenSC/libp11#676 is the discussion and
https://github.com/OpenSC/libp11/issues/676#issuecomment-5341749942 is
the specific recommendation.
- Debian hit the same defect and fixed it in openssl rather than libp11.
https://bugs.debian.org/1074764 was reported on 2024-07-02 against
libssl3, and openssl 3.0.13-1~deb12u2 shipped to bookworm on 2024-07-05
with the changelog entry "Revert "Improved detection of engine-provided
private "classic" keys" (Closes: #1074764)", three days later. It has
been carried in bookworm ever since.
- Upstream OpenSSL references.
- - the defect,
https://github.com/openssl/openssl/commit/2b74e75331a27fc89cad9c8ea6a26c70019300b5
- - the revert on openssl-3.0,
https://github.com/openssl/openssl/commit/ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6
- - the revert on master,
https://github.com/openssl/openssl/commit/39ea78379826fa98e8dc8c0d2b07e2c17cd68380
- - the pull request it was merged under,
https://github.com/openssl/openssl/pull/23063
- - the regressions upstream expected,
https://github.com/openssl/openssl/issues/17092 and
https://github.com/openssl/openssl/issues/17286
- - the open engine issue that predates the revert,
https://github.com/openssl/openssl/issues/23137
+ - the defect,
https://github.com/openssl/openssl/commit/2b74e75331a27fc89cad9c8ea6a26c70019300b5
+ - the revert on openssl-3.0,
https://github.com/openssl/openssl/commit/ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6
+ - the revert on master,
https://github.com/openssl/openssl/commit/39ea78379826fa98e8dc8c0d2b07e2c17cd68380
+ - the pull request it was merged under,
https://github.com/openssl/openssl/pull/23063
+ - the regressions upstream expected,
https://github.com/openssl/openssl/issues/17092 and
https://github.com/openssl/openssl/issues/17286
+ - the open engine issue that predates the revert,
https://github.com/openssl/openssl/issues/23137
- Downstream reports of the same crash,
https://github.com/mtrojnar/osslsigncode/issues/410 from the PuTTY
maintainer signing releases with a SafeNet token, and
https://github.com/mtrojnar/osslsigncode/issues/316
- Related Ubuntu bugs. LP #2163152 is the regression caused by the
libp11 workaround, reverted in 0.4.12-1.1ubuntu2. LP #2119094, LP
#2067163 and LP #2097330 are further reports of this crash.
- The previous description of this bug was the SRU template for the
libp11 workaround, which is now being reverted. You can find the old SRU
template description from this SRU bug's activity history.
** Description changed:
Note: This bug report, analysis of the issue, and the potential fix were
created using the assistance of an LLM.
[ Impact ]
OpenSSL 3.0.12 and 3.0.13 carry commit 2b74e75 ("Improved detection of
engine-provided private classic keys"), which runs a get1/set1 round-
trip on the key returned by ENGINE_load_private_key(). That round-trip
calls ENGINE_finish() on the key's engine and clears the binding,
dropping the functional reference the engine took for itself.
Applications that then release their own engine reference before using
the key take the reference count to zero, so the PKCS#11 context is torn
down while the key is still in use, and signing dereferences freed
memory. sbsign, sbvarsign, osslsigncode and Apache mod_ssl all follow
that pattern. Applications that hold their reference until teardown,
such as the openssl CLI, wpa_supplicant, libcurl, nginx and libpq, are
unaffected, which is why this does not reproduce with "openssl pkeyutl".
- Reported in Ubuntu here and in LP #2119094 (Google Cloud KMS and
+ Reported in Ubuntu here and in LP: #2119094 (Google Cloud KMS and
DigiCert KeyLocker code signing), LP: #2067163 and LP: #2097330, and
upstream as mtrojnar/osslsigncode#410 and #316.
Upstream reverted 2b74e75 in commit
ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6 on the openssl-3.0 branch,
which is 39ea78379826fa98e8dc8c0d2b07e2c17cd68380 on master. It was
released in 3.0.14 and has been carried in every 3.0.x since. noble is
the only supported Ubuntu series still carrying the defect. jammy has
3.0.2-0ubuntu1.30, which predates the change, and resolute and stonking
are both past the revert.
This upload backports that revert as a single patch deleting 42 lines
from crypto/engine/eng_pkey.c. No other patch in noble's 86-patch stack
touches crypto/engine/, so it applies with no fuzz or offset.
This bug was previously fixed in libp11 rather than openssl, by
backporting a workaround that registers the PKCS#11 engine as the
process-wide default for RSA and EC. That caused its own regression, LP
#2163152, and has been reverted in libp11 0.4.12-1.1ubuntu2, currently
in noble-proposed. libp11's upstream maintainer declined to fix the side
effect in libp11 and recommended this backport instead, saying "The
clean solution for affected distributions is to backport
openssl/openssl#23063 and disable this libp11 workaround for that
patched OpenSSL build. If the distribution retains the runtime version
number 3.0.13, both changes are necessary because OpenSSL_version_num()
cannot distinguish the backport." Debian reached the same conclusion
independently. The intention is to release the libp11 revert and this
openssl upload together, so that noble never spends time in the crashing
state.
[ Test Plan ]
Reproducible with SoftHSM2 and no hardware. libp11 must be
0.4.12-1.1build2 or 0.4.12-1.1ubuntu2, because the workaround in
0.4.12-1.1ubuntu1 masks the crash.
1. sudo apt install softhsm2 opensc libengine-pkcs11-openssl sbsigntool
shim-signed
2. Create a token, import an RSA key and a certificate.
openssl req -x509 -newkey rsa:2048 -keyout k.pem -out c.pem -days 365
-nodes -subj "/CN=Test"
softhsm2-util --init-token --free --label test --so-pin 1234 --pin 1234
softhsm2-util --import k.pem --token test --label testkey --id 01 --pin
1234
3. Sign a PE binary through the engine.
sbsign --engine pkcs11 --key
'pkcs11:token=test;object=testkey;type=private;pin-value=1234' --cert
c.pem --output /dev/null /usr/lib/shim/shimx64.efi
Before fix, Segmentation fault, exit 139.
After fix, "Signing Unsigned original image", exit 0.
Any PKCS#11 token works, substituting its own key URI. Verified with
SoftHSM2 and with a YubiHSM 2.
[ Where problems could occur ]
- openssl is in main and on every Ubuntu system, and 1397 binary
packages in noble depend on libssl3t64, so any defect introduced here
has an unusually large blast radius. That alone justifies caution
regardless of how small the change is. What bounds the risk is
reachability rather than popularity. The reverted code sits in
ENGINE_load_private_key(), part of the deprecated ENGINE API, and runs
only when an application explicitly loads a private key through an
engine. Nothing on a default install does that, since it needs an engine
to be configured and a token or HSM to be present. The patch deletes 42
lines and adds none, changes no header, no symbol and no struct layout,
so the ABI is untouched and nothing needs rebuilding.
- The patch restores crypto/engine/eng_pkey.c to its 3.0.11 form, so any
OpenSSL ENGINE that relied on OpenSSL coercing its returned key to
legacy will behave differently. Upstream named the two regressions this
revert would cause before merging it, openssl#17092 and openssl#17286.
Both came from the out-of-tree e_nss engine, which upstream judged to be
engine-side bugs already worked around there. Both issues are closed,
neither has had activity since 2023-10-04, and e_nss is not packaged in
Ubuntu.
- The engines shipped in noble on amd64, taken from the release and
updates Contents indexes, are afalg, loader_attic and padlock from
libssl3t64 itself, plus pkcs11 from libengine-pkcs11-openssl, tpm2tss
from libengine-tpm2-tss-openssl, gost from libengine-gost-openssl, and
qatengine. Only libp11 changes behaviour, in the intended direction.
tpm2tss already builds legacy keys, so the round-trip was a no-op for
it. The qatengine KPT path was not exercised, since it needs QAT
hardware.
- The reverted code is only reachable via ENGINE_load_private_key(), so
TLS handshakes, certificate verification, FIPS mode and provider-only
stacks are untouched.
- Engine teardown moves from key-load time back to EVP_PKEY_free time.
That is the pre-3.0.12 ordering, but it is still a change for every
consumer of the engine path.
- OpenSSL's own test suite cannot detect this, because no test signs
with an engine-loaded key. The suite passing says the patch applies
cleanly and nothing more, so verification has to be manual.
- On the field record, the revert has been in Debian bookworm since
openssl 3.0.13-1~deb12u2 in July 2024 and in every upstream 3.0.x since
3.0.14, with no report anywhere of a regression caused by it.
openssl#23137 is open and labelled a regression against engine-backed DH
keys, but it was filed on 2023-12-22, six weeks before the revert
landed, against 3.0.12, and its root cause is in crypto/dh/dh_backend.c.
Measured with SoftHSM2 and a YubiHSM 2, signing with sbsign against an
RSA-2048 token key.
openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1build2 sbsign
exits 139
openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1ubuntu1 sbsign
exits 0, engine left as process-wide default
openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1build2 sbsign
exits 0, engine not left as default
openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1ubuntu2~ppa1 sbsign
exits 0, engine not left as default
The last two rows used PPA builds based on 3.0.13-0ubuntu3.15, before
the 3.0.13-0ubuntu3.16 security update. This upload rebases the revert
onto that security update and will be re-verified against the -proposed
package.
[ Other Info ]
- - This SRU was invited in 2024. LP #2062167
+ - This SRU was invited in 2024. LP: #2062167
(https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/2062167)
proposed exactly this commit for noble before release, saying "The
bigger one is ad6cbe4b...: Revert "Improved detection of engine-provided
private "classic" keys" ... All look safe to me." It was deferred with
"it's too late for this right now, considering we're in Final Freeze for
24.04 ... Let's revisit as an SRU", and never filed.
- - Christian Ehrhardt identified the same commit independently on LP
+ - Christian Ehrhardt identified the same commit independently on LP:
#2119094, comment #6,
https://bugs.launchpad.net/ubuntu/+source/libp11/+bug/2119094/comments/6
- Upstream libp11 declined to fix the workaround's side effect in libp11
and recommended that distributions backport the OpenSSL revert and drop
the workaround. OpenSC/libp11#676 is the discussion and
https://github.com/OpenSC/libp11/issues/676#issuecomment-5341749942 is
the specific recommendation.
- Debian hit the same defect and fixed it in openssl rather than libp11.
https://bugs.debian.org/1074764 was reported on 2024-07-02 against
libssl3, and openssl 3.0.13-1~deb12u2 shipped to bookworm on 2024-07-05
with the changelog entry "Revert "Improved detection of engine-provided
private "classic" keys" (Closes: #1074764)", three days later. It has
been carried in bookworm ever since.
- Upstream OpenSSL references.
- the defect,
https://github.com/openssl/openssl/commit/2b74e75331a27fc89cad9c8ea6a26c70019300b5
- the revert on openssl-3.0,
https://github.com/openssl/openssl/commit/ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6
- the revert on master,
https://github.com/openssl/openssl/commit/39ea78379826fa98e8dc8c0d2b07e2c17cd68380
- the pull request it was merged under,
https://github.com/openssl/openssl/pull/23063
- the regressions upstream expected,
https://github.com/openssl/openssl/issues/17092 and
https://github.com/openssl/openssl/issues/17286
- the open engine issue that predates the revert,
https://github.com/openssl/openssl/issues/23137
- Downstream reports of the same crash,
https://github.com/mtrojnar/osslsigncode/issues/410 from the PuTTY
maintainer signing releases with a SafeNet token, and
https://github.com/mtrojnar/osslsigncode/issues/316
- - Related Ubuntu bugs. LP #2163152 is the regression caused by the
- libp11 workaround, reverted in 0.4.12-1.1ubuntu2. LP #2119094, LP
- #2067163 and LP #2097330 are further reports of this crash.
+ - Related Ubuntu bugs. LP: #2163152 is the regression caused by the
+ libp11 workaround, reverted in 0.4.12-1.1ubuntu2. LP: #2119094, LP:
+ #2067163 and LP: #2097330 are further reports of this crash.
- The previous description of this bug was the SRU template for the
libp11 workaround, which is now being reverted. You can find the old SRU
template description from this SRU bug's activity history.
** Description changed:
Note: This bug report, analysis of the issue, and the potential fix were
created using the assistance of an LLM.
[ Impact ]
OpenSSL 3.0.12 and 3.0.13 carry commit 2b74e75 ("Improved detection of
engine-provided private classic keys"), which runs a get1/set1 round-
trip on the key returned by ENGINE_load_private_key(). That round-trip
calls ENGINE_finish() on the key's engine and clears the binding,
dropping the functional reference the engine took for itself.
Applications that then release their own engine reference before using
the key take the reference count to zero, so the PKCS#11 context is torn
down while the key is still in use, and signing dereferences freed
memory. sbsign, sbvarsign, osslsigncode and Apache mod_ssl all follow
that pattern. Applications that hold their reference until teardown,
such as the openssl CLI, wpa_supplicant, libcurl, nginx and libpq, are
unaffected, which is why this does not reproduce with "openssl pkeyutl".
Reported in Ubuntu here and in LP: #2119094 (Google Cloud KMS and
DigiCert KeyLocker code signing), LP: #2067163 and LP: #2097330, and
upstream as mtrojnar/osslsigncode#410 and #316.
Upstream reverted 2b74e75 in commit
ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6 on the openssl-3.0 branch,
which is 39ea78379826fa98e8dc8c0d2b07e2c17cd68380 on master. It was
released in 3.0.14 and has been carried in every 3.0.x since. noble is
the only supported Ubuntu series still carrying the defect. jammy has
3.0.2-0ubuntu1.30, which predates the change, and resolute and stonking
are both past the revert.
This upload backports that revert as a single patch deleting 42 lines
from crypto/engine/eng_pkey.c. No other patch in noble's 86-patch stack
touches crypto/engine/, so it applies with no fuzz or offset.
This bug was previously fixed in libp11 rather than openssl, by
backporting a workaround that registers the PKCS#11 engine as the
- process-wide default for RSA and EC. That caused its own regression, LP
+ process-wide default for RSA and EC. That caused its own regression, LP:
#2163152, and has been reverted in libp11 0.4.12-1.1ubuntu2, currently
in noble-proposed. libp11's upstream maintainer declined to fix the side
effect in libp11 and recommended this backport instead, saying "The
clean solution for affected distributions is to backport
openssl/openssl#23063 and disable this libp11 workaround for that
patched OpenSSL build. If the distribution retains the runtime version
number 3.0.13, both changes are necessary because OpenSSL_version_num()
cannot distinguish the backport." Debian reached the same conclusion
independently. The intention is to release the libp11 revert and this
openssl upload together, so that noble never spends time in the crashing
state.
[ Test Plan ]
Reproducible with SoftHSM2 and no hardware. libp11 must be
0.4.12-1.1build2 or 0.4.12-1.1ubuntu2, because the workaround in
0.4.12-1.1ubuntu1 masks the crash.
1. sudo apt install softhsm2 opensc libengine-pkcs11-openssl sbsigntool
shim-signed
2. Create a token, import an RSA key and a certificate.
openssl req -x509 -newkey rsa:2048 -keyout k.pem -out c.pem -days 365
-nodes -subj "/CN=Test"
softhsm2-util --init-token --free --label test --so-pin 1234 --pin 1234
softhsm2-util --import k.pem --token test --label testkey --id 01 --pin
1234
3. Sign a PE binary through the engine.
sbsign --engine pkcs11 --key
'pkcs11:token=test;object=testkey;type=private;pin-value=1234' --cert
c.pem --output /dev/null /usr/lib/shim/shimx64.efi
Before fix, Segmentation fault, exit 139.
After fix, "Signing Unsigned original image", exit 0.
Any PKCS#11 token works, substituting its own key URI. Verified with
SoftHSM2 and with a YubiHSM 2.
[ Where problems could occur ]
- openssl is in main and on every Ubuntu system, and 1397 binary
packages in noble depend on libssl3t64, so any defect introduced here
has an unusually large blast radius. That alone justifies caution
regardless of how small the change is. What bounds the risk is
reachability rather than popularity. The reverted code sits in
ENGINE_load_private_key(), part of the deprecated ENGINE API, and runs
only when an application explicitly loads a private key through an
engine. Nothing on a default install does that, since it needs an engine
to be configured and a token or HSM to be present. The patch deletes 42
lines and adds none, changes no header, no symbol and no struct layout,
so the ABI is untouched and nothing needs rebuilding.
- The patch restores crypto/engine/eng_pkey.c to its 3.0.11 form, so any
OpenSSL ENGINE that relied on OpenSSL coercing its returned key to
legacy will behave differently. Upstream named the two regressions this
revert would cause before merging it, openssl#17092 and openssl#17286.
Both came from the out-of-tree e_nss engine, which upstream judged to be
engine-side bugs already worked around there. Both issues are closed,
neither has had activity since 2023-10-04, and e_nss is not packaged in
Ubuntu.
- The engines shipped in noble on amd64, taken from the release and
updates Contents indexes, are afalg, loader_attic and padlock from
libssl3t64 itself, plus pkcs11 from libengine-pkcs11-openssl, tpm2tss
from libengine-tpm2-tss-openssl, gost from libengine-gost-openssl, and
qatengine. Only libp11 changes behaviour, in the intended direction.
tpm2tss already builds legacy keys, so the round-trip was a no-op for
it. The qatengine KPT path was not exercised, since it needs QAT
hardware.
- The reverted code is only reachable via ENGINE_load_private_key(), so
TLS handshakes, certificate verification, FIPS mode and provider-only
stacks are untouched.
- Engine teardown moves from key-load time back to EVP_PKEY_free time.
That is the pre-3.0.12 ordering, but it is still a change for every
consumer of the engine path.
- OpenSSL's own test suite cannot detect this, because no test signs
with an engine-loaded key. The suite passing says the patch applies
cleanly and nothing more, so verification has to be manual.
- On the field record, the revert has been in Debian bookworm since
openssl 3.0.13-1~deb12u2 in July 2024 and in every upstream 3.0.x since
3.0.14, with no report anywhere of a regression caused by it.
openssl#23137 is open and labelled a regression against engine-backed DH
keys, but it was filed on 2023-12-22, six weeks before the revert
landed, against 3.0.12, and its root cause is in crypto/dh/dh_backend.c.
Measured with SoftHSM2 and a YubiHSM 2, signing with sbsign against an
RSA-2048 token key.
openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1build2 sbsign
exits 139
openssl 3.0.13-0ubuntu3.15 + libp11 0.4.12-1.1ubuntu1 sbsign
exits 0, engine left as process-wide default
openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1build2 sbsign
exits 0, engine not left as default
openssl 3.0.13-0ubuntu3.16~ppa1 + libp11 0.4.12-1.1ubuntu2~ppa1 sbsign
exits 0, engine not left as default
The last two rows used PPA builds based on 3.0.13-0ubuntu3.15, before
the 3.0.13-0ubuntu3.16 security update. This upload rebases the revert
onto that security update and will be re-verified against the -proposed
package.
[ Other Info ]
- This SRU was invited in 2024. LP: #2062167
(https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/2062167)
proposed exactly this commit for noble before release, saying "The
bigger one is ad6cbe4b...: Revert "Improved detection of engine-provided
private "classic" keys" ... All look safe to me." It was deferred with
"it's too late for this right now, considering we're in Final Freeze for
24.04 ... Let's revisit as an SRU", and never filed.
- Christian Ehrhardt identified the same commit independently on LP:
#2119094, comment #6,
https://bugs.launchpad.net/ubuntu/+source/libp11/+bug/2119094/comments/6
- Upstream libp11 declined to fix the workaround's side effect in libp11
and recommended that distributions backport the OpenSSL revert and drop
the workaround. OpenSC/libp11#676 is the discussion and
https://github.com/OpenSC/libp11/issues/676#issuecomment-5341749942 is
the specific recommendation.
- Debian hit the same defect and fixed it in openssl rather than libp11.
https://bugs.debian.org/1074764 was reported on 2024-07-02 against
libssl3, and openssl 3.0.13-1~deb12u2 shipped to bookworm on 2024-07-05
with the changelog entry "Revert "Improved detection of engine-provided
private "classic" keys" (Closes: #1074764)", three days later. It has
been carried in bookworm ever since.
- Upstream OpenSSL references.
- the defect,
https://github.com/openssl/openssl/commit/2b74e75331a27fc89cad9c8ea6a26c70019300b5
- the revert on openssl-3.0,
https://github.com/openssl/openssl/commit/ad6cbe4b7f57a783a66a7ae883ea0d35ef5f82b6
- the revert on master,
https://github.com/openssl/openssl/commit/39ea78379826fa98e8dc8c0d2b07e2c17cd68380
- the pull request it was merged under,
https://github.com/openssl/openssl/pull/23063
- the regressions upstream expected,
https://github.com/openssl/openssl/issues/17092 and
https://github.com/openssl/openssl/issues/17286
- the open engine issue that predates the revert,
https://github.com/openssl/openssl/issues/23137
- Downstream reports of the same crash,
https://github.com/mtrojnar/osslsigncode/issues/410 from the PuTTY
maintainer signing releases with a SafeNet token, and
https://github.com/mtrojnar/osslsigncode/issues/316
- Related Ubuntu bugs. LP: #2163152 is the regression caused by the
libp11 workaround, reverted in 0.4.12-1.1ubuntu2. LP: #2119094, LP:
#2067163 and LP: #2097330 are further reports of this crash.
- The previous description of this bug was the SRU template for the
libp11 workaround, which is now being reverted. You can find the old SRU
template description from this SRU bug's activity history.
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2158304
Title:
[SRU] sbsign (and any tool using the OpenSSL PKCS#11 engine) segfaults
when signing via a PKCS#11 token on OpenSSL 3.0.13
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/libp11/+bug/2158304/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs