This is an automated email from the ASF dual-hosted git repository.
davsclaus 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 dc7d79531a7d ci: Upgrade Bouncy Castle to 1.86 and adapt camel-pqc
(#27052)
dc7d79531a7d is described below
commit dc7d79531a7d6a6769b73922106a0167af788b5b
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Sep 29 14:01:36 2026 +0200
ci: Upgrade Bouncy Castle to 1.86 and adapt camel-pqc (#27052)
* ci: Upgrade Bouncy Castle to 1.86 and adapt camel-pqc
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
---
.../org/apache/camel/catalog/components/pqc.json | 4 +-
.../apache/camel/catalog/docs/pqc-component.adoc | 38 ++++-----
.../camel/catalog/docs/pqc-key-lifecycle.adoc | 22 ++---
.../org/apache/camel/component/pqc/pqc.json | 4 +-
.../camel-pqc/src/main/docs/pqc-component.adoc | 38 ++++-----
.../camel-pqc/src/main/docs/pqc-key-lifecycle.adoc | 22 ++---
.../apache/camel/component/pqc/PQCComponent.java | 4 -
.../camel/component/pqc/PQCConfiguration.java | 2 +-
.../pqc/PQCKeyEncapsulationAlgorithms.java | 4 +-
.../component/pqc/PQCParameterSpecResolver.java | 26 +++---
.../apache/camel/component/pqc/PQCProducer.java | 1 -
.../component/pqc/PQCSignatureAlgorithms.java | 1 -
.../pqc/crypto/PQCDefaultPicnicMaterial.java | 55 ------------
.../pqc/crypto/kem/PQCDefaultCMCEMaterial.java | 2 +-
.../pqc/crypto/kem/PQCDefaultFRODOMaterial.java | 4 +-
.../AwsSecretsManagerKeyLifecycleManager.java | 6 +-
.../HashicorpVaultKeyLifecycleManager.java | 6 +-
.../pqc/lifecycle/KeyAlgorithmSupport.java | 6 +-
.../pqc/PQCCMCEGenerateEncapsulationAESTest.java | 2 +-
.../pqc/PQCFRODOGenerateEncapsulationAESTest.java | 4 +-
.../pqc/PQCParameterSpecResolverTest.java | 48 +++++++++++
.../pqc/PQCSignaturePicnicNoAutowiredTest.java | 75 -----------------
.../component/pqc/PQCSignaturePicnicTest.java | 98 ----------------------
.../ROOT/pages/camel-4x-upgrade-guide-4_23.adoc | 34 ++++++++
parent/pom.xml | 2 +-
25 files changed, 173 insertions(+), 335 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 70368cbc6a4d..f1dcde7404e8 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
@@ -46,7 +46,7 @@
"keyStore": { "index": 19, "kind": "property", "displayName": "Key Store",
"group": "advanced", "label": "advanced", "required": false, "type": "object",
"javaType": "java.security.KeyStore", "deprecated": false, "deprecationNote":
"", "autowired": true, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "A KeyStore where we could get Cryptographic
material" },
"keyStorePassword": { "index": 20, "kind": "property", "displayName": "Key
Store Password", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": true, "security":
"secret", "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The KeyStore password to use in combination
with KeySto [...]
"parameterSpec": { "index": 21, "kind": "property", "displayName":
"Parameter Spec", "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": "The NIST parameter set
(security level) to use for the configured signature or key [...]
- "signatureAlgorithm": { "index": 22, "kind": "property", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "PICNIC",
"SNOVA", "MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "c [...]
+ "signatureAlgorithm": { "index": 22, "kind": "property", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "SNOVA",
"MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurati [...]
"signer": { "index": 23, "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" },
"statefulKeyWarningThreshold": { "index": 24, "kind": "property",
"displayName": "Stateful Key Warning Threshold", "group": "advanced", "label":
"advanced", "required": false, "type": "number", "javaType": "double",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "defaultValue": 0.1, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The warning threshold for stateful key exh
[...]
"storeExtractedSecretKeyAsHeader": { "index": 25, "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 extractSec [...]
@@ -99,7 +99,7 @@
"keyStore": { "index": 14, "kind": "parameter", "displayName": "Key
Store", "group": "advanced", "label": "advanced", "required": false, "type":
"object", "javaType": "java.security.KeyStore", "deprecated": false,
"deprecationNote": "", "autowired": true, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "A KeyStore where we
could get Cryptographic material" },
"keyStorePassword": { "index": 15, "kind": "parameter", "displayName":
"Key Store Password", "group": "advanced", "label": "advanced", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": true, "security":
"secret", "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The KeyStore password to use in combination
with KeySt [...]
"parameterSpec": { "index": 16, "kind": "parameter", "displayName":
"Parameter Spec", "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": "The NIST parameter set
(security level) to use for the configured signature or key [...]
- "signatureAlgorithm": { "index": 17, "kind": "parameter", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "PICNIC",
"SNOVA", "MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", " [...]
+ "signatureAlgorithm": { "index": 17, "kind": "parameter", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "SNOVA",
"MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurat [...]
"signer": { "index": 18, "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" },
"statefulKeyWarningThreshold": { "index": 19, "kind": "parameter",
"displayName": "Stateful Key Warning Threshold", "group": "advanced", "label":
"advanced", "required": false, "type": "number", "javaType": "double",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "defaultValue": 0.1, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The warning threshold for stateful key ex [...]
"storeExtractedSecretKeyAsHeader": { "index": 20, "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 extractSe [...]
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-component.adoc
index d731cea6dede..1a39419e84c7 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-component.adoc
@@ -58,11 +58,13 @@ Experimental and non-standardized
- Dilithium
- Falcon
-- Picnic
- SNOVA
- MAYO
- SPHINCS+
+NOTE: `DILITHIUM` and `SPHINCSPLUS` are kept for backward compatibility: they
generate ML-DSA and SLH-DSA keys, the
+standardized versions of these algorithms.
+
== Parameter Sets (NIST Security Levels)
By default each algorithm uses a fixed parameter set - for example ML-DSA-65
for `MLDSA` and ML-KEM-512 for `MLKEM`.
@@ -91,17 +93,16 @@ BouncyCastle constants (`ml_dsa_87`) is accepted as an
alias of the canonical na
| `MLKEM` | `ML-KEM-512` (default), `ML-KEM-768`, `ML-KEM-1024`
| `SLHDSA` | `SLH-DSA-SHA2-128S`, `SLH-DSA-SHAKE-256F`, ... (see
`SLHDSAParameterSpec`)
| `FALCON` | `FALCON-512`, `FALCON-1024`
-| `DILITHIUM` | `DILITHIUM2`, `DILITHIUM3`, `DILITHIUM5`
-| `SPHINCSPLUS` | `sha2-128s`, ... (see `SPHINCSPlusParameterSpec`)
-| `PICNIC` | `picnicl1fs`, ... (see `PicnicParameterSpec`)
-| `KYBER` | `kyber512`, `kyber768`, `kyber1024`
+| `DILITHIUM` | `ML-DSA-44`, `ML-DSA-65`, `ML-DSA-87` (default)
+| `SPHINCSPLUS` | The `SLHDSA` parameter sets, for example `SLH-DSA-SHA2-128S`
(default)
+| `KYBER` | `ML-KEM-512`, `ML-KEM-768`, `ML-KEM-1024` (default); `kyber512`,
`kyber768` and `kyber1024` are accepted as aliases
| `NTRU` | `ntruhps2048509`, ... (see `NTRUParameterSpec`)
| `NTRULPRime` | `ntrulpr653`, ... (see `NTRULPRimeParameterSpec`)
| `SNTRUPrime` | `sntrup761`, ... (see `SNTRUPrimeParameterSpec`)
| `BIKE` | `bike128`, `bike192`, `bike256`
| `HQC` | `hqc128`, `hqc192`, `hqc256`
-| `CMCE` | `mceliece348864`, ... (see `CMCEParameterSpec`)
-| `FRODO` | `frodokem640aes`, ... (see `FrodoParameterSpec`)
+| `CMCE` | `mceliece460896`, `mceliece8192128f` (default), ... (see
`org.bouncycastle.jcajce.spec.CMCEParameterSpec`)
+| `FRODO` | `frodokem976aes` (default), `frodokem1344shake`, ... (see
`org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec`)
| `SABER` | `lightsaberkem128r3`, ... (see `SABERParameterSpec`)
|===
@@ -366,10 +367,10 @@ All other signature algorithms follow the exact same
route pattern shown above f
|Dilithium
|`DILITHIUM`
-|Dilithium
-|BCPQC
-|dilithium2
-|`PQCDefaultDilithiumMaterial`
+|ML-DSA
+|BC
+|ML-DSA-87
+|`PQCDefaultDILITHIUMMaterial`
|Falcon
|`FALCON`
@@ -380,17 +381,10 @@ All other signature algorithms follow the exact same
route pattern shown above f
|SPHINCS+
|`SPHINCSPLUS`
-|SPHINCS+
-|BCPQC
-|sha2_128s
-|`PQCDefaultSPHINCSPlusMaterial`
-
-|Picnic
-|`PICNIC`
-|Picnic
-|BCPQC
-|picnicl1fs
-|`PQCDefaultPicknicMaterial`
+|SLH-DSA
+|BC
+|SLH-DSA-SHA2-128s
+|`PQCDefaultSPHINCSPLUSMaterial`
|===
To use any algorithm, set `signatureAlgorithm` in the URI (e.g.,
`signatureAlgorithm=SLHDSA`). Alternatively, register a KeyPair and Signature
in the registry using the JCA Algorithm Name and Provider from the table above.
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-key-lifecycle.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-key-lifecycle.adoc
index c8c0799d895f..b96d97c613c4 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-key-lifecycle.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pqc-key-lifecycle.adoc
@@ -52,7 +52,7 @@ KeyLifecycleManager keyManager = new
FileBasedKeyLifecycleManager("/secure/keys"
// Generate a new Dilithium key
KeyPair keyPair = keyManager.generateKeyPair("DILITHIUM", "app-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
// Use the key
KeyMetadata metadata = keyManager.getKeyMetadata("app-signing-key");
@@ -166,7 +166,7 @@ public HashicorpVaultKeyLifecycleManager createKeyManager()
{
// Generate a Dilithium key stored in Vault
KeyPair keyPair = keyManager.generateKeyPair("DILITHIUM", "app-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
// Key is stored in Vault at: secret/data/pqc/keys/app-signing-key
----
@@ -471,7 +471,7 @@ public AwsSecretsManagerKeyLifecycleManager
createKeyManager() {
// Generate a Dilithium key stored in AWS Secrets Manager
KeyPair keyPair = keyManager.generateKeyPair("DILITHIUM", "app-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
// Keys are stored as: pqc/keys/app-signing-key/private, /public, /metadata
----
@@ -836,7 +836,7 @@ KeyPair mldsaKey = keyManager.generateKeyPair("MLDSA",
"mldsa-key");
// Dilithium with specific parameter
KeyPair dilithiumKey = keyManager.generateKeyPair("DILITHIUM", "dilithium-key",
- DilithiumParameterSpec.dilithium3);
+ MLDSAParameterSpec.ml_dsa_65);
// Falcon (uses default Falcon-512)
KeyPair falconKey = keyManager.generateKeyPair("FALCON", "falcon-key");
@@ -1116,7 +1116,7 @@ public KeyLifecycleManager createKeyManager() throws
IOException {
public KeyPair createSigningKey() throws Exception {
KeyLifecycleManager manager = createKeyManager();
return manager.generateKeyPair("DILITHIUM", "route-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
}
----
@@ -1136,7 +1136,7 @@ camel:
scriptLanguage: groovy
script: |
def manager = new
org.apache.camel.component.pqc.lifecycle.FileBasedKeyLifecycleManager('/secure/keys')
- def spec =
org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec.dilithium2
+ def spec = org.bouncycastle.jcajce.spec.MLDSAParameterSpec.ml_dsa_44
manager.generateKeyPair('DILITHIUM', 'route-signing-key', spec)
----
====
@@ -1202,9 +1202,9 @@ The lifecycle manager provides sensible defaults for all
algorithms:
|===
|Algorithm |Default Parameter Spec
-|DILITHIUM |dilithium2
+|DILITHIUM |ML-DSA-44
|FALCON |falcon_512
-|SPHINCSPLUS |sha2_128s
+|SPHINCSPLUS |SLH-DSA-SHA2-128S
|XMSS |10-tree height with SHA-256
|XMSSMT |XMSSMT-SHA2-20d2-256
|LMS/HSS |LMS-SHA256-N32-H10 with SHA256-N32-W4
@@ -1212,10 +1212,10 @@ The lifecycle manager provides sensible defaults for
all algorithms:
|NTRULPRime |ntrulpr653
|SNTRUPrime |sntrup761
|SABER |lightsaberkem128r3
-|FRODO |frodokem640aes
+|FRODO |frodokem976aes
|BIKE |bike128
|HQC |hqc128
-|CMCE |mceliece348864
+|CMCE |mceliece460896
|===
== Best Practices
@@ -1312,7 +1312,7 @@ for (int i = 0; i < 100; i++) {
executor.submit(() -> {
try {
keyManager.generateKeyPair("DILITHIUM", "key-" + index,
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
} catch (Exception e) {
logger.error("Key generation failed", e);
}
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 70368cbc6a4d..f1dcde7404e8 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
@@ -46,7 +46,7 @@
"keyStore": { "index": 19, "kind": "property", "displayName": "Key Store",
"group": "advanced", "label": "advanced", "required": false, "type": "object",
"javaType": "java.security.KeyStore", "deprecated": false, "deprecationNote":
"", "autowired": true, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "A KeyStore where we could get Cryptographic
material" },
"keyStorePassword": { "index": 20, "kind": "property", "displayName": "Key
Store Password", "group": "advanced", "label": "advanced", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": true, "security":
"secret", "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The KeyStore password to use in combination
with KeySto [...]
"parameterSpec": { "index": 21, "kind": "property", "displayName":
"Parameter Spec", "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": "The NIST parameter set
(security level) to use for the configured signature or key [...]
- "signatureAlgorithm": { "index": 22, "kind": "property", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "PICNIC",
"SNOVA", "MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "c [...]
+ "signatureAlgorithm": { "index": 22, "kind": "property", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "SNOVA",
"MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurati [...]
"signer": { "index": 23, "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" },
"statefulKeyWarningThreshold": { "index": 24, "kind": "property",
"displayName": "Stateful Key Warning Threshold", "group": "advanced", "label":
"advanced", "required": false, "type": "number", "javaType": "double",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "defaultValue": 0.1, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The warning threshold for stateful key exh
[...]
"storeExtractedSecretKeyAsHeader": { "index": 25, "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 extractSec [...]
@@ -99,7 +99,7 @@
"keyStore": { "index": 14, "kind": "parameter", "displayName": "Key
Store", "group": "advanced", "label": "advanced", "required": false, "type":
"object", "javaType": "java.security.KeyStore", "deprecated": false,
"deprecationNote": "", "autowired": true, "secret": false,
"configurationClass": "org.apache.camel.component.pqc.PQCConfiguration",
"configurationField": "configuration", "description": "A KeyStore where we
could get Cryptographic material" },
"keyStorePassword": { "index": 15, "kind": "parameter", "displayName":
"Key Store Password", "group": "advanced", "label": "advanced", "required":
false, "type": "string", "javaType": "java.lang.String", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": true, "security":
"secret", "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The KeyStore password to use in combination
with KeySt [...]
"parameterSpec": { "index": 16, "kind": "parameter", "displayName":
"Parameter Spec", "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": "The NIST parameter set
(security level) to use for the configured signature or key [...]
- "signatureAlgorithm": { "index": 17, "kind": "parameter", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "PICNIC",
"SNOVA", "MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", " [...]
+ "signatureAlgorithm": { "index": 17, "kind": "parameter", "displayName":
"Signature Algorithm", "group": "advanced", "label": "advanced", "required":
false, "type": "enum", "javaType": "java.lang.String", "enum": [ "MLDSA",
"SLHDSA", "LMS", "HSS", "XMSS", "XMSSMT", "DILITHIUM", "FALCON", "SNOVA",
"MAYO", "SPHINCSPLUS" ], "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurat [...]
"signer": { "index": 18, "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" },
"statefulKeyWarningThreshold": { "index": 19, "kind": "parameter",
"displayName": "Stateful Key Warning Threshold", "group": "advanced", "label":
"advanced", "required": false, "type": "number", "javaType": "double",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "defaultValue": 0.1, "configurationClass":
"org.apache.camel.component.pqc.PQCConfiguration", "configurationField":
"configuration", "description": "The warning threshold for stateful key ex [...]
"storeExtractedSecretKeyAsHeader": { "index": 20, "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 extractSe [...]
diff --git a/components/camel-pqc/src/main/docs/pqc-component.adoc
b/components/camel-pqc/src/main/docs/pqc-component.adoc
index d731cea6dede..1a39419e84c7 100644
--- a/components/camel-pqc/src/main/docs/pqc-component.adoc
+++ b/components/camel-pqc/src/main/docs/pqc-component.adoc
@@ -58,11 +58,13 @@ Experimental and non-standardized
- Dilithium
- Falcon
-- Picnic
- SNOVA
- MAYO
- SPHINCS+
+NOTE: `DILITHIUM` and `SPHINCSPLUS` are kept for backward compatibility: they
generate ML-DSA and SLH-DSA keys, the
+standardized versions of these algorithms.
+
== Parameter Sets (NIST Security Levels)
By default each algorithm uses a fixed parameter set - for example ML-DSA-65
for `MLDSA` and ML-KEM-512 for `MLKEM`.
@@ -91,17 +93,16 @@ BouncyCastle constants (`ml_dsa_87`) is accepted as an
alias of the canonical na
| `MLKEM` | `ML-KEM-512` (default), `ML-KEM-768`, `ML-KEM-1024`
| `SLHDSA` | `SLH-DSA-SHA2-128S`, `SLH-DSA-SHAKE-256F`, ... (see
`SLHDSAParameterSpec`)
| `FALCON` | `FALCON-512`, `FALCON-1024`
-| `DILITHIUM` | `DILITHIUM2`, `DILITHIUM3`, `DILITHIUM5`
-| `SPHINCSPLUS` | `sha2-128s`, ... (see `SPHINCSPlusParameterSpec`)
-| `PICNIC` | `picnicl1fs`, ... (see `PicnicParameterSpec`)
-| `KYBER` | `kyber512`, `kyber768`, `kyber1024`
+| `DILITHIUM` | `ML-DSA-44`, `ML-DSA-65`, `ML-DSA-87` (default)
+| `SPHINCSPLUS` | The `SLHDSA` parameter sets, for example `SLH-DSA-SHA2-128S`
(default)
+| `KYBER` | `ML-KEM-512`, `ML-KEM-768`, `ML-KEM-1024` (default); `kyber512`,
`kyber768` and `kyber1024` are accepted as aliases
| `NTRU` | `ntruhps2048509`, ... (see `NTRUParameterSpec`)
| `NTRULPRime` | `ntrulpr653`, ... (see `NTRULPRimeParameterSpec`)
| `SNTRUPrime` | `sntrup761`, ... (see `SNTRUPrimeParameterSpec`)
| `BIKE` | `bike128`, `bike192`, `bike256`
| `HQC` | `hqc128`, `hqc192`, `hqc256`
-| `CMCE` | `mceliece348864`, ... (see `CMCEParameterSpec`)
-| `FRODO` | `frodokem640aes`, ... (see `FrodoParameterSpec`)
+| `CMCE` | `mceliece460896`, `mceliece8192128f` (default), ... (see
`org.bouncycastle.jcajce.spec.CMCEParameterSpec`)
+| `FRODO` | `frodokem976aes` (default), `frodokem1344shake`, ... (see
`org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec`)
| `SABER` | `lightsaberkem128r3`, ... (see `SABERParameterSpec`)
|===
@@ -366,10 +367,10 @@ All other signature algorithms follow the exact same
route pattern shown above f
|Dilithium
|`DILITHIUM`
-|Dilithium
-|BCPQC
-|dilithium2
-|`PQCDefaultDilithiumMaterial`
+|ML-DSA
+|BC
+|ML-DSA-87
+|`PQCDefaultDILITHIUMMaterial`
|Falcon
|`FALCON`
@@ -380,17 +381,10 @@ All other signature algorithms follow the exact same
route pattern shown above f
|SPHINCS+
|`SPHINCSPLUS`
-|SPHINCS+
-|BCPQC
-|sha2_128s
-|`PQCDefaultSPHINCSPlusMaterial`
-
-|Picnic
-|`PICNIC`
-|Picnic
-|BCPQC
-|picnicl1fs
-|`PQCDefaultPicknicMaterial`
+|SLH-DSA
+|BC
+|SLH-DSA-SHA2-128s
+|`PQCDefaultSPHINCSPLUSMaterial`
|===
To use any algorithm, set `signatureAlgorithm` in the URI (e.g.,
`signatureAlgorithm=SLHDSA`). Alternatively, register a KeyPair and Signature
in the registry using the JCA Algorithm Name and Provider from the table above.
diff --git a/components/camel-pqc/src/main/docs/pqc-key-lifecycle.adoc
b/components/camel-pqc/src/main/docs/pqc-key-lifecycle.adoc
index c8c0799d895f..b96d97c613c4 100644
--- a/components/camel-pqc/src/main/docs/pqc-key-lifecycle.adoc
+++ b/components/camel-pqc/src/main/docs/pqc-key-lifecycle.adoc
@@ -52,7 +52,7 @@ KeyLifecycleManager keyManager = new
FileBasedKeyLifecycleManager("/secure/keys"
// Generate a new Dilithium key
KeyPair keyPair = keyManager.generateKeyPair("DILITHIUM", "app-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
// Use the key
KeyMetadata metadata = keyManager.getKeyMetadata("app-signing-key");
@@ -166,7 +166,7 @@ public HashicorpVaultKeyLifecycleManager createKeyManager()
{
// Generate a Dilithium key stored in Vault
KeyPair keyPair = keyManager.generateKeyPair("DILITHIUM", "app-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
// Key is stored in Vault at: secret/data/pqc/keys/app-signing-key
----
@@ -471,7 +471,7 @@ public AwsSecretsManagerKeyLifecycleManager
createKeyManager() {
// Generate a Dilithium key stored in AWS Secrets Manager
KeyPair keyPair = keyManager.generateKeyPair("DILITHIUM", "app-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
// Keys are stored as: pqc/keys/app-signing-key/private, /public, /metadata
----
@@ -836,7 +836,7 @@ KeyPair mldsaKey = keyManager.generateKeyPair("MLDSA",
"mldsa-key");
// Dilithium with specific parameter
KeyPair dilithiumKey = keyManager.generateKeyPair("DILITHIUM", "dilithium-key",
- DilithiumParameterSpec.dilithium3);
+ MLDSAParameterSpec.ml_dsa_65);
// Falcon (uses default Falcon-512)
KeyPair falconKey = keyManager.generateKeyPair("FALCON", "falcon-key");
@@ -1116,7 +1116,7 @@ public KeyLifecycleManager createKeyManager() throws
IOException {
public KeyPair createSigningKey() throws Exception {
KeyLifecycleManager manager = createKeyManager();
return manager.generateKeyPair("DILITHIUM", "route-signing-key",
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
}
----
@@ -1136,7 +1136,7 @@ camel:
scriptLanguage: groovy
script: |
def manager = new
org.apache.camel.component.pqc.lifecycle.FileBasedKeyLifecycleManager('/secure/keys')
- def spec =
org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec.dilithium2
+ def spec = org.bouncycastle.jcajce.spec.MLDSAParameterSpec.ml_dsa_44
manager.generateKeyPair('DILITHIUM', 'route-signing-key', spec)
----
====
@@ -1202,9 +1202,9 @@ The lifecycle manager provides sensible defaults for all
algorithms:
|===
|Algorithm |Default Parameter Spec
-|DILITHIUM |dilithium2
+|DILITHIUM |ML-DSA-44
|FALCON |falcon_512
-|SPHINCSPLUS |sha2_128s
+|SPHINCSPLUS |SLH-DSA-SHA2-128S
|XMSS |10-tree height with SHA-256
|XMSSMT |XMSSMT-SHA2-20d2-256
|LMS/HSS |LMS-SHA256-N32-H10 with SHA256-N32-W4
@@ -1212,10 +1212,10 @@ The lifecycle manager provides sensible defaults for
all algorithms:
|NTRULPRime |ntrulpr653
|SNTRUPrime |sntrup761
|SABER |lightsaberkem128r3
-|FRODO |frodokem640aes
+|FRODO |frodokem976aes
|BIKE |bike128
|HQC |hqc128
-|CMCE |mceliece348864
+|CMCE |mceliece460896
|===
== Best Practices
@@ -1312,7 +1312,7 @@ for (int i = 0; i < 100; i++) {
executor.submit(() -> {
try {
keyManager.generateKeyPair("DILITHIUM", "key-" + index,
- DilithiumParameterSpec.dilithium2);
+ MLDSAParameterSpec.ml_dsa_44);
} catch (Exception e) {
logger.error("Key generation failed", e);
}
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCComponent.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCComponent.java
index 65643de19781..7b37f94f7c1f 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCComponent.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCComponent.java
@@ -118,10 +118,6 @@ public class PQCComponent extends HealthCheckComponent {
configuration.setSigner(PQCDefaultFalconMaterial.signer);
configuration.setKeyPair(PQCDefaultFalconMaterial.keyPair);
break;
- case "PICNIC":
-
configuration.setSigner(PQCDefaultPicnicMaterial.signer);
-
configuration.setKeyPair(PQCDefaultPicnicMaterial.keyPair);
- break;
case "SNOVA":
configuration.setSigner(PQCDefaultSNOVAMaterial.signer);
configuration.setKeyPair(PQCDefaultSNOVAMaterial.keyPair);
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 c84d1a490598..a3e689e3a68f 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
@@ -45,7 +45,7 @@ public class PQCConfiguration implements Cloneable {
@UriParam
@Metadata(label = "advanced", autowired = true)
private Signature signer;
- @UriParam(enums =
"MLDSA,SLHDSA,LMS,HSS,XMSS,XMSSMT,DILITHIUM,FALCON,PICNIC,SNOVA,MAYO,SPHINCSPLUS")
+ @UriParam(enums =
"MLDSA,SLHDSA,LMS,HSS,XMSS,XMSSMT,DILITHIUM,FALCON,SNOVA,MAYO,SPHINCSPLUS")
@Metadata(label = "advanced")
private String signatureAlgorithm;
@UriParam
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCKeyEncapsulationAlgorithms.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCKeyEncapsulationAlgorithms.java
index 6e060311713c..58cad9cbfcbd 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCKeyEncapsulationAlgorithms.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCKeyEncapsulationAlgorithms.java
@@ -24,9 +24,9 @@ public enum PQCKeyEncapsulationAlgorithms {
// Experimental and non-standardized
BIKE("BIKE", "BCPQC"),
HQC("HQC", "BCPQC"),
- CMCE("CMCE", "BCPQC"),
+ CMCE("CMCE", "BC"),
SABER("SABER", "BCPQC"),
- FRODO("FRODO", "BCPQC"),
+ FRODO("FrodoKEM", "BC"),
NTRU("NTRU", "BCPQC"),
NTRULPRime("NTRULPRime", "BCPQC"),
SNTRUPrime("SNTRUPrime", "BCPQC"),
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCParameterSpecResolver.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCParameterSpecResolver.java
index c0fcff9a4c44..37e5f3be2761 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCParameterSpecResolver.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCParameterSpecResolver.java
@@ -20,22 +20,18 @@ import java.security.spec.AlgorithmParameterSpec;
import java.util.Set;
import org.apache.camel.util.ObjectHelper;
+import org.bouncycastle.jcajce.spec.CMCEParameterSpec;
+import org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec;
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;
import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec;
import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec;
import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.FrodoParameterSpec;
import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec;
import org.bouncycastle.pqc.jcajce.spec.NTRULPRimeParameterSpec;
import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.PicnicParameterSpec;
import org.bouncycastle.pqc.jcajce.spec.SABERParameterSpec;
import org.bouncycastle.pqc.jcajce.spec.SNTRUPrimeParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.SPHINCSPlusParameterSpec;
/**
* Resolves the BouncyCastle {@link AlgorithmParameterSpec} for a PQC
algorithm from the parameter-set name configured
@@ -55,7 +51,7 @@ public final class PQCParameterSpecResolver {
*/
private static final Set<String> SUPPORTED_ALGORITHMS = Set.of(
// Signature algorithms
- "MLDSA", "SLHDSA", "FALCON", "DILITHIUM", "SPHINCSPLUS", "PICNIC",
+ "MLDSA", "SLHDSA", "FALCON", "DILITHIUM", "SPHINCSPLUS",
// Key encapsulation algorithms
"MLKEM", "KYBER", "NTRU", "NTRULPRime", "SNTRUPrime", "BIKE",
"HQC", "CMCE", "FRODO", "SABER");
@@ -97,7 +93,7 @@ public final class PQCParameterSpecResolver {
try {
resolved = doResolve(algorithm, name);
} catch (IllegalArgumentException e) {
- // The ML-DSA/ML-KEM/SLH-DSA specs throw for an unknown name
+ // The ML-DSA/ML-KEM/SLH-DSA/CMCE/FrodoKEM specs throw for an
unknown name
throw new IllegalArgumentException(
"Unknown parameterSpec '" + parameterSpec + "' for
algorithm " + algorithm, e);
}
@@ -118,17 +114,17 @@ public final class PQCParameterSpecResolver {
return SLHDSAParameterSpec.fromName(parameterSpec);
case "FALCON":
return FalconParameterSpec.fromName(parameterSpec);
+ // DILITHIUM and SPHINCSPLUS generate ML-DSA and SLH-DSA keys (see
PQCSignatureAlgorithms), so they take the
+ // standardized parameter sets
case "DILITHIUM":
- return DilithiumParameterSpec.fromName(parameterSpec);
+ return MLDSAParameterSpec.fromName(parameterSpec);
case "SPHINCSPLUS":
- return SPHINCSPlusParameterSpec.fromName(parameterSpec);
- case "PICNIC":
- return PicnicParameterSpec.fromName(parameterSpec);
+ return SLHDSAParameterSpec.fromName(parameterSpec);
// Key encapsulation algorithms
case "MLKEM":
- return MLKEMParameterSpec.fromName(parameterSpec);
case "KYBER":
- return KyberParameterSpec.fromName(parameterSpec);
+ // KYBER generates ML-KEM keys (see
PQCKeyEncapsulationAlgorithms)
+ return MLKEMParameterSpec.fromName(parameterSpec);
case "NTRU":
return NTRUParameterSpec.fromName(parameterSpec);
case "NTRULPRime":
@@ -142,7 +138,7 @@ public final class PQCParameterSpecResolver {
case "CMCE":
return CMCEParameterSpec.fromName(parameterSpec);
case "FRODO":
- return FrodoParameterSpec.fromName(parameterSpec);
+ return FrodoKEMParameterSpec.fromName(parameterSpec);
case "SABER":
return SABERParameterSpec.fromName(parameterSpec);
default:
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 4e818da8d059..030d20133df3 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
@@ -98,7 +98,6 @@ public class PQCProducer extends DefaultProducer {
PQCSignatureAlgorithms.XMSSMT.name(),
PQCSignatureAlgorithms.DILITHIUM.name(),
PQCSignatureAlgorithms.FALCON.name(),
- PQCSignatureAlgorithms.PICNIC.name(),
PQCSignatureAlgorithms.SNOVA.name(),
PQCSignatureAlgorithms.MAYO.name(),
PQCSignatureAlgorithms.SPHINCSPLUS.name());
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCSignatureAlgorithms.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCSignatureAlgorithms.java
index a528ecf01c86..ca70f7d9fca9 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCSignatureAlgorithms.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/PQCSignatureAlgorithms.java
@@ -29,7 +29,6 @@ public enum PQCSignatureAlgorithms {
// Experimental and non-standardized
FALCON("FALCON", "BCPQC"),
- PICNIC("PICNIC", "BCPQC"),
SNOVA("Snova", "BCPQC"),
MAYO("Mayo", "BCPQC"),
SPHINCSPLUS("SLH-DSA", "BC");
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/PQCDefaultPicnicMaterial.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/PQCDefaultPicnicMaterial.java
deleted file mode 100644
index b168b6d58f8e..000000000000
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/PQCDefaultPicnicMaterial.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.crypto;
-
-import java.security.*;
-
-import org.apache.camel.component.pqc.PQCSignatureAlgorithms;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
-import org.bouncycastle.pqc.jcajce.spec.PicnicParameterSpec;
-
-public class PQCDefaultPicnicMaterial {
- public static final KeyPair keyPair;
- public static final Signature signer;
-
- static {
- if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
- Security.addProvider(new BouncyCastleProvider());
- }
- if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) ==
null) {
- Security.addProvider(new BouncyCastlePQCProvider());
- }
- KeyPairGenerator generator;
- try {
- generator = prepareKeyPair();
- keyPair = generator.generateKeyPair();
- signer =
Signature.getInstance(PQCSignatureAlgorithms.PICNIC.getAlgorithm(),
- PQCSignatureAlgorithms.PICNIC.getBcProvider());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- protected static KeyPairGenerator prepareKeyPair()
- throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidAlgorithmParameterException {
- KeyPairGenerator kpGen =
KeyPairGenerator.getInstance(PQCSignatureAlgorithms.PICNIC.getAlgorithm(),
- PQCSignatureAlgorithms.PICNIC.getBcProvider());
- kpGen.initialize(PicnicParameterSpec.picnic3l5);
- return kpGen;
- }
-}
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultCMCEMaterial.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultCMCEMaterial.java
index ea6060a27c9d..c065121cac2d 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultCMCEMaterial.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultCMCEMaterial.java
@@ -22,9 +22,9 @@ import javax.crypto.KeyGenerator;
import org.apache.camel.component.pqc.PQCKeyEncapsulationAlgorithms;
import org.apache.camel.util.SecureRandomHelper;
+import org.bouncycastle.jcajce.spec.CMCEParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
-import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec;
public class PQCDefaultCMCEMaterial {
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultFRODOMaterial.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultFRODOMaterial.java
index b8776ab33d40..1109d316d6f6 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultFRODOMaterial.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/crypto/kem/PQCDefaultFRODOMaterial.java
@@ -22,9 +22,9 @@ import javax.crypto.KeyGenerator;
import org.apache.camel.component.pqc.PQCKeyEncapsulationAlgorithms;
import org.apache.camel.util.SecureRandomHelper;
+import org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
-import org.bouncycastle.pqc.jcajce.spec.FrodoParameterSpec;
public class PQCDefaultFRODOMaterial {
@@ -52,7 +52,7 @@ public class PQCDefaultFRODOMaterial {
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidAlgorithmParameterException {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance(PQCKeyEncapsulationAlgorithms.FRODO.getAlgorithm(),
PQCKeyEncapsulationAlgorithms.FRODO.getBcProvider());
- kpg.initialize(FrodoParameterSpec.frodokem976aes,
SecureRandomHelper.getSecureRandom());
+ kpg.initialize(FrodoKEMParameterSpec.frodokem976aes,
SecureRandomHelper.getSecureRandom());
return kpg;
}
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/AwsSecretsManagerKeyLifecycleManager.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/AwsSecretsManagerKeyLifecycleManager.java
index ef2acc2035b2..76ef0f38ce4a 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/AwsSecretsManagerKeyLifecycleManager.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/AwsSecretsManagerKeyLifecycleManager.java
@@ -36,6 +36,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.camel.component.pqc.PQCKeyEncapsulationAlgorithms;
import org.apache.camel.component.pqc.PQCSignatureAlgorithms;
import org.apache.camel.util.SecureRandomHelper;
+import org.bouncycastle.jcajce.spec.CMCEParameterSpec;
+import org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec;
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;
import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec;
@@ -606,13 +608,13 @@ public class AwsSecretsManagerKeyLifecycleManager
implements KeyLifecycleManager
case "SABER":
return SABERParameterSpec.lightsaberkem128r3;
case "FRODO":
- return FrodoParameterSpec.frodokem640aes;
+ return FrodoKEMParameterSpec.frodokem976aes;
case "BIKE":
return BIKEParameterSpec.bike128;
case "HQC":
return HQCParameterSpec.hqc128;
case "CMCE":
- return CMCEParameterSpec.mceliece348864;
+ return CMCEParameterSpec.mceliece460896;
default:
return null;
}
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/HashicorpVaultKeyLifecycleManager.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/HashicorpVaultKeyLifecycleManager.java
index 142dfc486877..46e5cfd19b22 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/HashicorpVaultKeyLifecycleManager.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/HashicorpVaultKeyLifecycleManager.java
@@ -35,6 +35,8 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.camel.component.pqc.PQCKeyEncapsulationAlgorithms;
import org.apache.camel.component.pqc.PQCSignatureAlgorithms;
import org.apache.camel.util.SecureRandomHelper;
+import org.bouncycastle.jcajce.spec.CMCEParameterSpec;
+import org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec;
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;
import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec;
@@ -629,13 +631,13 @@ public class HashicorpVaultKeyLifecycleManager implements
KeyLifecycleManager {
case "SABER":
return SABERParameterSpec.lightsaberkem128r3;
case "FRODO":
- return FrodoParameterSpec.frodokem640aes;
+ return FrodoKEMParameterSpec.frodokem976aes;
case "BIKE":
return BIKEParameterSpec.bike128;
case "HQC":
return HQCParameterSpec.hqc128;
case "CMCE":
- return CMCEParameterSpec.mceliece348864;
+ return CMCEParameterSpec.mceliece460896;
default:
return null;
}
diff --git
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/KeyAlgorithmSupport.java
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/KeyAlgorithmSupport.java
index 018f1d469298..0f812c286469 100644
---
a/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/KeyAlgorithmSupport.java
+++
b/components/camel-pqc/src/main/java/org/apache/camel/component/pqc/lifecycle/KeyAlgorithmSupport.java
@@ -23,6 +23,8 @@ import java.security.spec.AlgorithmParameterSpec;
import org.apache.camel.component.pqc.PQCKeyEncapsulationAlgorithms;
import org.apache.camel.component.pqc.PQCSignatureAlgorithms;
import org.apache.camel.util.SecureRandomHelper;
+import org.bouncycastle.jcajce.spec.CMCEParameterSpec;
+import org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec;
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;
import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec;
@@ -149,13 +151,13 @@ public final class KeyAlgorithmSupport {
case "SABER":
return SABERParameterSpec.lightsaberkem128r3;
case "FRODO":
- return FrodoParameterSpec.frodokem640aes;
+ return FrodoKEMParameterSpec.frodokem976aes;
case "BIKE":
return BIKEParameterSpec.bike128;
case "HQC":
return HQCParameterSpec.hqc128;
case "CMCE":
- return CMCEParameterSpec.mceliece348864;
+ return CMCEParameterSpec.mceliece460896;
default:
return null;
}
diff --git
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCCMCEGenerateEncapsulationAESTest.java
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCCMCEGenerateEncapsulationAESTest.java
index b95d43dbfa9c..f5e5f446cf6e 100644
---
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCCMCEGenerateEncapsulationAESTest.java
+++
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCCMCEGenerateEncapsulationAESTest.java
@@ -28,9 +28,9 @@ import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit6.CamelTestSupport;
import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
+import org.bouncycastle.jcajce.spec.CMCEParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
-import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec;
import org.bouncycastle.util.Arrays;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
diff --git
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCFRODOGenerateEncapsulationAESTest.java
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCFRODOGenerateEncapsulationAESTest.java
index c09d689d8160..7f3921b8f054 100644
---
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCFRODOGenerateEncapsulationAESTest.java
+++
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCFRODOGenerateEncapsulationAESTest.java
@@ -28,9 +28,9 @@ import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit6.CamelTestSupport;
import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
+import org.bouncycastle.jcajce.spec.FrodoKEMParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
-import org.bouncycastle.pqc.jcajce.spec.FrodoParameterSpec;
import org.bouncycastle.util.Arrays;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -92,7 +92,7 @@ public class PQCFRODOGenerateEncapsulationAESTest extends
CamelTestSupport {
public KeyPair setKeyPair() throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidAlgorithmParameterException {
KeyPairGenerator kpg =
KeyPairGenerator.getInstance(PQCKeyEncapsulationAlgorithms.FRODO.getAlgorithm(),
PQCKeyEncapsulationAlgorithms.FRODO.getBcProvider());
- kpg.initialize(FrodoParameterSpec.frodokem976aes, new SecureRandom());
+ kpg.initialize(FrodoKEMParameterSpec.frodokem976aes, new
SecureRandom());
KeyPair kp = kpg.generateKeyPair();
return kp;
}
diff --git
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCParameterSpecResolverTest.java
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCParameterSpecResolverTest.java
index 6164c533dcdc..48e5d092d5ab 100644
---
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCParameterSpecResolverTest.java
+++
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCParameterSpecResolverTest.java
@@ -16,13 +16,17 @@
*/
package org.apache.camel.component.pqc;
+import java.security.KeyPairGenerator;
import java.security.Security;
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 org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -47,6 +51,9 @@ class PQCParameterSpecResolverTest {
assertNotNull(PQCParameterSpecResolver.resolve("MLDSA", "ML-DSA-87"));
assertNotNull(PQCParameterSpecResolver.resolve("SLHDSA",
"SLH-DSA-SHA2-128S"));
assertNotNull(PQCParameterSpecResolver.resolve("FALCON",
"FALCON-1024"));
+ // DILITHIUM and SPHINCSPLUS generate ML-DSA and SLH-DSA keys, so they
take the standardized names
+ assertNotNull(PQCParameterSpecResolver.resolve("DILITHIUM",
"ML-DSA-65"));
+ assertNotNull(PQCParameterSpecResolver.resolve("SPHINCSPLUS",
"SLH-DSA-SHA2-128S"));
}
@Test
@@ -62,7 +69,37 @@ class PQCParameterSpecResolverTest {
assertNotNull(PQCParameterSpecResolver.resolve("MLKEM", "ml_kem_512"));
assertNotNull(PQCParameterSpecResolver.resolve("MLKEM",
"ml_kem_1024"));
assertNotNull(PQCParameterSpecResolver.resolve("KYBER", "kyber768"));
+ assertNotNull(PQCParameterSpecResolver.resolve("KYBER",
"ML-KEM-1024"));
assertNotNull(PQCParameterSpecResolver.resolve("BIKE", "bike128"));
+ assertNotNull(PQCParameterSpecResolver.resolve("CMCE",
"mceliece460896"));
+ assertNotNull(PQCParameterSpecResolver.resolve("FRODO",
"frodokem976aes"));
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "MLDSA, ML-DSA-65", "SLHDSA, SLH-DSA-SHA2-128S", "FALCON,
FALCON-512", "DILITHIUM, ML-DSA-65",
+ "SPHINCSPLUS, SLH-DSA-SHA2-128S" })
+ void
testResolvedSignatureSpecInitializesTheAlgorithmKeyPairGenerator(String
algorithm, String parameterSpec)
+ throws Exception {
+ PQCSignatureAlgorithms signatureAlgorithm =
PQCSignatureAlgorithms.valueOf(algorithm);
+ KeyPairGenerator generator =
KeyPairGenerator.getInstance(signatureAlgorithm.getAlgorithm(),
+ signatureAlgorithm.getBcProvider());
+
+ assertDoesNotThrow(() ->
generator.initialize(PQCParameterSpecResolver.resolve(algorithm,
parameterSpec)));
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "MLKEM, ML-KEM-768", "KYBER, kyber768", "NTRU, ntruhps2048509",
"NTRULPRime, ntrulpr653",
+ "SNTRUPrime, sntrup761", "BIKE, bike128", "HQC, hqc128", "CMCE,
mceliece460896", "FRODO, frodokem976aes",
+ "SABER, lightsaberkem128r3" })
+ void
testResolvedKeyEncapsulationSpecInitializesTheAlgorithmKeyPairGenerator(String
algorithm, String parameterSpec)
+ throws Exception {
+ PQCKeyEncapsulationAlgorithms kemAlgorithm =
PQCKeyEncapsulationAlgorithms.valueOf(algorithm);
+ KeyPairGenerator generator =
KeyPairGenerator.getInstance(kemAlgorithm.getAlgorithm(),
+ kemAlgorithm.getBcProvider());
+
+ assertDoesNotThrow(() ->
generator.initialize(PQCParameterSpecResolver.resolve(algorithm,
parameterSpec)));
}
@Test
@@ -94,6 +131,17 @@ class PQCParameterSpecResolverTest {
assertTrue(e.getMessage().contains("Unknown parameterSpec"));
}
+ @Test
+ void testParameterSetsDroppedByBouncyCastleRejected() {
+ // The Classic McEliece and FrodoKEM specs of the BC provider have no
mceliece348864 or frodokem640 sets
+ IllegalArgumentException cmce =
assertThrows(IllegalArgumentException.class,
+ () -> PQCParameterSpecResolver.resolve("CMCE",
"mceliece348864"));
+ assertTrue(cmce.getMessage().contains("Unknown parameterSpec"));
+ IllegalArgumentException frodo =
assertThrows(IllegalArgumentException.class,
+ () -> PQCParameterSpecResolver.resolve("FRODO",
"frodokem640aes"));
+ assertTrue(frodo.getMessage().contains("Unknown parameterSpec"));
+ }
+
@Test
void testUnknownParameterSpecRejectedWhenSpecReturnsNull() {
// the older BouncyCastle spec classes return null rather than
throwing for an unknown name
diff --git
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCSignaturePicnicNoAutowiredTest.java
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCSignaturePicnicNoAutowiredTest.java
deleted file mode 100644
index 5448230d974c..000000000000
---
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCSignaturePicnicNoAutowiredTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 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.junit6.CamelTestSupport;
-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.assertTrue;
-
-public class PQCSignaturePicnicNoAutowiredTest extends CamelTestSupport {
-
- @EndpointInject("mock:sign")
- protected MockEndpoint resultSign;
-
- @EndpointInject("mock:verify")
- protected MockEndpoint resultVerify;
-
- @Produce("direct:sign")
- protected ProducerTemplate templateSign;
-
- public PQCSignaturePicnicNoAutowiredTest() throws NoSuchAlgorithmException
{
- }
-
- @Override
- protected RouteBuilder createRouteBuilder() {
- return new RouteBuilder() {
- @Override
- public void configure() {
-
from("direct:sign").to("pqc:sign?operation=sign&signatureAlgorithm=PICNIC").to("mock:sign")
-
.to("pqc:verify?operation=verify&signatureAlgorithm=PICNIC")
- .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();
- resultVerify.assertIsSatisfied();
-
assertTrue(resultVerify.getExchanges().get(0).getMessage().getHeader(PQCConstants.VERIFY,
Boolean.class));
- }
-}
diff --git
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCSignaturePicnicTest.java
b/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCSignaturePicnicTest.java
deleted file mode 100644
index 2e1dc9434d49..000000000000
---
a/components/camel-pqc/src/test/java/org/apache/camel/component/pqc/PQCSignaturePicnicTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Security;
-import java.security.Signature;
-
-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.junit6.CamelTestSupport;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
-import org.bouncycastle.pqc.jcajce.spec.PicnicParameterSpec;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class PQCSignaturePicnicTest extends CamelTestSupport {
-
- @EndpointInject("mock:sign")
- protected MockEndpoint resultSign;
-
- @EndpointInject("mock:verify")
- protected MockEndpoint resultVerify;
-
- @Produce("direct:sign")
- protected ProducerTemplate templateSign;
-
- public PQCSignaturePicnicTest() throws NoSuchAlgorithmException {
- }
-
- @Override
- protected RouteBuilder createRouteBuilder() {
- return new RouteBuilder() {
- @Override
- public void configure() {
-
from("direct:sign").to("pqc:sign?operation=sign").to("mock:sign").to("pqc:verify?operation=verify")
- .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();
- resultVerify.assertIsSatisfied();
-
assertTrue(resultVerify.getExchanges().get(0).getMessage().getHeader(PQCConstants.VERIFY,
Boolean.class));
- }
-
- @BindToRegistry("Keypair")
- public KeyPair setKeyPair() throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidAlgorithmParameterException {
- KeyPairGenerator kpGen =
KeyPairGenerator.getInstance(PQCSignatureAlgorithms.PICNIC.getAlgorithm(),
- PQCSignatureAlgorithms.PICNIC.getBcProvider());
- kpGen.initialize(PicnicParameterSpec.picnic3l5);
- KeyPair kp = kpGen.generateKeyPair();
- return kp;
- }
-
- @BindToRegistry("Signer")
- public Signature getSigner() throws NoSuchAlgorithmException,
NoSuchProviderException {
- Signature mlDsa =
Signature.getInstance(PQCSignatureAlgorithms.PICNIC.getAlgorithm(),
- PQCSignatureAlgorithms.PICNIC.getBcProvider());
- return mlDsa;
- }
-}
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index e3b446578ccf..ea85daddbf6b 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -3521,6 +3521,40 @@ Deployments that organised keys that way must switch to
a flat `keyId` (for exam
Only the file-based manager is affected; the in-memory and cloud-backed
managers were never file-path
based.
+=== camel-pqc - Bouncy Castle 1.86 (Breaking change)
+
+Camel now uses Bouncy Castle 1.86, which removes the legacy implementations of
several post-quantum
+algorithms from the `BCPQC` provider.
+
+*Picnic removed.* Bouncy Castle 1.86 no longer ships Picnic, so the `PICNIC`
value of the
+`signatureAlgorithm` option, the `PQCSignatureAlgorithms.PICNIC` constant and
`PQCDefaultPicnicMaterial`
+have been removed. Routes signing with Picnic must move to another signature
algorithm, such as `MLDSA`
+or `SLHDSA`.
+
+*Classic McEliece and FrodoKEM use the `BC` provider.* `CMCE` and `FRODO` are
now served by the Classic
+McEliece and FrodoKEM implementations of the `BC` provider (JCA names `CMCE`
and `FrodoKEM`) instead of
+`BCPQC`. That implementation has no `mceliece348864` or `frodokem640`
parameter sets: the
+`parameterSpec` option rejects them, and the default parameter sets of the key
lifecycle managers changed
+from `mceliece348864` to `mceliece460896` and from `frodokem640aes` to
`frodokem976aes`.
+
+*Stored keys must be generated again.* The `BC` provider rejects the algorithm
identifier of Classic
+McEliece and FrodoKEM keys generated by the removed `BCPQC` implementations,
and Picnic keys can no
+longer be read at all. Keys of these algorithms held by a key lifecycle
manager, a key store or the
+registry have to be regenerated, and the peers they are shared with updated.
+
+*`parameterSpec` for `DILITHIUM`, `SPHINCSPLUS` and `KYBER`.* These algorithms
generate ML-DSA, SLH-DSA
+and ML-KEM keys, so `parameterSpec` now takes the standardized parameter-set
names, for example
+`ML-DSA-65`, `SLH-DSA-SHA2-128S` or `ML-KEM-768`. The `dilithium2`,
`dilithium3` and `dilithium5` names
+are no longer accepted, while `kyber512`, `kyber768`, `kyber1024` and SPHINCS+
names such as
+`sha2-128s` still are. With Bouncy Castle 1.85 a `DILITHIUM` or `SPHINCSPLUS`
endpoint configured with a
+`parameterSpec` already failed to generate its key.
+
+Code that creates key material itself has to follow the same move: the
`CMCEParameterSpec`,
+`FrodoParameterSpec`, `KyberParameterSpec`, `DilithiumParameterSpec`,
`SPHINCSPlusParameterSpec` and
+`PicnicParameterSpec` classes of `org.bouncycastle.pqc.jcajce.spec` no longer
exist. Use
+`CMCEParameterSpec`, `FrodoKEMParameterSpec`, `MLKEMParameterSpec`,
`MLDSAParameterSpec` and
+`SLHDSAParameterSpec` of `org.bouncycastle.jcajce.spec` with the `BC` provider
instead.
+
=== camel-crypto
Three changes to `CryptoDataFormat`, none of which affects the format of data
already written.
diff --git a/parent/pom.xml b/parent/pom.xml
index 889047eedbbb..68078c1542f8 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -96,7 +96,7 @@
<azure-sdk-bom-version>1.3.3</azure-sdk-bom-version>
<azure-storage-blob-changefeed-version>12.0.0-beta.39</azure-storage-blob-changefeed-version>
<beanio-version>3.2.1</beanio-version>
- <bouncycastle-version>1.85</bouncycastle-version>
+ <bouncycastle-version>1.86</bouncycastle-version>
<box-java-sdk-version>4.16.4</box-java-sdk-version>
<braintree-gateway-version>3.54.0</braintree-gateway-version>
<build-helper-maven-plugin-version>3.6.2</build-helper-maven-plugin-version>