From ff2c85e51fcfafcb62bc7f49d33e62b6a3da9fb3 Mon Sep 17 00:00:00 2001 From: JiriOndrusek Date: Thu, 15 Feb 2024 16:25:02 +0100 Subject: [PATCH] Easier adaptation of custom algorithm suite CXF-8971, which defaulrs to FIPS --- .../ws-security-policy/application.properties | 78 +++++- .../cxf/ws/security/CxfWsSecurityConfig.java | 224 ++++++++++++++++++ .../ws/security/WssConfigurationConstant.java | 4 +- .../cxf/ws/security/WssFactoryCustomizer.java | 3 + .../CustomEncryptSignPolicyHelloService.java | 17 ++ ...stomEncryptSignPolicyHelloServiceImpl.java | 18 ++ ...stomizedEncryptSignPolicyHelloService.java | 18 ++ ...izedEncryptSignPolicyHelloServiceImpl.java | 18 ++ .../policy/SecurityPolicyResource.java | 28 +++ .../src/main/resources/application.properties | 78 +++++- .../resources/custom-encrypt-sign-policy.xml | 61 +++++ .../policy/CustomEncryptSignPolicyTest.java | 57 +++++ 12 files changed, 599 insertions(+), 5 deletions(-) create mode 100644 integration-tests/ws-security-policy/src/main/java/io/quarkiverse/cxf/it/security/policy/CustomEncryptSignPolicyHelloService.java create mode 100644 integration-tests/ws-security-policy/src/main/java/io/quarkiverse/cxf/it/security/policy/CustomEncryptSignPolicyHelloServiceImpl.java create mode 100644 integration-tests/ws-security-policy/src/main/java/io/quarkiverse/cxf/it/security/policy/CustomizedEncryptSignPolicyHelloService.java create mode 100644 integration-tests/ws-security-policy/src/main/java/io/quarkiverse/cxf/it/security/policy/CustomizedEncryptSignPolicyHelloServiceImpl.java create mode 100644 integration-tests/ws-security-policy/src/main/resources/custom-encrypt-sign-policy.xml create mode 100644 integration-tests/ws-security-policy/src/test/java/io/quarkiverse/cxf/it/security/policy/CustomEncryptSignPolicyTest.java diff --git a/docs/modules/ROOT/examples/ws-security-policy/application.properties b/docs/modules/ROOT/examples/ws-security-policy/application.properties index 25fcf932b..6248ab915 100644 --- a/docs/modules/ROOT/examples/ws-security-policy/application.properties +++ b/docs/modules/ROOT/examples/ws-security-policy/application.properties @@ -225,5 +225,79 @@ quarkus.cxf.client.helloSaml2.security.signature.password = password quarkus.cxf.client.helloSaml2.security.signature.crypto = #aliceCrypto quarkus.cxf.client.helloSaml2.security.saml-callback-handler = #saml2CallbackHandler - - +#custom algorithm suite + +quarkus.cxf.endpoint."/helloCustomEncryptSign".implementor = io.quarkiverse.cxf.it.security.policy.CustomEncryptSignPolicyHelloServiceImpl +quarkus.cxf.endpoint."/helloCustomEncryptSign".security.return.security.error = true +quarkus.cxf.endpoint."/helloCustomEncryptSign".security.signature.username = bob +quarkus.cxf.endpoint."/helloCustomEncryptSign".security.signature.password = password +quarkus.cxf.endpoint."/helloCustomEncryptSign".security.signature.crypto = #bobCrypto +quarkus.cxf.endpoint."/helloCustomEncryptSign".security.encryption.username = alice +quarkus.cxf.endpoint."/helloCustomEncryptSign".security.encryption.crypto = #bobCrypto + +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".implementor = io.quarkiverse.cxf.it.security.policy.CustomizedEncryptSignPolicyHelloServiceImpl +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.return.security.error = true +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.signature.username = bob +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.signature.password = password +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.signature.crypto = #bobCrypto +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.encryption.username = alice +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.encryption.crypto = #bobCrypto +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.custom.digest.algorithm = http://www.w3.org/2000/09/xmldsig#sha1 +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.custom.encryption.algorithm = http://www.w3.org/2001/04/xmlenc#aes256-cbc +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.custom.asymmetric.key.encryption.algorithm = http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.custom.encryption.key.derivation = http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1 +quarkus.cxf.endpoint."/helloCustomizedEncryptSign".security.custom.signature.key.derivation = http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1 + +quarkus.cxf.client.helloCustomEncryptSign.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/helloCustomEncryptSign +quarkus.cxf.client.helloCustomEncryptSign.service-interface = io.quarkiverse.cxf.it.security.policy.CustomEncryptSignPolicyHelloService +quarkus.cxf.client.helloCustomEncryptSign.features = #messageCollector +quarkus.cxf.client.helloCustomEncryptSign.trust-store = client-truststore.${keystore.type} +quarkus.cxf.client.helloCustomEncryptSign.trust-store-password = password +quarkus.cxf.client.helloCustomEncryptSign.security.signature.username = alice +quarkus.cxf.client.helloCustomEncryptSign.security.signature.password = password +quarkus.cxf.client.helloCustomEncryptSign.security.signature.crypto = #aliceCrypto +quarkus.cxf.client.helloCustomEncryptSign.security.encryption.username = bob +quarkus.cxf.client.helloCustomEncryptSign.security.encryption.crypto = #aliceCrypto + +quarkus.cxf.client.helloCustomizedEncryptSign.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/helloCustomizedEncryptSign +quarkus.cxf.client.helloCustomizedEncryptSign.service-interface = io.quarkiverse.cxf.it.security.policy.CustomizedEncryptSignPolicyHelloService +quarkus.cxf.client.helloCustomizedEncryptSign.features = #messageCollector +quarkus.cxf.client.helloCustomizedEncryptSign.trust-store = client-truststore.${keystore.type} +quarkus.cxf.client.helloCustomizedEncryptSign.trust-store-password = password +quarkus.cxf.client.helloCustomizedEncryptSign.security.signature.username = alice +quarkus.cxf.client.helloCustomizedEncryptSign.security.signature.password = password +quarkus.cxf.client.helloCustomizedEncryptSign.security.signature.crypto = #aliceCrypto +quarkus.cxf.client.helloCustomizedEncryptSign.security.encryption.username = bob +quarkus.cxf.client.helloCustomizedEncryptSign.security.encryption.crypto = #aliceCrypto +quarkus.cxf.client.helloCustomizedEncryptSign.security.custom.digest.algorithm = http://www.w3.org/2000/09/xmldsig#sha1 +quarkus.cxf.client.helloCustomizedEncryptSign.security.custom.encryption.algorithm = http://www.w3.org/2001/04/xmlenc#aes256-cbc +quarkus.cxf.client.helloCustomizedEncryptSign.security.custom.asymmetric.key.encryption.algorithm = http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p +quarkus.cxf.client.helloCustomizedEncryptSign.security.custom.encryption.key.derivation = http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1 +quarkus.cxf.client.helloCustomizedEncryptSign.security.custom.signature.key.derivation = http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1 + +quarkus.cxf.client.helloCustomEncryptSignWrong01.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/helloCustomizedEncryptSign +quarkus.cxf.client.helloCustomEncryptSignWrong01.service-interface = io.quarkiverse.cxf.it.security.policy.CustomEncryptSignPolicyHelloService +quarkus.cxf.client.helloCustomEncryptSignWrong01.features = #messageCollector +quarkus.cxf.client.helloCustomEncryptSignWrong01.trust-store = client-truststore.${keystore.type} +quarkus.cxf.client.helloCustomEncryptSignWrong01.trust-store-password = password +quarkus.cxf.client.helloCustomEncryptSignWrong01.security.signature.username = alice +quarkus.cxf.client.helloCustomEncryptSignWrong01.security.signature.password = password +quarkus.cxf.client.helloCustomEncryptSignWrong01.security.signature.crypto = #aliceCrypto +quarkus.cxf.client.helloCustomEncryptSignWrong01.security.encryption.username = bob +quarkus.cxf.client.helloCustomEncryptSignWrong01.security.encryption.crypto = #aliceCrypto + +quarkus.cxf.client.helloCustomEncryptSignWrong02.client-endpoint-url = https://localhost:${quarkus.http.test-ssl-port}/services/helloCustomEncryptSign +quarkus.cxf.client.helloCustomEncryptSignWrong02.service-interface = io.quarkiverse.cxf.it.security.policy.CustomizedEncryptSignPolicyHelloService +quarkus.cxf.client.helloCustomEncryptSignWrong02.features = #messageCollector +quarkus.cxf.client.helloCustomEncryptSignWrong02.trust-store = client-truststore.${keystore.type} +quarkus.cxf.client.helloCustomEncryptSignWrong02.trust-store-password = password +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.signature.username = alice +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.signature.password = password +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.signature.crypto = #aliceCrypto +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.encryption.username = bob +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.encryption.crypto = #aliceCrypto +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.custom.digest.algorithm = http://www.w3.org/2000/09/xmldsig#sha1 +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.custom.encryption.algorithm = http://www.w3.org/2001/04/xmlenc#aes256-cbc +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.custom.asymmetric.key.encryption.algorithm = http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.custom.encryption.key.derivation = http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1 +quarkus.cxf.client.helloCustomEncryptSignWrong02.security.custom.signature.key.derivation = http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1 \ No newline at end of file diff --git a/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/CxfWsSecurityConfig.java b/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/CxfWsSecurityConfig.java index 4d636f1e4..ee907d925 100644 --- a/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/CxfWsSecurityConfig.java +++ b/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/CxfWsSecurityConfig.java @@ -2,10 +2,13 @@ import static io.quarkiverse.cxf.ws.security.WssConfigurationConstant.Transformer.beanRef; import static io.quarkiverse.cxf.ws.security.WssConfigurationConstant.Transformer.properties; +import static io.quarkiverse.cxf.ws.security.WssConfigurationConstant.Transformer.toInteger; import java.util.Map; import java.util.Optional; +import org.apache.cxf.ws.security.SecurityConstants; + import io.quarkus.runtime.annotations.ConfigDocFilename; import io.quarkus.runtime.annotations.ConfigGroup; import io.quarkus.runtime.annotations.ConfigPhase; @@ -955,6 +958,227 @@ public interface ClientOrEndpointSecurityConfig { @WithName("kerberos.client") Optional kerberosClient(); + // + // Custom Algorithm Suite + // + + /** + * If algorithm suite with the identifier CustomizedAlgorithmSuite is used, it can be fully customized. + * Suggested usage is for scenarios for the non-standard security requirements (like FIPS). + * + *

+ * Default values are derived from the algorithm suite Basic256Sha256Rsa15 and are FIPS compliant. + *

+ *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ * + *

+ * Default values: + *

+ * + *

+ */ + public static final String CUSTOM_ALGORITHM_SUITE_NAME = "CustomAlgorithmSuite"; + + /** + * Digest Algorithm. + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_DIGEST_ALGORITHM) + @WithName("custom.digest.algorithm") + @WithDefault("http://www.w3.org/2001/04/xmlenc#sha256") + public String digestAlgorithm(); + + /** + * Encryption Algorithm. + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_ENCRYPTION_ALGORITHM) + @WithName("custom.encryption.algorithm") + @WithDefault("http://www.w3.org/2009/xmlenc11#aes256-gcm") + public String encryptionAlgorithm(); + + /** + * Symmetric Key Encryption Algorithm. + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_SYMMETRIC_KEY_ENCRYPTION_ALGORITHM) + @WithName("custom.symmetric.key.encryption.algorithm") + @WithDefault("http://www.w3.org/2001/04/xmlenc#kw-aes256") + public String symmetricKeyEncryptionAlgorithm(); + + /** + * Asymmetric Key Encryption Algorithm. + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_ASYMMETRIC_KEY_ENCRYPTION_ALGORITHM) + @WithName("custom.asymmetric.key.encryption.algorithm") + @WithDefault("http://www.w3.org/2001/04/xmlenc#rsa-1_5") + public String asymmetricKeyEncryptionAlgorithm(); + + /** + * Encryption Key Derivation. For more information about algorithms, see WS-SecurityPolicy 1.2 and security algorithms + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_ENCRYPTION_KEY_DERIVATION) + @WithName("custom.encryption.key.derivation") + @WithDefault("http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1") + public String encryptionKeyDerivation(); + + /** + * Signature Key Derivation. + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_SIGNATURE_KEY_DERIVATION) + @WithName("custom.signature.key.derivation") + @WithDefault("http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1") + public String signatureKeyDerivation(); + + /** + * Encryption Derived Key Length (number of bits). + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_ENCRYPTION_DERIVED_KEY_LENGTH, transformer = toInteger) + @WithName("custom.encryption.derived.key.length") + @WithDefault("256") + public Integer encryptionDerivedKeyLength(); + + /** + * Signature Derived Key Length (number of bits). + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_SIGNATURE_DERIVED_KEY_LENGTH, transformer = toInteger) + @WithName("custom.signature.derived.key.length") + @WithDefault("192") + public Integer signatureDerivedKeyLength(); + + /** + * Minimum Symmetric Key Length (number of bits). + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_MINIMUM_SYMMETRIC_KEY_LENGTH, transformer = toInteger) + @WithName("custom.minimum.symmetric.key.length") + @WithDefault("256") + public Integer minimumSymmetricKeyLength(); + + /** + * Maximum Symmetric Key Length (number of bits). + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_MAXIMUM_SYMMETRIC_KEY_LENGTH, transformer = toInteger) + @WithName("custom.maximum.symmetric.key.length") + @WithDefault("256") + public Integer maximumSymmetricKeyLength(); + + /** + * Minimum Symmetric Key Length (number of bits). + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_MINIMUM_ASYMMETRIC_KEY_LENGTH, transformer = toInteger) + @WithName("custom.minimum.asymmetric.key.length") + @WithDefault("1024") + public Integer minimumAsymmetricKeyLength(); + + /** + * Maximum Symmetric Key Length (number of bits). + *

+ * For more information about algorithms, see + * WS-SecurityPolicy + * 1.2 + * and security + * algorithms + *

+ */ + @WssConfigurationConstant(key = SecurityConstants.CUSTOM_ALG_SUITE_MAXIMUM_ASYMMETRIC_KEY_LENGTH, transformer = toInteger) + @WithName("custom.maximum.asymmetric.key.length") + @WithDefault("4096") + public Integer maximumAsymmetricKeyLength(); } /** diff --git a/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssConfigurationConstant.java b/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssConfigurationConstant.java index 9935ca22a..5e565eba9 100644 --- a/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssConfigurationConstant.java +++ b/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssConfigurationConstant.java @@ -40,7 +40,9 @@ public enum Transformer { /** Looks up the given bean reference in the CDI container */ beanRef, /** Makes {@link Properties} out of a Map */ - properties; + properties, + /** Calls {@code Integer.parseInt()} on the given type's {@code toString()} */ + toInteger; } } diff --git a/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssFactoryCustomizer.java b/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssFactoryCustomizer.java index dc740444d..47d2bbdbc 100644 --- a/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssFactoryCustomizer.java +++ b/extensions/ws-security/runtime/src/main/java/io/quarkiverse/cxf/ws/security/WssFactoryCustomizer.java @@ -133,6 +133,9 @@ static void consumeAnnotated(Class cl, Object config, BiConsumer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration-tests/ws-security-policy/src/test/java/io/quarkiverse/cxf/it/security/policy/CustomEncryptSignPolicyTest.java b/integration-tests/ws-security-policy/src/test/java/io/quarkiverse/cxf/it/security/policy/CustomEncryptSignPolicyTest.java new file mode 100644 index 000000000..4762bb309 --- /dev/null +++ b/integration-tests/ws-security-policy/src/test/java/io/quarkiverse/cxf/it/security/policy/CustomEncryptSignPolicyTest.java @@ -0,0 +1,57 @@ +package io.quarkiverse.cxf.it.security.policy; + +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; + +@QuarkusTest +public class CustomEncryptSignPolicyTest { + + @Test + void helloDefaultCustomValues() { + RestAssured.given() + .config(PolicyTestUtils.restAssuredConfig()) + .body("Dolly") + .post("/cxf/security-policy/helloCustomEncryptSign") + .then() + .statusCode(200) + .body(is("Hello Dolly from CustomEncryptSign!")); + } + + @Test + void helloCustomizedValuesCorrectly() { + RestAssured.given() + .config(PolicyTestUtils.restAssuredConfig()) + .body("Dolly") + .post("/cxf/security-policy/helloCustomizedEncryptSign") + .then() + .statusCode(200) + .body(is("Hello Dolly from CustomizedEncryptSign!")); + } + + @Test + void helloCustomizedValuesWrong01() { + //client used default custom algorithm suite, but server is changed (server is same as in the test 'helloDefaultCustomValues') + RestAssured.given() + .config(PolicyTestUtils.restAssuredConfig()) + .body("Dolly") + .post("/cxf/security-policy/helloCustomEncryptSignWrong01") + .then() + .statusCode(500); + } + + @Test + void helloCustomizedValuesWrong02() { + //client customizes custom algorithm suite, but server is using default one (server is same as in the test 'helloCustomizedValuesCorrectly') + RestAssured.given() + .config(PolicyTestUtils.restAssuredConfig()) + .body("Dolly") + .post("/cxf/security-policy/helloCustomEncryptSignWrong02") + .then() + .statusCode(500); + } + +}