This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch pqc-examples in repository https://gitbox.apache.org/repos/asf/camel-jbang-examples.git
commit 44b539e9e006a6cdd599c8e84a7d516c9d14e1a1 Author: Andrea Cosentino <[email protected]> AuthorDate: Mon Oct 13 14:08:08 2025 +0200 Added Java example for PQC Signing with Hashicorp Vault Key Lifecycle Management Signed-off-by: Andrea Cosentino <[email protected]> --- pqc-document-signing/PQCDocumentSigningRoutes.java | 20 ++++++++----- pqc-document-signing/README.adoc | 35 ++++++++++++++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/pqc-document-signing/PQCDocumentSigningRoutes.java b/pqc-document-signing/PQCDocumentSigningRoutes.java index 6b5c72e..94f0f70 100644 --- a/pqc-document-signing/PQCDocumentSigningRoutes.java +++ b/pqc-document-signing/PQCDocumentSigningRoutes.java @@ -31,9 +31,10 @@ import org.springframework.vault.core.VaultTemplate; /** * RouteBuilder for PQC Document Signing with HashiCorp Vault integration. * - * This class defines 11 routes: + * This class defines 12 routes: * 1. Initialize PQC signing key on startup - * 2. REST API - Sign and verify a document + * 2. REST API - Sign a document + * 3. REST API - Verify a document signature * 4. REST API - Get key metadata * 5. REST API - List all keys * 6. REST API - Rotate signing key @@ -106,12 +107,17 @@ public class PQCDocumentSigningRoutes extends RouteBuilder { " \"keyMetadata\": ${body}\n" + "}")) .setHeader("Content-Type", constant("application/json")) - .log("Response: ${body}") - // Decode base64 signature to binary + .log("Response: ${body}"); + + // Route 3: REST API - Verify a document signature + from("platform-http:/api/verify") + .routeId("verify-document-api") + .log("Received document verification request: ${body}") + // Get signature from X-Signature header (workaround for header filtering) .process(exchange -> { - String base64Signature = exchange.getMessage().getHeader("CamelPQCSignature", String.class); + String base64Signature = exchange.getIn().getHeader("X-Signature", String.class); if (base64Signature == null || base64Signature.isEmpty()) { - throw new IllegalArgumentException("CamelPQCSignature header is missing or empty"); + throw new IllegalArgumentException("X-Signature header is missing or empty"); } byte[] signature = Base64.getDecoder().decode(base64Signature); exchange.getIn().setHeader("CamelPQCSignature", signature); @@ -143,7 +149,7 @@ public class PQCDocumentSigningRoutes extends RouteBuilder { "}")) .end() .setHeader("Content-Type", constant("application/json")) - .log("Verification result: ${body}");; + .log("Verification result: ${body}"); // Route 4: REST API - Get key metadata from("platform-http:/api/key/metadata") diff --git a/pqc-document-signing/README.adoc b/pqc-document-signing/README.adoc index d8fe80b..09b313e 100644 --- a/pqc-document-signing/README.adoc +++ b/pqc-document-signing/README.adoc @@ -48,7 +48,7 @@ The example consists of the following files: [source,text] ---- pqc-document-signing/ -├── PQCDocumentSigningRoutes.java # Main RouteBuilder with 11 routes +├── PQCDocumentSigningRoutes.java # Main RouteBuilder with 12 routes ├── application.properties # Configuration file └── README.adoc # This file ---- @@ -113,7 +113,32 @@ $ curl -X POST http://localhost:8080/api/sign \ Note: The `signature` field contains a base64-encoded quantum-resistant signature. -=== 2. Get Key Metadata +=== 2. Verify a Document Signature + +Verifies the authenticity of a signed document using the signature from the sign response. + +[source,sh] +---- +$ curl -X POST http://localhost:8080/api/verify \ + -H "Content-Type: text/plain" \ + -H "X-Signature: UMyKJt21oIYWNq0jDe6v63Xw8bs7JZ9hg9KEYXdFPIMxXS3AHwOa..." \ + -d "This is a confidential document that needs quantum-resistant protection" +---- + +Note: Pass the base64-encoded signature from the sign response in the `X-Signature` header. The `X-Signature` header is used instead of `CamelPQCSignature` to avoid header filtering by REST frameworks. + +**Response:** +[source,json] +---- +{ + "status": "verified", + "valid": true, + "message": "Document signature is valid", + "signatureAlgorithm": "DILITHIUM" +} +---- + +=== 3. Get Key Metadata Retrieves detailed metadata about the signing key, including usage count and lifecycle status. @@ -140,7 +165,7 @@ $ curl http://localhost:8080/api/key/metadata } ---- -=== 3. List All Keys +=== 4. List All Keys Lists all PQC keys stored in Vault. @@ -164,7 +189,7 @@ $ curl http://localhost:8080/api/keys } ---- -=== 4. Rotate Signing Key +=== 5. Rotate Signing Key Manually rotates the signing key (creates a new key and deprecates the old one). @@ -259,7 +284,7 @@ key.rotation.check.period=60000 # Check interval (ms) === Signature Verification Failed * Ensure you're using the same document content for both signing and verification -* Include the `CamelPQCSignature` header with the base64-encoded signature from the sign response +* Include the `X-Signature` header with the base64-encoded signature from the sign response * The signature must be passed exactly as received from the sign endpoint (base64 string) * Verify the key hasn't been rotated or revoked * Check logs for "ERROR during verification" messages which indicate signature format issues
