Andrea Cosentino created CAMEL-25795:
----------------------------------------
Summary: camel-pqc - stopping an endpoint removes the Bouncy
Castle providers from the whole JVM
Key: CAMEL-25795
URL: https://issues.apache.org/jira/browse/CAMEL-25795
Project: Camel
Issue Type: Bug
Components: camel-pqc
Reporter: Andrea Cosentino
{{PQCEndpoint.doStop()}} unconditionally removes the Bouncy Castle providers
from the process-global {{java.security.Security}} registry.
{{PQCEndpoint.java:74-83}}:
{code:java}
@Override
public void doStop() throws Exception {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) != null) {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
}
if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) !=
null) {
Security.removeProvider(BouncyCastlePQCProvider.PROVIDER_NAME);
}
super.doStop();
}
{code}
{{doStart()}} only *adds* the provider when it is absent —
{{PQCEndpoint.java:64-72}}:
{code:java}
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
{code}
So an endpoint routinely removes a provider it did not install: one registered
by the application in a static initialiser, by {{java.security}} configuration,
or by another Camel endpoint.
h3. Why it bites in practice
{{java.security.Security}} is shared by every {{CamelContext}}, by camel-crypto
/ camel-jsch / camel-ssh / camel-xmlsecurity, by the JSSE stack, and by all
non-Camel code in the JVM. The canonical route in this component's own
documentation uses two endpoints ({{pqc:sign}} + {{pqc:verify}}): stopping one
silently de-registers BC for the other and for the rest of the JVM, after which
every {{Signature.getInstance(..., "BC")}} fails with
{{NoSuchProviderException}}. Removal can also race with another thread that is
mid-operation.
CAMEL-22016 added the null guard but did not address provider ownership.
h3. Suggested fix
Record in the endpoint whether *this* endpoint actually added each provider,
and only remove the ones it added. Given that the registry is JVM-global and
there is no reference counting across endpoints, simply never removing the
providers is also a defensible option — adding a provider is idempotent and
cheap.
----
_Reported by Claude Code (AI agent) on behalf of [~oscerd]. Every code
reference was verified against commit {{7aae27315946}} on {{main}}._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)