oscerd commented on code in PR #28099:
URL: https://github.com/apache/camel/pull/28099#discussion_r4324721722


##########
components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCProducer.java:
##########
@@ -1146,47 +1156,102 @@ private void checkStatefulKeyBeforeSign() {
     }
 
     /**
-     * Persists stateful key state after a signing operation through the 
KeyLifecycleManager, if configured. This
-     * ensures the key index is tracked across restarts.
+     * Records the use of the signing key through the KeyLifecycleManager, if 
one is configured and the exchange names a
+     * key.
+     * <p/>
+     * This advances {@code usageCount}, which is what the {@code maxKeyUsage} 
rotation signal of
+     * {@link org.apache.camel.component.pqc.lifecycle.KeyRotationScheduler} 
reads. It therefore runs for every signing
+     * key, not only the stateful ones: ML-DSA, SLH-DSA and Falcon keys would 
otherwise sit at a usage count of zero
+     * forever and never be rotated.
+     * <p/>
+     * The key encapsulation operations do not call this method, so a KEM key 
still does not advance its usage count and
+     * {@code maxKeyUsage} does not apply to it.
+     * <p/>
+     * For a stateful signature key the advanced private key is stored as 
well, so the one-time index survives a
+     * restart.
      */
-    private void persistStatefulKeyStateAfterSign(Exchange exchange) throws 
Exception {
+    private void recordKeyUsageAfterSign(Exchange exchange) throws Exception {
         if (keyPair == null || keyPair.getPrivate() == null) {
             return;
         }
 
         PrivateKey privateKey = keyPair.getPrivate();
-        long remaining = getStatefulKeyRemaining(privateKey);
-        if (remaining < 0) {
-            // Not a stateful key
-            return;
-        }
+        boolean stateful = getStatefulKeyRemaining(privateKey) >= 0;
 
         KeyLifecycleManager klm = getConfiguration().getKeyLifecycleManager();
         if (klm == null) {
+            // Only the stateful risk is worth reporting here. A plain signing 
endpoint with no lifecycle management
+            // is an ordinary setup, and with no manager there is no 
maxKeyUsage threshold to miss.
+            if (stateful) {
+                warnKeyUsageNotRecorded(true, "no keyLifecycleManager is 
configured on the endpoint");
+            }
             return;
         }
 
         String keyId = exchange.getMessage().getHeader(PQCConstants.KEY_ID, 
String.class);
         if (ObjectHelper.isEmpty(keyId)) {
+            warnKeyUsageNotRecorded(stateful,
+                    "the exchange carries no " + PQCConstants.KEY_ID + " 
header identifying the key");
             return;
         }
 
-        // Update metadata with current usage
         KeyMetadata metadata = klm.getKeyMetadata(keyId);
         if (metadata == null) {

Review Comment:
   Fixed where the code comes from, in #28094: its commit "CAMEL-25797: Address 
review feedback - a failed metadata read for a non-stateful key keeps the 
signature" wraps the `getKeyMetadata` read like the `updateKeyMetadata` write. 
For a non-stateful key a failing read is logged once per producer and the 
signature is kept; for a stateful key it still fails the exchange, as the index 
must be persisted. This branch is rebased on that commit, so the wrap is in the 
code here as well, and 
`KeyRotationSignalsTest.aFailedMetadataReadKeepsTheSignatureOfAStatelessKey` 
covers it with a manager whose reads can be made to fail.
   
   _Claude Code on behalf of oscerd_
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to