This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new fccd8eda572 CAMEL-21969 - Camel-PQC: Support KEM operations (#17800)
fccd8eda572 is described below
commit fccd8eda572ca0c4b93e7eb113c059535b347699
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Apr 18 10:09:26 2025 +0200
CAMEL-21969 - Camel-PQC: Support KEM operations (#17800)
* CAMEL-21969 - Camel-PQC: Support KEM operations
Signed-off-by: Andrea Cosentino <[email protected]>
* CAMEL-21969 - Camel-PQC: Support KEM operations
Signed-off-by: Andrea Cosentino <[email protected]>
---------
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../org/apache/camel/catalog/components/pqc.json | 26 +++--
.../component/pqc/PQCComponentConfigurer.java | 20 +++-
.../camel/component/pqc/PQCEndpointConfigurer.java | 20 +++-
.../camel/component/pqc/PQCEndpointUriFactory.java | 5 +-
.../org/apache/camel/component/pqc/pqc.json | 26 +++--
.../camel/component/pqc/PQCConfiguration.java | 44 +++++++++
...ons.java => PQCKeyEncapsulationAlgorithms.java} | 19 +++-
.../apache/camel/component/pqc/PQCOperations.java | 6 +-
.../apache/camel/component/pqc/PQCProducer.java | 68 ++++++++++++-
...Operations.java => PQCSymmetricAlgorithms.java} | 16 +++-
.../pqc/PQCBIKEGenerateEncapsulationAESTest.java | 105 +++++++++++++++++++++
.../pqc/PQCMLKEMGenerateEncapsulationAESTest.java | 105 +++++++++++++++++++++
.../component/dsl/PqcComponentBuilderFactory.java | 51 ++++++++++
.../endpoint/dsl/PQCEndpointBuilderFactory.java | 59 ++++++++++++
14 files changed, 534 insertions(+), 36 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 0695a846795..56a677dff2e 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
@@ -26,13 +26,16 @@
"componentProperties": {
"configuration": { "index": 0, "kind": "property", "displayName":
"Configuration", "group": "producer", "label": "", "required": false, "type":
"object", "javaType": "org.apache.camel.component.pqc.PQCConfiguration",
"deprecated": false, "autowired": false, "secret": false, "description":
"Component configuration" },
"lazyStartProducer": { "index": 1, "kind": "property", "displayName":
"Lazy Start Producer", "group": "producer", "label": "producer", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": false, "description":
"Whether the producer should be started lazy (on the first message). By
starting lazy you can use this to allow CamelContext and routes to startup in
situations where a producer may otherwise fail [...]
- "operation": { "index": 2, "kind": "property", "displayName": "Operation",
"group": "producer", "label": "", "required": true, "type": "object",
"javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [ "sign",
"verify" ], "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The operation to perform" },
+ "operation": { "index": 2, "kind": "property", "displayName": "Operation",
"group": "producer", "label": "", "required": true, "type": "object",
"javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [ "sign",
"verify", "generateSecretKeyEncapsulation", "extractSecretKeyEncapsulation" ],
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configura [...]
"autowiredEnabled": { "index": 3, "kind": "property", "displayName":
"Autowired Enabled", "group": "advanced", "label": "advanced", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": true, "description":
"Whether autowiring is enabled. This is used for automatic autowiring options
(the option must be marked as autowired) by looking up in the registry to find
if there is a single instance of matching t [...]
- "keyPair": { "index": 4, "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": 5, "kind": "property", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair o [...]
- "signer": { "index": 6, "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" },
- "healthCheckConsumerEnabled": { "index": 7, "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": 8, "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 producer [...]
+ "keyEncapsulationAlgorithm": { "index": 4, "kind": "property",
"displayName": "Key Encapsulation Algorithm", "group": "advanced", "label":
"advanced", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "In case there is no keyGenerator, we specify
an algorithm t [...]
+ "keyGenerator": { "index": 5, "kind": "property", "displayName": "Key
Generator", "group": "advanced", "label": "advanced", "required": false,
"type": "object", "javaType": "javax.crypto.KeyGenerator", "deprecated": false,
"deprecationNote": "", "autowired": true, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "The Key Generator to be
used in encapsulation and extraction" },
+ "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", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair o [...]
+ "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",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case we are using KEM
operations, we need a Symmetric algorithm [...]
+ "healthCheckConsumerEnabled": { "index": 10, "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": 11, "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" },
@@ -41,10 +44,13 @@
},
"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" },
- "operation": { "index": 1, "kind": "parameter", "displayName":
"Operation", "group": "producer", "label": "", "required": true, "type":
"object", "javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [
"sign", "verify" ], "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The operation to perform" },
+ "operation": { "index": 1, "kind": "parameter", "displayName":
"Operation", "group": "producer", "label": "", "required": true, "type":
"object", "javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [
"sign", "verify", "generateSecretKeyEncapsulation",
"extractSecretKeyEncapsulation" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configur [...]
"lazyStartProducer": { "index": 2, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "required": false, "type": "boolean", "javaType":
"boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "description": "Whether the producer should be started
lazy (on the first message). By starting lazy you can use this to allow
CamelContext and routes to startup in situations where a produc [...]
- "keyPair": { "index": 3, "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": 4, "kind": "parameter", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair [...]
- "signer": { "index": 5, "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" }
+ "keyEncapsulationAlgorithm": { "index": 3, "kind": "parameter",
"displayName": "Key Encapsulation Algorithm", "group": "advanced", "label":
"advanced", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "In case there is no keyGenerator, we specify
an algorithm [...]
+ "keyGenerator": { "index": 4, "kind": "parameter", "displayName": "Key
Generator", "group": "advanced", "label": "advanced", "required": false,
"type": "object", "javaType": "javax.crypto.KeyGenerator", "deprecated": false,
"deprecationNote": "", "autowired": true, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "The Key Generator to be
used in encapsulation and extraction" },
+ "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", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair [...]
+ "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",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case we are using KEM
operations, we need a Symmetric algorithm [...]
}
}
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 e74c90c83c0..405f409a321 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
@@ -37,6 +37,10 @@ public class PQCComponentConfigurer extends
PropertyConfigurerSupport implements
case "healthCheckConsumerEnabled":
target.setHealthCheckConsumerEnabled(property(camelContext, boolean.class,
value)); return true;
case "healthcheckproducerenabled":
case "healthCheckProducerEnabled":
target.setHealthCheckProducerEnabled(property(camelContext, boolean.class,
value)); return true;
+ case "keyencapsulationalgorithm":
+ case "keyEncapsulationAlgorithm":
getOrCreateConfiguration(target).setKeyEncapsulationAlgorithm(property(camelContext,
java.lang.String.class, value)); return true;
+ case "keygenerator":
+ case "keyGenerator":
getOrCreateConfiguration(target).setKeyGenerator(property(camelContext,
javax.crypto.KeyGenerator.class, value)); return true;
case "keypair":
case "keyPair":
getOrCreateConfiguration(target).setKeyPair(property(camelContext,
java.security.KeyPair.class, value)); return true;
case "lazystartproducer":
@@ -45,13 +49,15 @@ 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 "symmetrickeyalgorithm":
+ case "symmetricKeyAlgorithm":
getOrCreateConfiguration(target).setSymmetricKeyAlgorithm(property(camelContext,
java.lang.String.class, value)); return true;
default: return false;
}
}
@Override
public String[] getAutowiredNames() {
- return new String[]{"keyPair", "signer"};
+ return new String[]{"keyGenerator", "keyPair", "signer"};
}
@Override
@@ -64,6 +70,10 @@ public class PQCComponentConfigurer extends
PropertyConfigurerSupport implements
case "healthCheckConsumerEnabled": return boolean.class;
case "healthcheckproducerenabled":
case "healthCheckProducerEnabled": return boolean.class;
+ case "keyencapsulationalgorithm":
+ case "keyEncapsulationAlgorithm": return java.lang.String.class;
+ case "keygenerator":
+ case "keyGenerator": return javax.crypto.KeyGenerator.class;
case "keypair":
case "keyPair": return java.security.KeyPair.class;
case "lazystartproducer":
@@ -72,6 +82,8 @@ public class PQCComponentConfigurer extends
PropertyConfigurerSupport implements
case "signaturealgorithm":
case "signatureAlgorithm": return java.lang.String.class;
case "signer": return java.security.Signature.class;
+ case "symmetrickeyalgorithm":
+ case "symmetricKeyAlgorithm": return java.lang.String.class;
default: return null;
}
}
@@ -87,6 +99,10 @@ public class PQCComponentConfigurer extends
PropertyConfigurerSupport implements
case "healthCheckConsumerEnabled": return
target.isHealthCheckConsumerEnabled();
case "healthcheckproducerenabled":
case "healthCheckProducerEnabled": return
target.isHealthCheckProducerEnabled();
+ case "keyencapsulationalgorithm":
+ case "keyEncapsulationAlgorithm": return
getOrCreateConfiguration(target).getKeyEncapsulationAlgorithm();
+ case "keygenerator":
+ case "keyGenerator": return
getOrCreateConfiguration(target).getKeyGenerator();
case "keypair":
case "keyPair": return getOrCreateConfiguration(target).getKeyPair();
case "lazystartproducer":
@@ -95,6 +111,8 @@ public class PQCComponentConfigurer extends
PropertyConfigurerSupport implements
case "signaturealgorithm":
case "signatureAlgorithm": return
getOrCreateConfiguration(target).getSignatureAlgorithm();
case "signer": return getOrCreateConfiguration(target).getSigner();
+ case "symmetrickeyalgorithm":
+ case "symmetricKeyAlgorithm": return
getOrCreateConfiguration(target).getSymmetricKeyAlgorithm();
default: return null;
}
}
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 10dad97b29e..3b0b352a379 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
@@ -23,6 +23,10 @@ public class PQCEndpointConfigurer extends
PropertyConfigurerSupport implements
public boolean configure(CamelContext camelContext, Object obj, String
name, Object value, boolean ignoreCase) {
PQCEndpoint target = (PQCEndpoint) obj;
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "keyencapsulationalgorithm":
+ case "keyEncapsulationAlgorithm":
target.getConfiguration().setKeyEncapsulationAlgorithm(property(camelContext,
java.lang.String.class, value)); return true;
+ case "keygenerator":
+ case "keyGenerator":
target.getConfiguration().setKeyGenerator(property(camelContext,
javax.crypto.KeyGenerator.class, value)); return true;
case "keypair":
case "keyPair":
target.getConfiguration().setKeyPair(property(camelContext,
java.security.KeyPair.class, value)); return true;
case "lazystartproducer":
@@ -31,18 +35,24 @@ 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 "symmetrickeyalgorithm":
+ case "symmetricKeyAlgorithm":
target.getConfiguration().setSymmetricKeyAlgorithm(property(camelContext,
java.lang.String.class, value)); return true;
default: return false;
}
}
@Override
public String[] getAutowiredNames() {
- return new String[]{"keyPair", "signer"};
+ return new String[]{"keyGenerator", "keyPair", "signer"};
}
@Override
public Class<?> getOptionType(String name, boolean ignoreCase) {
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "keyencapsulationalgorithm":
+ case "keyEncapsulationAlgorithm": return java.lang.String.class;
+ case "keygenerator":
+ case "keyGenerator": return javax.crypto.KeyGenerator.class;
case "keypair":
case "keyPair": return java.security.KeyPair.class;
case "lazystartproducer":
@@ -51,6 +61,8 @@ public class PQCEndpointConfigurer extends
PropertyConfigurerSupport implements
case "signaturealgorithm":
case "signatureAlgorithm": return java.lang.String.class;
case "signer": return java.security.Signature.class;
+ case "symmetrickeyalgorithm":
+ case "symmetricKeyAlgorithm": return java.lang.String.class;
default: return null;
}
}
@@ -59,6 +71,10 @@ public class PQCEndpointConfigurer extends
PropertyConfigurerSupport implements
public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
PQCEndpoint target = (PQCEndpoint) obj;
switch (ignoreCase ? name.toLowerCase() : name) {
+ case "keyencapsulationalgorithm":
+ case "keyEncapsulationAlgorithm": return
target.getConfiguration().getKeyEncapsulationAlgorithm();
+ case "keygenerator":
+ case "keyGenerator": return
target.getConfiguration().getKeyGenerator();
case "keypair":
case "keyPair": return target.getConfiguration().getKeyPair();
case "lazystartproducer":
@@ -67,6 +83,8 @@ public class PQCEndpointConfigurer extends
PropertyConfigurerSupport implements
case "signaturealgorithm":
case "signatureAlgorithm": return
target.getConfiguration().getSignatureAlgorithm();
case "signer": return target.getConfiguration().getSigner();
+ case "symmetrickeyalgorithm":
+ case "symmetricKeyAlgorithm": return
target.getConfiguration().getSymmetricKeyAlgorithm();
default: return null;
}
}
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 ca4d27133e1..def55d2d54c 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,13 +23,16 @@ 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<>(6);
+ Set<String> props = new HashSet<>(9);
+ props.add("keyEncapsulationAlgorithm");
+ props.add("keyGenerator");
props.add("keyPair");
props.add("label");
props.add("lazyStartProducer");
props.add("operation");
props.add("signatureAlgorithm");
props.add("signer");
+ props.add("symmetricKeyAlgorithm");
PROPERTY_NAMES = Collections.unmodifiableSet(props);
SECRET_PROPERTY_NAMES = Collections.emptySet();
MULTI_VALUE_PREFIXES = Collections.emptySet();
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 0695a846795..56a677dff2e 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
@@ -26,13 +26,16 @@
"componentProperties": {
"configuration": { "index": 0, "kind": "property", "displayName":
"Configuration", "group": "producer", "label": "", "required": false, "type":
"object", "javaType": "org.apache.camel.component.pqc.PQCConfiguration",
"deprecated": false, "autowired": false, "secret": false, "description":
"Component configuration" },
"lazyStartProducer": { "index": 1, "kind": "property", "displayName":
"Lazy Start Producer", "group": "producer", "label": "producer", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": false, "description":
"Whether the producer should be started lazy (on the first message). By
starting lazy you can use this to allow CamelContext and routes to startup in
situations where a producer may otherwise fail [...]
- "operation": { "index": 2, "kind": "property", "displayName": "Operation",
"group": "producer", "label": "", "required": true, "type": "object",
"javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [ "sign",
"verify" ], "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The operation to perform" },
+ "operation": { "index": 2, "kind": "property", "displayName": "Operation",
"group": "producer", "label": "", "required": true, "type": "object",
"javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [ "sign",
"verify", "generateSecretKeyEncapsulation", "extractSecretKeyEncapsulation" ],
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configura [...]
"autowiredEnabled": { "index": 3, "kind": "property", "displayName":
"Autowired Enabled", "group": "advanced", "label": "advanced", "required":
false, "type": "boolean", "javaType": "boolean", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": true, "description":
"Whether autowiring is enabled. This is used for automatic autowiring options
(the option must be marked as autowired) by looking up in the registry to find
if there is a single instance of matching t [...]
- "keyPair": { "index": 4, "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": 5, "kind": "property", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair o [...]
- "signer": { "index": 6, "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" },
- "healthCheckConsumerEnabled": { "index": 7, "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": 8, "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 producer [...]
+ "keyEncapsulationAlgorithm": { "index": 4, "kind": "property",
"displayName": "Key Encapsulation Algorithm", "group": "advanced", "label":
"advanced", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "In case there is no keyGenerator, we specify
an algorithm t [...]
+ "keyGenerator": { "index": 5, "kind": "property", "displayName": "Key
Generator", "group": "advanced", "label": "advanced", "required": false,
"type": "object", "javaType": "javax.crypto.KeyGenerator", "deprecated": false,
"deprecationNote": "", "autowired": true, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "The Key Generator to be
used in encapsulation and extraction" },
+ "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", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair o [...]
+ "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",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case we are using KEM
operations, we need a Symmetric algorithm [...]
+ "healthCheckConsumerEnabled": { "index": 10, "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": 11, "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" },
@@ -41,10 +44,13 @@
},
"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" },
- "operation": { "index": 1, "kind": "parameter", "displayName":
"Operation", "group": "producer", "label": "", "required": true, "type":
"object", "javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [
"sign", "verify" ], "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The operation to perform" },
+ "operation": { "index": 1, "kind": "parameter", "displayName":
"Operation", "group": "producer", "label": "", "required": true, "type":
"object", "javaType": "org.apache.camel.component.pqc.PQCOperations", "enum": [
"sign", "verify", "generateSecretKeyEncapsulation",
"extractSecretKeyEncapsulation" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configur [...]
"lazyStartProducer": { "index": 2, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "required": false, "type": "boolean", "javaType":
"boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "description": "Whether the producer should be started
lazy (on the first message). By starting lazy you can use this to allow
CamelContext and routes to startup in situations where a produc [...]
- "keyPair": { "index": 3, "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": 4, "kind": "parameter", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair [...]
- "signer": { "index": 5, "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" }
+ "keyEncapsulationAlgorithm": { "index": 3, "kind": "parameter",
"displayName": "Key Encapsulation Algorithm", "group": "advanced", "label":
"advanced", "required": false, "type": "string", "javaType":
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "In case there is no keyGenerator, we specify
an algorithm [...]
+ "keyGenerator": { "index": 4, "kind": "parameter", "displayName": "Key
Generator", "group": "advanced", "label": "advanced", "required": false,
"type": "object", "javaType": "javax.crypto.KeyGenerator", "deprecated": false,
"deprecationNote": "", "autowired": true, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "The Key Generator to be
used in encapsulation and extraction" },
+ "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", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case there is no
signer, we specify an algorithm to build the KeyPair [...]
+ "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",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "In case we are using KEM
operations, we need a Symmetric algorithm [...]
}
}
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 35fad553e73..b0f0fa92983 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
@@ -19,6 +19,8 @@ package org.apache.camel.component.pqc;
import java.security.KeyPair;
import java.security.Signature;
+import javax.crypto.KeyGenerator;
+
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriParam;
@@ -43,6 +45,15 @@ public class PQCConfiguration implements Cloneable {
@UriParam
@Metadata(label = "advanced")
private String signatureAlgorithm;
+ @UriParam
+ @Metadata(label = "advanced", autowired = true)
+ private KeyGenerator keyGenerator;
+ @UriParam
+ @Metadata(label = "advanced")
+ private String keyEncapsulationAlgorithm;
+ @UriParam
+ @Metadata(label = "advanced")
+ private String symmetricKeyAlgorithm;
public PQCOperations getOperation() {
return operation;
@@ -88,6 +99,39 @@ public class PQCConfiguration implements Cloneable {
this.signatureAlgorithm = signatureAlgorithm;
}
+ public KeyGenerator getKeyGenerator() {
+ return keyGenerator;
+ }
+
+ /**
+ * The Key Generator to be used in encapsulation and extraction
+ */
+ public void setKeyGenerator(KeyGenerator keyGenerator) {
+ this.keyGenerator = keyGenerator;
+ }
+
+ public String getKeyEncapsulationAlgorithm() {
+ return keyEncapsulationAlgorithm;
+ }
+
+ /**
+ * In case there is no keyGenerator, we specify an algorithm to build the
KeyGenerator
+ */
+ public void setKeyEncapsulationAlgorithm(String keyEncapsulationAlgorithm)
{
+ this.keyEncapsulationAlgorithm = keyEncapsulationAlgorithm;
+ }
+
+ public String getSymmetricKeyAlgorithm() {
+ return symmetricKeyAlgorithm;
+ }
+
+ /**
+ * In case we are using KEM operations, we need a Symmetric algorithm to
be defined for the flow to work.
+ */
+ public void setSymmetricKeyAlgorithm(String symmetricKeyAlgorithm) {
+ this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
+ }
+
// *************************************************
//
// *************************************************
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCKeyEncapsulationAlgorithms.java
similarity index 70%
copy from
components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
copy to
components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCKeyEncapsulationAlgorithms.java
index 37052290228..8d9b4c905fb 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCKeyEncapsulationAlgorithms.java
@@ -16,9 +16,22 @@
*/
package org.apache.camel.component.pqc;
-public enum PQCOperations {
+public enum PQCKeyEncapsulationAlgorithms {
- sign,
- verify
+ // Standardized and implemented
+ MLKEM("ML-KEM"),
+ BIKE("BIKE");
+
+ // Experimental and non-standardized
+
+ private final String algorithm;
+
+ PQCKeyEncapsulationAlgorithms(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
}
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
index 37052290228..45d6abdc5c1 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
@@ -17,8 +17,8 @@
package org.apache.camel.component.pqc;
public enum PQCOperations {
-
sign,
- verify
-
+ verify,
+ generateSecretKeyEncapsulation,
+ extractSecretKeyEncapsulation
}
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 a63280cda0c..28768490d67 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
@@ -18,11 +18,16 @@ package org.apache.camel.component.pqc;
import java.security.*;
+import javax.crypto.KeyGenerator;
+
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.InvalidPayloadException;
import org.apache.camel.support.DefaultProducer;
import org.apache.camel.util.ObjectHelper;
+import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
+import org.bouncycastle.jcajce.spec.KEMExtractSpec;
+import org.bouncycastle.jcajce.spec.KEMGenerateSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,6 +39,7 @@ public class PQCProducer extends DefaultProducer {
private static final Logger LOG =
LoggerFactory.getLogger(PQCProducer.class);
private Signature signer;
+ private KeyGenerator keyGenerator;
public PQCProducer(Endpoint endpoint) {
super(endpoint);
@@ -48,6 +54,12 @@ public class PQCProducer extends DefaultProducer {
case verify:
verification(exchange);
break;
+ case generateSecretKeyEncapsulation:
+ generateEncapsulation(exchange);
+ break;
+ case extractSecretKeyEncapsulation:
+ extractEncapsulation(exchange);
+ break;
default:
throw new IllegalArgumentException("Unsupported operation");
}
@@ -74,11 +86,25 @@ public class PQCProducer extends DefaultProducer {
protected void doStart() throws Exception {
super.doStart();
- signer = getEndpoint().getConfiguration().getSigner();
+ if (getConfiguration().getOperation().equals(PQCOperations.sign)
+ ||
getConfiguration().getOperation().equals(PQCOperations.verify)) {
+ signer = getEndpoint().getConfiguration().getSigner();
+
+ if (ObjectHelper.isEmpty(signer)) {
+ signer = Signature
+
.getInstance(PQCSignatureAlgorithms.valueOf(getConfiguration().getSignatureAlgorithm()).getAlgorithm());
+ }
+ }
+
+ if
(getConfiguration().getOperation().equals(PQCOperations.generateSecretKeyEncapsulation)
+ ||
getConfiguration().getOperation().equals(PQCOperations.extractSecretKeyEncapsulation))
{
+ keyGenerator = getEndpoint().getConfiguration().getKeyGenerator();
- if (ObjectHelper.isEmpty(signer)) {
- signer = Signature
-
.getInstance(PQCSignatureAlgorithms.valueOf(getConfiguration().getSignatureAlgorithm()).getAlgorithm());
+ if (ObjectHelper.isEmpty(keyGenerator)) {
+ keyGenerator = KeyGenerator
+
.getInstance(PQCKeyEncapsulationAlgorithms.valueOf(getConfiguration().getKeyEncapsulationAlgorithm())
+ .getAlgorithm());
+ }
}
}
@@ -106,4 +132,38 @@ public class PQCProducer extends DefaultProducer {
}
}
+ private void generateEncapsulation(Exchange exchange)
+ throws InvalidAlgorithmParameterException {
+ // initialise for creating an encapsulation and shared secret.
+ keyGenerator.init(new
KEMGenerateSpec(getEndpoint().getConfiguration().getKeyPair().getPublic(),
"AES", 128),
+ new SecureRandom());
+ // SecretKeyWithEncapsulation is the class to use as the secret key,
it has additional
+ // methods on it for recovering the encapsulation as well.
+ SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)
keyGenerator.generateKey();
+
+ exchange.getMessage().setBody(secEnc1,
SecretKeyWithEncapsulation.class);
+ }
+
+ private void extractEncapsulation(Exchange exchange)
+ throws InvalidAlgorithmParameterException,
+ InvalidPayloadException {
+ // initialise for creating an encapsulation and shared secret.
+ SecretKeyWithEncapsulation payload =
exchange.getMessage().getMandatoryBody(SecretKeyWithEncapsulation.class);
+
+ if
(ObjectHelper.isEmpty(getConfiguration().getSymmetricKeyAlgorithm())) {
+ throw new IllegalArgumentException("Symmetric Algorithm needs to
be specified");
+ }
+
+ keyGenerator.init(
+ new KEMExtractSpec(
+
getEndpoint().getConfiguration().getKeyPair().getPrivate(),
payload.getEncapsulation(),
+
PQCSymmetricAlgorithms.valueOf(getConfiguration().getSymmetricKeyAlgorithm()).getAlgorithm(),
128),
+ new SecureRandom());
+
+ // initialise for extracting the shared secret from the encapsulation.
+ SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)
keyGenerator.generateKey();
+
+ exchange.getMessage().setBody(secEnc2,
SecretKeyWithEncapsulation.class);
+ }
+
}
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCSymmetricAlgorithms.java
similarity index 74%
copy from
components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
copy to
components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCSymmetricAlgorithms.java
index 37052290228..543512332bc 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCOperations.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCSymmetricAlgorithms.java
@@ -16,9 +16,19 @@
*/
package org.apache.camel.component.pqc;
-public enum PQCOperations {
+public enum PQCSymmetricAlgorithms {
- sign,
- verify
+ // Standardized and implemented
+ AES("AES");
+
+ private final String algorithm;
+
+ PQCSymmetricAlgorithms(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
}
diff --git
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCBIKEGenerateEncapsulationAESTest.java
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCBIKEGenerateEncapsulationAESTest.java
new file mode 100644
index 00000000000..d5743e76a0a
--- /dev/null
+++
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCBIKEGenerateEncapsulationAESTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.test.junit5.CamelTestSupport;
+import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
+import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec;
+import org.bouncycastle.util.Arrays;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class PQCBIKEGenerateEncapsulationAESTest extends CamelTestSupport {
+
+ @EndpointInject("mock:sign")
+ protected MockEndpoint resultSign;
+
+ @Produce("direct:sign")
+ protected ProducerTemplate templateSign;
+
+ @EndpointInject("mock:verify")
+ protected MockEndpoint resultVerify;
+
+ public PQCBIKEGenerateEncapsulationAESTest() throws
NoSuchAlgorithmException {
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+
from("direct:sign").to("pqc:keyenc?operation=generateSecretKeyEncapsulation&symmetricKeyAlgorithm=AES")
+ .to("mock:sign")
+
.to("pqc:keyenc?operation=extractSecretKeyEncapsulation&symmetricKeyAlgorithm=AES").to("mock:verify");
+ }
+ };
+ }
+
+ @BeforeAll
+ public static void startup() throws Exception {
+ Security.addProvider(new BouncyCastleProvider());
+ Security.addProvider(new BouncyCastlePQCProvider());
+ }
+
+ @Test
+ void testSignAndVerify() throws Exception {
+ resultSign.expectedMessageCount(1);
+ resultVerify.expectedMessageCount(1);
+ templateSign.sendBody("Hello");
+ resultSign.assertIsSatisfied();
+
assertNotNull(resultSign.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class));
+ assertEquals(PQCSymmetricAlgorithms.AES.getAlgorithm(),
+
resultSign.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class).getAlgorithm());
+ SecretKeyWithEncapsulation secEncrypted
+ =
resultSign.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class);
+
assertNotNull(resultVerify.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class));
+ assertEquals(PQCSymmetricAlgorithms.AES.getAlgorithm(),
+
resultVerify.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class).getAlgorithm());
+ SecretKeyWithEncapsulation secEncryptedExtracted
+ =
resultVerify.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class);
+ assertTrue(Arrays.areEqual(secEncrypted.getEncoded(),
secEncryptedExtracted.getEncoded()));
+ }
+
+ @BindToRegistry("Keypair")
+ public KeyPair setKeyPair() throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidAlgorithmParameterException {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("BIKE", "BCPQC");
+ kpg.initialize(BIKEParameterSpec.bike192, new SecureRandom());
+ KeyPair kp = kpg.generateKeyPair();
+ return kp;
+ }
+
+ @BindToRegistry("KeyGenerator")
+ public KeyGenerator setKeyGenerator()
+ throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidAlgorithmParameterException {
+ KeyGenerator kg = KeyGenerator.getInstance("BIKE", "BCPQC");
+ return kg;
+ }
+}
diff --git
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCMLKEMGenerateEncapsulationAESTest.java
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCMLKEMGenerateEncapsulationAESTest.java
new file mode 100644
index 00000000000..7d866d13ea8
--- /dev/null
+++
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCMLKEMGenerateEncapsulationAESTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.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.bouncycastle.util.Arrays;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class PQCMLKEMGenerateEncapsulationAESTest extends CamelTestSupport {
+
+ @EndpointInject("mock:encapsulate")
+ protected MockEndpoint resultEncapsulate;
+
+ @Produce("direct:encapsulate")
+ protected ProducerTemplate templateEncapsulate;
+
+ @EndpointInject("mock:extract")
+ protected MockEndpoint resultExtract;
+
+ public PQCMLKEMGenerateEncapsulationAESTest() throws
NoSuchAlgorithmException {
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ 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("mock:extract");
+ }
+ };
+ }
+
+ @BeforeAll
+ public static void startup() throws Exception {
+ Security.addProvider(new BouncyCastleProvider());
+ Security.addProvider(new BouncyCastlePQCProvider());
+ }
+
+ @Test
+ void testSignAndVerify() throws Exception {
+ resultEncapsulate.expectedMessageCount(1);
+ resultExtract.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());
+ SecretKeyWithEncapsulation secEncrypted
+ =
resultEncapsulate.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class);
+
assertNotNull(resultExtract.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class));
+ assertEquals(PQCSymmetricAlgorithms.AES.getAlgorithm(),
+
resultExtract.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class).getAlgorithm());
+ SecretKeyWithEncapsulation secEncryptedExtracted
+ =
resultExtract.getExchanges().get(0).getMessage().getBody(SecretKeyWithEncapsulation.class);
+ assertTrue(Arrays.areEqual(secEncrypted.getEncoded(),
secEncryptedExtracted.getEncoded()));
+ }
+
+ @BindToRegistry("Keypair")
+ public KeyPair setKeyPair() throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidAlgorithmParameterException {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BC");
+ 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("ML-KEM", "BC");
+ 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 5cbe68cfa86..e0c6a1d5bbf 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
@@ -130,6 +130,38 @@ public interface PqcComponentBuilderFactory {
return this;
}
+ /**
+ * In case there is no keyGenerator, we specify an algorithm to build
+ * the KeyGenerator.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: advanced
+ *
+ * @param keyEncapsulationAlgorithm the value to set
+ * @return the dsl builder
+ */
+ default PqcComponentBuilder keyEncapsulationAlgorithm(java.lang.String
keyEncapsulationAlgorithm) {
+ doSetProperty("keyEncapsulationAlgorithm",
keyEncapsulationAlgorithm);
+ return this;
+ }
+
+ /**
+ * The Key Generator to be used in encapsulation and extraction.
+ *
+ * The option is a: <code>javax.crypto.KeyGenerator</code>
+ * type.
+ *
+ * Group: advanced
+ *
+ * @param keyGenerator the value to set
+ * @return the dsl builder
+ */
+ default PqcComponentBuilder keyGenerator(javax.crypto.KeyGenerator
keyGenerator) {
+ doSetProperty("keyGenerator", keyGenerator);
+ return this;
+ }
+
/**
* The KeyPair to be used.
*
@@ -177,6 +209,22 @@ public interface PqcComponentBuilderFactory {
return this;
}
+ /**
+ * In case we are using KEM operations, we need a Symmetric algorithm
to
+ * be defined for the flow to work.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: advanced
+ *
+ * @param symmetricKeyAlgorithm the value to set
+ * @return the dsl builder
+ */
+ default PqcComponentBuilder symmetricKeyAlgorithm(java.lang.String
symmetricKeyAlgorithm) {
+ doSetProperty("symmetricKeyAlgorithm", symmetricKeyAlgorithm);
+ return this;
+ }
+
/**
* Used for enabling or disabling all consumer based health checks from
@@ -239,9 +287,12 @@ public interface PqcComponentBuilderFactory {
case "lazyStartProducer": ((PQCComponent)
component).setLazyStartProducer((boolean) value); return true;
case "operation": getOrCreateConfiguration((PQCComponent)
component).setOperation((org.apache.camel.component.pqc.PQCOperations) value);
return true;
case "autowiredEnabled": ((PQCComponent)
component).setAutowiredEnabled((boolean) value); return true;
+ case "keyEncapsulationAlgorithm":
getOrCreateConfiguration((PQCComponent)
component).setKeyEncapsulationAlgorithm((java.lang.String) value); return true;
+ case "keyGenerator": getOrCreateConfiguration((PQCComponent)
component).setKeyGenerator((javax.crypto.KeyGenerator) value); return true;
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 "symmetricKeyAlgorithm":
getOrCreateConfiguration((PQCComponent)
component).setSymmetricKeyAlgorithm((java.lang.String) value); return true;
case "healthCheckConsumerEnabled": ((PQCComponent)
component).setHealthCheckConsumerEnabled((boolean) value); return true;
case "healthCheckProducerEnabled": ((PQCComponent)
component).setHealthCheckProducerEnabled((boolean) value); return true;
default: return false;
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 b572c379ae7..52375322438 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
@@ -134,6 +134,50 @@ public interface PQCEndpointBuilderFactory {
doSetProperty("lazyStartProducer", lazyStartProducer);
return this;
}
+ /**
+ * In case there is no keyGenerator, we specify an algorithm to build
+ * the KeyGenerator.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: advanced
+ *
+ * @param keyEncapsulationAlgorithm the value to set
+ * @return the dsl builder
+ */
+ default AdvancedPQCEndpointBuilder keyEncapsulationAlgorithm(String
keyEncapsulationAlgorithm) {
+ doSetProperty("keyEncapsulationAlgorithm",
keyEncapsulationAlgorithm);
+ return this;
+ }
+ /**
+ * The Key Generator to be used in encapsulation and extraction.
+ *
+ * The option is a: <code>javax.crypto.KeyGenerator</code> type.
+ *
+ * Group: advanced
+ *
+ * @param keyGenerator the value to set
+ * @return the dsl builder
+ */
+ default AdvancedPQCEndpointBuilder
keyGenerator(javax.crypto.KeyGenerator keyGenerator) {
+ doSetProperty("keyGenerator", keyGenerator);
+ return this;
+ }
+ /**
+ * The Key Generator to be used in encapsulation and extraction.
+ *
+ * The option will be converted to a
+ * <code>javax.crypto.KeyGenerator</code> type.
+ *
+ * Group: advanced
+ *
+ * @param keyGenerator the value to set
+ * @return the dsl builder
+ */
+ default AdvancedPQCEndpointBuilder keyGenerator(String keyGenerator) {
+ doSetProperty("keyGenerator", keyGenerator);
+ return this;
+ }
/**
* The KeyPair to be used.
*
@@ -207,6 +251,21 @@ public interface PQCEndpointBuilderFactory {
doSetProperty("signer", signer);
return this;
}
+ /**
+ * In case we are using KEM operations, we need a Symmetric algorithm
to
+ * be defined for the flow to work.
+ *
+ * The option is a: <code>java.lang.String</code> type.
+ *
+ * Group: advanced
+ *
+ * @param symmetricKeyAlgorithm the value to set
+ * @return the dsl builder
+ */
+ default AdvancedPQCEndpointBuilder symmetricKeyAlgorithm(String
symmetricKeyAlgorithm) {
+ doSetProperty("symmetricKeyAlgorithm", symmetricKeyAlgorithm);
+ return this;
+ }
}
public interface PQCBuilders {