This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch CAMEL-22010 in repository https://gitbox.apache.org/repos/asf/camel.git
commit c3cd5e44dcefea145d1096a49ceaab70830928ea Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Thu Apr 24 11:37:47 2025 +0200 CAMEL-22010 - Camel-PQC: Define an option to store result of extractSecretKeyFromEncapsulation as header or in body Signed-off-by: Andrea Cosentino <anco...@gmail.com> --- .../org/apache/camel/catalog/components/pqc.json | 17 +-- .../component/pqc/PQCComponentConfigurer.java | 6 ++ .../camel/component/pqc/PQCEndpointConfigurer.java | 6 ++ .../camel/component/pqc/PQCEndpointUriFactory.java | 3 +- .../org/apache/camel/component/pqc/pqc.json | 17 +-- .../camel/component/pqc/PQCConfiguration.java | 15 +++ .../apache/camel/component/pqc/PQCConstants.java | 4 + .../apache/camel/component/pqc/PQCProducer.java | 6 +- ...ncapsulationCryptoRoundTripAESAsHeaderTest.java | 118 +++++++++++++++++++++ .../component/dsl/PqcComponentBuilderFactory.java | 19 ++++ .../endpoint/dsl/PQCEndpointBuilderFactory.java | 45 ++++++++ 11 files changed, 240 insertions(+), 16 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pqc.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pqc.json index 9dca96d95a4..601b3c0cce1 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pqc.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pqc.json @@ -33,15 +33,17 @@ "keyPair": { "index": 6, "kind": "property", "displayName": "Key Pair", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.KeyPair", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The KeyPair to be used" }, "signatureAlgorithm": { "index": 7, "kind": "property", "displayName": "Signature Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "MLDSA", "SLHDSA", "LMS", "XMSS", "FALCON", "PICNIC", "RAINBOW" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description" [...] "signer": { "index": 8, "kind": "property", "displayName": "Signer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.Signature", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The Signer to be used" }, - "symmetricKeyAlgorithm": { "index": 9, "kind": "property", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "c [...] - "symmetricKeyLength": { "index": 10, "kind": "property", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" }, - "healthCheckConsumerEnabled": { "index": 11, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, - "healthCheckProducerEnabled": { "index": 12, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on produce [...] + "storeExtractedSecretKeyAsHeader": { "index": 9, "kind": "property", "displayName": "Store Extracted Secret Key As Header", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "In the context of extractSecr [...] + "symmetricKeyAlgorithm": { "index": 10, "kind": "property", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, " [...] + "symmetricKeyLength": { "index": 11, "kind": "property", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" }, + "healthCheckConsumerEnabled": { "index": 12, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, + "healthCheckProducerEnabled": { "index": 13, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on produce [...] }, "headers": { "CamelPQCOperation": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation we want to perform", "constantName": "org.apache.camel.component.pqc.PQCConstants#OPERATION" }, "CamelPQCSignature": { "index": 1, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The signature of a body", "constantName": "org.apache.camel.component.pqc.PQCConstants#SIGNATURE" }, - "CamelPQCVerification": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The result of verification of a Body signature", "constantName": "org.apache.camel.component.pqc.PQCConstants#VERIFY" } + "CamelPQCVerification": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The result of verification of a Body signature", "constantName": "org.apache.camel.component.pqc.PQCConstants#VERIFY" }, + "CamelPQCSecretKey": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The extracted key in case of extractSecretKeyFromEncapsulation operation and storeExtractedSecretKeyAsHeader option enabled", "constantName": "org.apache.camel.component.pqc.PQCConstants#SECRET_KEY" } }, "properties": { "label": { "index": 0, "kind": "path", "displayName": "Label", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "Logical name" }, @@ -52,7 +54,8 @@ "keyPair": { "index": 5, "kind": "parameter", "displayName": "Key Pair", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.KeyPair", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The KeyPair to be used" }, "signatureAlgorithm": { "index": 6, "kind": "parameter", "displayName": "Signature Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "MLDSA", "SLHDSA", "LMS", "XMSS", "FALCON", "PICNIC", "RAINBOW" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description [...] "signer": { "index": 7, "kind": "parameter", "displayName": "Signer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.Signature", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The Signer to be used" }, - "symmetricKeyAlgorithm": { "index": 8, "kind": "parameter", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, " [...] - "symmetricKeyLength": { "index": 9, "kind": "parameter", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" } + "storeExtractedSecretKeyAsHeader": { "index": 8, "kind": "parameter", "displayName": "Store Extracted Secret Key As Header", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "In the context of extractSec [...] + "symmetricKeyAlgorithm": { "index": 9, "kind": "parameter", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, " [...] + "symmetricKeyLength": { "index": 10, "kind": "parameter", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" } } } diff --git a/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCComponentConfigurer.java b/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCComponentConfigurer.java index ecb99708b40..e73482ba596 100644 --- a/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCComponentConfigurer.java +++ b/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCComponentConfigurer.java @@ -49,6 +49,8 @@ public class PQCComponentConfigurer extends PropertyConfigurerSupport implements case "signaturealgorithm": case "signatureAlgorithm": getOrCreateConfiguration(target).setSignatureAlgorithm(property(camelContext, java.lang.String.class, value)); return true; case "signer": getOrCreateConfiguration(target).setSigner(property(camelContext, java.security.Signature.class, value)); return true; + case "storeextractedsecretkeyasheader": + case "storeExtractedSecretKeyAsHeader": getOrCreateConfiguration(target).setStoreExtractedSecretKeyAsHeader(property(camelContext, boolean.class, value)); return true; case "symmetrickeyalgorithm": case "symmetricKeyAlgorithm": getOrCreateConfiguration(target).setSymmetricKeyAlgorithm(property(camelContext, java.lang.String.class, value)); return true; case "symmetrickeylength": @@ -84,6 +86,8 @@ public class PQCComponentConfigurer extends PropertyConfigurerSupport implements case "signaturealgorithm": case "signatureAlgorithm": return java.lang.String.class; case "signer": return java.security.Signature.class; + case "storeextractedsecretkeyasheader": + case "storeExtractedSecretKeyAsHeader": return boolean.class; case "symmetrickeyalgorithm": case "symmetricKeyAlgorithm": return java.lang.String.class; case "symmetrickeylength": @@ -115,6 +119,8 @@ public class PQCComponentConfigurer extends PropertyConfigurerSupport implements case "signaturealgorithm": case "signatureAlgorithm": return getOrCreateConfiguration(target).getSignatureAlgorithm(); case "signer": return getOrCreateConfiguration(target).getSigner(); + case "storeextractedsecretkeyasheader": + case "storeExtractedSecretKeyAsHeader": return getOrCreateConfiguration(target).isStoreExtractedSecretKeyAsHeader(); case "symmetrickeyalgorithm": case "symmetricKeyAlgorithm": return getOrCreateConfiguration(target).getSymmetricKeyAlgorithm(); case "symmetrickeylength": diff --git a/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointConfigurer.java b/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointConfigurer.java index bed7d3a3aa6..5b10acac77a 100644 --- a/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointConfigurer.java +++ b/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointConfigurer.java @@ -35,6 +35,8 @@ public class PQCEndpointConfigurer extends PropertyConfigurerSupport implements case "signaturealgorithm": case "signatureAlgorithm": target.getConfiguration().setSignatureAlgorithm(property(camelContext, java.lang.String.class, value)); return true; case "signer": target.getConfiguration().setSigner(property(camelContext, java.security.Signature.class, value)); return true; + case "storeextractedsecretkeyasheader": + case "storeExtractedSecretKeyAsHeader": target.getConfiguration().setStoreExtractedSecretKeyAsHeader(property(camelContext, boolean.class, value)); return true; case "symmetrickeyalgorithm": case "symmetricKeyAlgorithm": target.getConfiguration().setSymmetricKeyAlgorithm(property(camelContext, java.lang.String.class, value)); return true; case "symmetrickeylength": @@ -63,6 +65,8 @@ public class PQCEndpointConfigurer extends PropertyConfigurerSupport implements case "signaturealgorithm": case "signatureAlgorithm": return java.lang.String.class; case "signer": return java.security.Signature.class; + case "storeextractedsecretkeyasheader": + case "storeExtractedSecretKeyAsHeader": return boolean.class; case "symmetrickeyalgorithm": case "symmetricKeyAlgorithm": return java.lang.String.class; case "symmetrickeylength": @@ -87,6 +91,8 @@ public class PQCEndpointConfigurer extends PropertyConfigurerSupport implements case "signaturealgorithm": case "signatureAlgorithm": return target.getConfiguration().getSignatureAlgorithm(); case "signer": return target.getConfiguration().getSigner(); + case "storeextractedsecretkeyasheader": + case "storeExtractedSecretKeyAsHeader": return target.getConfiguration().isStoreExtractedSecretKeyAsHeader(); case "symmetrickeyalgorithm": case "symmetricKeyAlgorithm": return target.getConfiguration().getSymmetricKeyAlgorithm(); case "symmetrickeylength": diff --git a/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointUriFactory.java b/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointUriFactory.java index 9054e90e7ff..2cb2277e03f 100644 --- a/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointUriFactory.java +++ b/components/camel-pqc/src/generated/java/org/apache/camel/component/pqc/PQCEndpointUriFactory.java @@ -23,7 +23,7 @@ public class PQCEndpointUriFactory extends org.apache.camel.support.component.En private static final Set<String> SECRET_PROPERTY_NAMES; private static final Set<String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(10); + Set<String> props = new HashSet<>(11); props.add("keyEncapsulationAlgorithm"); props.add("keyGenerator"); props.add("keyPair"); @@ -32,6 +32,7 @@ public class PQCEndpointUriFactory extends org.apache.camel.support.component.En props.add("operation"); props.add("signatureAlgorithm"); props.add("signer"); + props.add("storeExtractedSecretKeyAsHeader"); props.add("symmetricKeyAlgorithm"); props.add("symmetricKeyLength"); PROPERTY_NAMES = Collections.unmodifiableSet(props); diff --git a/components/camel-pqc/src/generated/resources/META-INF/org/apache/camel/component/pqc/pqc.json b/components/camel-pqc/src/generated/resources/META-INF/org/apache/camel/component/pqc/pqc.json index 9dca96d95a4..601b3c0cce1 100644 --- a/components/camel-pqc/src/generated/resources/META-INF/org/apache/camel/component/pqc/pqc.json +++ b/components/camel-pqc/src/generated/resources/META-INF/org/apache/camel/component/pqc/pqc.json @@ -33,15 +33,17 @@ "keyPair": { "index": 6, "kind": "property", "displayName": "Key Pair", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.KeyPair", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The KeyPair to be used" }, "signatureAlgorithm": { "index": 7, "kind": "property", "displayName": "Signature Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "MLDSA", "SLHDSA", "LMS", "XMSS", "FALCON", "PICNIC", "RAINBOW" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description" [...] "signer": { "index": 8, "kind": "property", "displayName": "Signer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.Signature", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The Signer to be used" }, - "symmetricKeyAlgorithm": { "index": 9, "kind": "property", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "c [...] - "symmetricKeyLength": { "index": 10, "kind": "property", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" }, - "healthCheckConsumerEnabled": { "index": 11, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, - "healthCheckProducerEnabled": { "index": 12, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on produce [...] + "storeExtractedSecretKeyAsHeader": { "index": 9, "kind": "property", "displayName": "Store Extracted Secret Key As Header", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "In the context of extractSecr [...] + "symmetricKeyAlgorithm": { "index": 10, "kind": "property", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, " [...] + "symmetricKeyLength": { "index": 11, "kind": "property", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" }, + "healthCheckConsumerEnabled": { "index": 12, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, + "healthCheckProducerEnabled": { "index": 13, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on produce [...] }, "headers": { "CamelPQCOperation": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation we want to perform", "constantName": "org.apache.camel.component.pqc.PQCConstants#OPERATION" }, "CamelPQCSignature": { "index": 1, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The signature of a body", "constantName": "org.apache.camel.component.pqc.PQCConstants#SIGNATURE" }, - "CamelPQCVerification": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The result of verification of a Body signature", "constantName": "org.apache.camel.component.pqc.PQCConstants#VERIFY" } + "CamelPQCVerification": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The result of verification of a Body signature", "constantName": "org.apache.camel.component.pqc.PQCConstants#VERIFY" }, + "CamelPQCSecretKey": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The extracted key in case of extractSecretKeyFromEncapsulation operation and storeExtractedSecretKeyAsHeader option enabled", "constantName": "org.apache.camel.component.pqc.PQCConstants#SECRET_KEY" } }, "properties": { "label": { "index": 0, "kind": "path", "displayName": "Label", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "Logical name" }, @@ -52,7 +54,8 @@ "keyPair": { "index": 5, "kind": "parameter", "displayName": "Key Pair", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.KeyPair", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The KeyPair to be used" }, "signatureAlgorithm": { "index": 6, "kind": "parameter", "displayName": "Signature Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "MLDSA", "SLHDSA", "LMS", "XMSS", "FALCON", "PICNIC", "RAINBOW" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description [...] "signer": { "index": 7, "kind": "parameter", "displayName": "Signer", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.security.Signature", "deprecated": false, "deprecationNote": "", "autowired": true, "secret": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The Signer to be used" }, - "symmetricKeyAlgorithm": { "index": 8, "kind": "parameter", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, " [...] - "symmetricKeyLength": { "index": 9, "kind": "parameter", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" } + "storeExtractedSecretKeyAsHeader": { "index": 8, "kind": "parameter", "displayName": "Store Extracted Secret Key As Header", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "In the context of extractSec [...] + "symmetricKeyAlgorithm": { "index": 9, "kind": "parameter", "displayName": "Symmetric Key Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "AES", "ARIA", "RC2", "RC5", "CAMELLIA", "CAST5", "CAST6", "CHACHA7539", "DSTU7624", "GOST28147", "GOST3412_2015", "GRAIN128", "HC128", "HC256", "SALSA20", "SEED", "SM4", "DESEDE" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, " [...] + "symmetricKeyLength": { "index": 10, "kind": "parameter", "displayName": "Symmetric Key Length", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 128, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration", "configurationField": "configuration", "description": "The required length of the symmetric key used" } } } diff --git a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConfiguration.java b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConfiguration.java index e8e40876eb6..820930f0927 100644 --- a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConfiguration.java +++ b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConfiguration.java @@ -57,6 +57,9 @@ public class PQCConfiguration implements Cloneable { @UriParam @Metadata(label = "advanced", defaultValue = "128") private int symmetricKeyLength = 128; + @UriParam + @Metadata(label = "advanced", defaultValue = "false") + private boolean storeExtractedSecretKeyAsHeader = false; public PQCOperations getOperation() { return operation; @@ -146,6 +149,18 @@ public class PQCConfiguration implements Cloneable { this.symmetricKeyLength = symmetricKeyLength; } + public boolean isStoreExtractedSecretKeyAsHeader() { + return storeExtractedSecretKeyAsHeader; + } + + /** + * In the context of extractSecretKeyFromEncapsulation operation, this option define if we want to have the key set + * as header + */ + public void setStoreExtractedSecretKeyAsHeader(boolean storeExtractedSecretKeyAsHeader) { + this.storeExtractedSecretKeyAsHeader = storeExtractedSecretKeyAsHeader; + } + // ************************************************* // // ************************************************* diff --git a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConstants.java b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConstants.java index 6c5cc255884..dd23c2123a7 100644 --- a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConstants.java +++ b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCConstants.java @@ -30,4 +30,8 @@ public interface PQCConstants { @Metadata(description = "The result of verification of a Body signature", javaType = "Boolean") String VERIFY = "CamelPQCVerification"; + + @Metadata(description = "The extracted key in case of extractSecretKeyFromEncapsulation operation and storeExtractedSecretKeyAsHeader option enabled", + javaType = "Boolean") + String SECRET_KEY = "CamelPQCSecretKey"; } diff --git a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCProducer.java b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCProducer.java index 1ab4a966660..1b6e76fb572 100644 --- a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCProducer.java +++ b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCProducer.java @@ -187,7 +187,11 @@ public class PQCProducer extends DefaultProducer { SecretKey restoredKey = new SecretKeySpec(payload.getEncoded(), getConfiguration().getSymmetricKeyAlgorithm()); - exchange.getMessage().setBody(restoredKey, SecretKey.class); + if (!getConfiguration().isStoreExtractedSecretKeyAsHeader()) { + exchange.getMessage().setBody(restoredKey, SecretKey.class); + } else { + exchange.getMessage().setHeader(PQCConstants.SECRET_KEY, restoredKey); + } } } diff --git a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCMLKEMGenerateEncapsulationCryptoRoundTripAESAsHeaderTest.java b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCMLKEMGenerateEncapsulationCryptoRoundTripAESAsHeaderTest.java new file mode 100644 index 00000000000..61385ae8f94 --- /dev/null +++ b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCMLKEMGenerateEncapsulationCryptoRoundTripAESAsHeaderTest.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.pqc; + +import java.security.*; + +import javax.crypto.KeyGenerator; + +import org.apache.camel.BindToRegistry; +import org.apache.camel.EndpointInject; +import org.apache.camel.Produce; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.converter.crypto.CryptoDataFormat; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; +import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class PQCMLKEMGenerateEncapsulationCryptoRoundTripAESAsHeaderTest extends CamelTestSupport { + + @EndpointInject("mock:encapsulate") + protected MockEndpoint resultEncapsulate; + + @Produce("direct:encapsulate") + protected ProducerTemplate templateEncapsulate; + + @EndpointInject("mock:encrypted") + protected MockEndpoint resultEncrypted; + + @EndpointInject("mock:unencrypted") + protected MockEndpoint resultDecrypted; + + public PQCMLKEMGenerateEncapsulationCryptoRoundTripAESAsHeaderTest() throws NoSuchAlgorithmException { + } + + @Override + protected RouteBuilder createRouteBuilder() { + CryptoDataFormat cryptoFormat = new CryptoDataFormat("AES", null); + return new RouteBuilder() { + @Override + public void configure() { + from("direct:encapsulate").to("pqc:keyenc?operation=generateSecretKeyEncapsulation&symmetricKeyAlgorithm=AES") + .to("mock:encapsulate") + .to("pqc:keyenc?operation=extractSecretKeyEncapsulation&symmetricKeyAlgorithm=AES") + .to("pqc:keyenc?operation=extractSecretKeyFromEncapsulation&symmetricKeyAlgorithm=AES&storeExtractedSecretKeyAsHeader=true") + .setHeader(CryptoDataFormat.KEY, header(PQCConstants.SECRET_KEY)) + .log("${headers}") + .setBody(constant("Hello")) + .marshal(cryptoFormat) + .log("Encrypted ${body}") + .to("mock:encrypted") + .unmarshal(cryptoFormat) + .log("Unencrypted ${body}") + .to("mock:unencrypted"); + ; + } + }; + } + + @BeforeAll + public static void startup() throws Exception { + Security.addProvider(new BouncyCastleProvider()); + Security.addProvider(new BouncyCastlePQCProvider()); + } + + @Test + void testSignAndVerify() throws Exception { + resultEncapsulate.expectedMessageCount(1); + resultEncrypted.expectedMessageCount(1); + resultDecrypted.expectedMessageCount(1); + templateEncapsulate.sendBody("Hello"); + resultEncapsulate.assertIsSatisfied(); + assertNotNull(resultEncapsulate.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class)); + assertEquals(PQCSymmetricAlgorithms.AES.getAlgorithm(), + resultEncapsulate.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class).getAlgorithm()); + assertNotNull(resultEncrypted.getExchanges().get(0).getMessage().getBody()); + assertEquals("Hello", resultDecrypted.getExchanges().get(0).getMessage().getBody(String.class)); + } + + @BindToRegistry("Keypair") + public KeyPair setKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { + KeyPairGenerator kpg = KeyPairGenerator.getInstance(PQCKeyEncapsulationAlgorithms.MLKEM.getAlgorithm(), + PQCKeyEncapsulationAlgorithms.MLKEM.getBcProvider()); + kpg.initialize(MLKEMParameterSpec.ml_kem_512, new SecureRandom()); + KeyPair kp = kpg.generateKeyPair(); + return kp; + } + + @BindToRegistry("KeyGenerator") + public KeyGenerator setKeyGenerator() + throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { + KeyGenerator kg = KeyGenerator.getInstance(PQCKeyEncapsulationAlgorithms.MLKEM.getAlgorithm(), + PQCKeyEncapsulationAlgorithms.MLKEM.getBcProvider()); + return kg; + } +} diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PqcComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PqcComponentBuilderFactory.java index 89868dcffee..d482e2d261d 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PqcComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PqcComponentBuilderFactory.java @@ -209,6 +209,24 @@ public interface PqcComponentBuilderFactory { return this; } + + /** + * In the context of extractSecretKeyFromEncapsulation operation, this + * option define if we want to have the key set as header. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: advanced + * + * @param storeExtractedSecretKeyAsHeader the value to set + * @return the dsl builder + */ + default PqcComponentBuilder storeExtractedSecretKeyAsHeader(boolean storeExtractedSecretKeyAsHeader) { + doSetProperty("storeExtractedSecretKeyAsHeader", storeExtractedSecretKeyAsHeader); + return this; + } + /** * In case we are using KEM operations, we need a Symmetric algorithm to * be defined for the flow to work. @@ -309,6 +327,7 @@ public interface PqcComponentBuilderFactory { case "keyPair": getOrCreateConfiguration((PQCComponent) component).setKeyPair((java.security.KeyPair) value); return true; case "signatureAlgorithm": getOrCreateConfiguration((PQCComponent) component).setSignatureAlgorithm((java.lang.String) value); return true; case "signer": getOrCreateConfiguration((PQCComponent) component).setSigner((java.security.Signature) value); return true; + case "storeExtractedSecretKeyAsHeader": getOrCreateConfiguration((PQCComponent) component).setStoreExtractedSecretKeyAsHeader((boolean) value); return true; case "symmetricKeyAlgorithm": getOrCreateConfiguration((PQCComponent) component).setSymmetricKeyAlgorithm((java.lang.String) value); return true; case "symmetricKeyLength": getOrCreateConfiguration((PQCComponent) component).setSymmetricKeyLength((int) value); return true; case "healthCheckConsumerEnabled": ((PQCComponent) component).setHealthCheckConsumerEnabled((boolean) value); return true; diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/PQCEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/PQCEndpointBuilderFactory.java index 0b81fe20e54..79c36a63362 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/PQCEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/PQCEndpointBuilderFactory.java @@ -251,6 +251,38 @@ public interface PQCEndpointBuilderFactory { doSetProperty("signer", signer); return this; } + /** + * In the context of extractSecretKeyFromEncapsulation operation, this + * option define if we want to have the key set as header. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: advanced + * + * @param storeExtractedSecretKeyAsHeader the value to set + * @return the dsl builder + */ + default AdvancedPQCEndpointBuilder storeExtractedSecretKeyAsHeader(boolean storeExtractedSecretKeyAsHeader) { + doSetProperty("storeExtractedSecretKeyAsHeader", storeExtractedSecretKeyAsHeader); + return this; + } + /** + * In the context of extractSecretKeyFromEncapsulation operation, this + * option define if we want to have the key set as header. + * + * The option will be converted to a <code>boolean</code> type. + * + * Default: false + * Group: advanced + * + * @param storeExtractedSecretKeyAsHeader the value to set + * @return the dsl builder + */ + default AdvancedPQCEndpointBuilder storeExtractedSecretKeyAsHeader(String storeExtractedSecretKeyAsHeader) { + doSetProperty("storeExtractedSecretKeyAsHeader", storeExtractedSecretKeyAsHeader); + return this; + } /** * In case we are using KEM operations, we need a Symmetric algorithm to * be defined for the flow to work. @@ -400,6 +432,19 @@ public interface PQCEndpointBuilderFactory { public String pQCVerification() { return "CamelPQCVerification"; } + /** + * The extracted key in case of extractSecretKeyFromEncapsulation + * operation and storeExtractedSecretKeyAsHeader option enabled. + * + * The option is a: {@code Boolean} type. + * + * Group: producer + * + * @return the name of the header {@code PQCSecretKey}. + */ + public String pQCSecretKey() { + return "CamelPQCSecretKey"; + } } static PQCEndpointBuilder endpointBuilder(String componentName, String path) { class PQCEndpointBuilderImpl extends AbstractEndpointBuilder implements PQCEndpointBuilder, AdvancedPQCEndpointBuilder {