Andrea Cosentino created CAMEL-25805:
----------------------------------------

             Summary: camel-pqc - the CamelPQCOperation header override fails 
with a NullPointerException
                 Key: CAMEL-25805
                 URL: https://issues.apache.org/jira/browse/CAMEL-25805
             Project: Camel
          Issue Type: Bug
          Components: camel-pqc
            Reporter: Andrea Cosentino


The producer lets a message choose the operation per exchange, but the 
resources each operation needs are created at start-up only for the 
*configured* operation.

{{PQCProducer.java:237-244}}:
{code:java}
    private PQCOperations determineOperation(Exchange exchange) {
        PQCOperations operation = 
exchange.getIn().getHeader(PQCConstants.OPERATION, PQCOperations.class);
        if (operation == null) {
            operation = getConfiguration().getOperation();
        }
        return operation;
    }
{code}

{{doStart()}} creates {{signer}} only for sign/verify ({{:386-392}}) and 
{{keyGenerator}} only for the two encapsulation operations ({{:398-404}}).

So with {{operation=sign}} on the endpoint and 
{{CamelPQCOperation=generateSecretKeyEncapsulation}} on the message, 
{{keyGeneratorForExchange()}} returns the null field — 
{{PQCProducer.java:647-652}}:
{code:java}
    private KeyGenerator keyGeneratorForExchange() throws 
NoSuchAlgorithmException {
        if (keyGeneratorAlgorithm == null) {
            return keyGenerator;
        }
{code}
and {{synchronized (generator)}} at {{:671}} throws a bare 
{{NullPointerException}} with nothing to indicate that the header was the cause.

{{CamelPQCOperation}} is public, {{@Metadata}}-documented API 
({{PQCConstants.java:25-26}}).

h3. Suggested fix

Either resolve the per-operation resources lazily on first use for whichever 
operation the exchange selects, or validate the header against what 
{{doStart()}} prepared and fail with a message naming both the configured and 
the requested operation.

h3. Two small related items in the same dispatch path

{{PQCProducer.java:228-229}} discards the offending value:
{code:java}
                default:
                    throw new IllegalArgumentException("Unsupported operation");
{code}
and {{:1274-1276}} swallows an unknown classical algorithm entirely with 
{{catch (IllegalArgumentException e) { // Unknown classical algorithm - will 
fail later during init }}} and no log line.

Separately, {{PQCConstants.java:34-36}} declares the wrong type for a header 
the producer sets to a {{SecretKey}} at {{:733}}:
{code:java}
    @Metadata(description = "The extracted key in case of 
extractSecretKeyFromEncapsulation operation and storeExtractedSecretKeyAsHeader 
option enabled",
              javaType = "Boolean")
    String SECRET_KEY = "CamelPQCSecretKey";
{code}
It should be {{javax.crypto.SecretKey}}, as {{HYBRID_SECRET_KEY}} correctly 
declares at {{:88}}. The wrong type is mirrored into the generated catalog and 
the rendered header table. {{OPERATION}} is likewise declared {{javaType = 
"String"}} but read as {{PQCOperations}}.

h3. Test gap

No test in {{src/test}} sets {{CamelPQCOperation}} at all, so the documented 
per-exchange override is entirely unexercised.

----
_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)

Reply via email to