[java-opensaml] 02/02: OSJ-339: Add config prop for global ECDH KDF.
Brent Putman
putmanb at georgetown.edu
Tue Jul 27 03:14:19 UTC 2021
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch main
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=c482720f1145dcc81817003f8136e05891a0eb3e
commit c482720f1145dcc81817003f8136e05891a0eb3e
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Tue Jul 20 19:24:38 2021 -0400
OSJ-339: Add config prop for global ECDH KDF.
---
.../DefaultSecurityConfigurationBootstrap.java | 68 +++++++++---
.../DefaultSecurityConfigurationBootstrapTest.java | 120 +++++++++++++++++++++
2 files changed, 173 insertions(+), 15 deletions(-)
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/DefaultSecurityConfigurationBootstrap.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/DefaultSecurityConfigurationBootstrap.java
index d21a30df8..d78841ede 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/DefaultSecurityConfigurationBootstrap.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/config/impl/DefaultSecurityConfigurationBootstrap.java
@@ -22,14 +22,17 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import javax.annotation.Nonnull;
+import org.opensaml.core.config.ConfigurationService;
import org.opensaml.security.crypto.JCAConstants;
import org.opensaml.xmlsec.agreement.impl.DigestMethod;
import org.opensaml.xmlsec.agreement.impl.KANonce;
import org.opensaml.xmlsec.derivation.impl.ConcatKDF;
+import org.opensaml.xmlsec.derivation.impl.PBKDF2;
import org.opensaml.xmlsec.encryption.support.ChainingEncryptedKeyResolver;
import org.opensaml.xmlsec.encryption.support.EncryptedKeyResolver;
import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
@@ -68,6 +71,15 @@ import net.shibboleth.utilities.java.support.component.ComponentInitializationEx
*/
public class DefaultSecurityConfigurationBootstrap {
+ /** Config property name for ECDH default Key Derivation Function (KDF). */
+ public static final String CONFIG_PROPERTY_ECDH_DEFAULT_KDF = "opensaml.config.ecdh.defaultKDF";
+
+ /** Config property value for default KDF: ConcatKDF. */
+ public static final String CONCATKDF = "ConcatKDF";
+
+ /** Config property value for default KDF: PBKDF2. */
+ public static final String PBKDF2 = "PBKDF2";
+
/** Logger. */
private static final Logger LOG = LoggerFactory.getLogger(DefaultSecurityConfigurationBootstrap.class);
@@ -113,19 +125,49 @@ public class DefaultSecurityConfigurationBootstrap {
null
));
+ config.setKeyAgreementConfigurations(buildKeyAgreementConfigurations());
+
+ config.setDataKeyInfoGeneratorManager(buildDataEncryptionKeyInfoGeneratorManager());
+ config.setKeyTransportKeyInfoGeneratorManager(buildKeyTransportEncryptionKeyInfoGeneratorManager());
+
+ return config;
+ }
+
+ /**
+ * Build key agreement configurations.
+ *
+ * @return key agreement configurations.
+ */
+ @Nonnull protected static Map<String, KeyAgreementEncryptionConfiguration> buildKeyAgreementConfigurations() {
+
+ final Map<String, KeyAgreementEncryptionConfiguration> kaConfigs = new HashMap<>();
try {
- final Map<String, KeyAgreementEncryptionConfiguration> kaConfigs = new HashMap<>();
+
+ final Properties props = ConfigurationService.getConfigurationProperties();
final KeyAgreementEncryptionConfiguration ecConfig = new KeyAgreementEncryptionConfiguration();
ecConfig.setAlgorithm(EncryptionConstants.ALGO_ID_KEYAGREEMENT_ECDH_ES);
- final ConcatKDF ecConcatKDF = new ConcatKDF();
- // Need to set these 3 to something to confirm to NIST spec requirements. Actual deployments
- // can and should override in a custom config with specific parameter values, if needed.
- ecConcatKDF.setAlgorithmID("00");
- ecConcatKDF.setPartyUInfo("00");
- ecConcatKDF.setPartyVInfo("00");
- ecConcatKDF.initialize();
- ecConfig.setParameters(Set.of(ecConcatKDF));
+
+ final String ecKDF =
+ props != null ? props.getProperty(CONFIG_PROPERTY_ECDH_DEFAULT_KDF, CONCATKDF) : CONCATKDF;
+
+ if (CONCATKDF.equals(ecKDF)) {
+ final ConcatKDF ecConcatKDF = new ConcatKDF();
+ // Need to set these 3 to something to confirm to NIST spec requirements. Actual deployments
+ // can and should override in a custom config with specific parameter values, if needed.
+ ecConcatKDF.setAlgorithmID("00");
+ ecConcatKDF.setPartyUInfo("00");
+ ecConcatKDF.setPartyVInfo("00");
+ ecConcatKDF.initialize();
+ ecConfig.setParameters(Set.of(ecConcatKDF));
+ } else if (PBKDF2.equals(ecKDF)) {
+ final PBKDF2 ecPBKDF2 = new PBKDF2();
+ ecPBKDF2.initialize();
+ ecConfig.setParameters(Set.of(ecPBKDF2));
+ } else {
+ LOG.warn("Saw unknown value for ECDH KDF '{}', omitting global ECDH KDF configuration", ecKDF);
+ ecConfig.setParameters(Collections.emptySet());
+ }
kaConfigs.put(JCAConstants.KEY_ALGO_EC, ecConfig);
// For DH we default the Legacy KDF variant as that is mandatory for DH support.
@@ -134,21 +176,17 @@ public class DefaultSecurityConfigurationBootstrap {
final DigestMethod digestMethod = new DigestMethod();
digestMethod.setAlgorithm(EncryptionConstants.ALGO_ID_DIGEST_SHA256);
digestMethod.initialize();
- KANonce nonce = new KANonce();
+ final KANonce nonce = new KANonce();
// This will use an auto-generated nonce value each time
nonce.initialize();
dhConfig.setParameters(Set.of(digestMethod, nonce));
kaConfigs.put(JCAConstants.KEY_ALGO_DH, dhConfig);
- config.setKeyAgreementConfigurations(kaConfigs);
} catch (final ComponentInitializationException e) {
LOG.error("Initialization failure on global key agreement encryption configuration, will be unusable", e);
}
- config.setDataKeyInfoGeneratorManager(buildDataEncryptionKeyInfoGeneratorManager());
- config.setKeyTransportKeyInfoGeneratorManager(buildKeyTransportEncryptionKeyInfoGeneratorManager());
-
- return config;
+ return kaConfigs;
}
/**
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/config/impl/DefaultSecurityConfigurationBootstrapTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/config/impl/DefaultSecurityConfigurationBootstrapTest.java
new file mode 100644
index 000000000..e31190c38
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/config/impl/DefaultSecurityConfigurationBootstrapTest.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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.opensaml.xmlsec.config.impl;
+
+import java.util.Map;
+import java.util.Properties;
+
+import org.opensaml.core.config.provider.ThreadLocalConfigurationPropertiesHolder;
+import org.opensaml.security.crypto.JCAConstants;
+import org.opensaml.xmlsec.derivation.KeyDerivation;
+import org.opensaml.xmlsec.derivation.impl.ConcatKDF;
+import org.opensaml.xmlsec.derivation.impl.PBKDF2;
+import org.opensaml.xmlsec.encryption.support.KeyAgreementEncryptionConfiguration;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ *
+ */
+public class DefaultSecurityConfigurationBootstrapTest {
+
+ @Test
+ public void testECDHDefaultKDF() {
+ Map<String, KeyAgreementEncryptionConfiguration> kaConfigs = DefaultSecurityConfigurationBootstrap.buildKeyAgreementConfigurations();
+ Assert.assertTrue(kaConfigs.containsKey(JCAConstants.KEY_ALGO_EC));
+
+ KeyAgreementEncryptionConfiguration config = kaConfigs.get(JCAConstants.KEY_ALGO_EC);
+ KeyDerivation keyDerivation = config.getParameters().stream()
+ .filter(KeyDerivation.class::isInstance)
+ .map(KeyDerivation.class::cast)
+ .findFirst().orElse(null);
+ Assert.assertNotNull(keyDerivation);
+ Assert.assertTrue(ConcatKDF.class.isInstance(keyDerivation));
+ }
+
+ @Test
+ public void testECDHConcatKDF() {
+ try {
+ Properties props = new Properties();
+ props.setProperty("opensaml.config.ecdh.defaultKDF", "ConcatKDF");
+ ThreadLocalConfigurationPropertiesHolder.setProperties(props);
+
+ Map<String, KeyAgreementEncryptionConfiguration> kaConfigs = DefaultSecurityConfigurationBootstrap.buildKeyAgreementConfigurations();
+ Assert.assertTrue(kaConfigs.containsKey(JCAConstants.KEY_ALGO_EC));
+
+ KeyAgreementEncryptionConfiguration config = kaConfigs.get(JCAConstants.KEY_ALGO_EC);
+ KeyDerivation keyDerivation = config.getParameters().stream()
+ .filter(KeyDerivation.class::isInstance)
+ .map(KeyDerivation.class::cast)
+ .findFirst().orElse(null);
+ Assert.assertNotNull(keyDerivation);
+ Assert.assertTrue(ConcatKDF.class.isInstance(keyDerivation));
+ } finally {
+ ThreadLocalConfigurationPropertiesHolder.clear();
+ }
+
+ }
+
+ @Test
+ public void testECDHPBKDF2() {
+ try {
+ Properties props = new Properties();
+ props.setProperty("opensaml.config.ecdh.defaultKDF", "PBKDF2");
+ ThreadLocalConfigurationPropertiesHolder.setProperties(props);
+
+ Map<String, KeyAgreementEncryptionConfiguration> kaConfigs = DefaultSecurityConfigurationBootstrap.buildKeyAgreementConfigurations();
+ Assert.assertTrue(kaConfigs.containsKey(JCAConstants.KEY_ALGO_EC));
+
+ KeyAgreementEncryptionConfiguration config = kaConfigs.get(JCAConstants.KEY_ALGO_EC);
+ KeyDerivation keyDerivation = config.getParameters().stream()
+ .filter(KeyDerivation.class::isInstance)
+ .map(KeyDerivation.class::cast)
+ .findFirst().orElse(null);
+ Assert.assertNotNull(keyDerivation);
+ Assert.assertTrue(PBKDF2.class.isInstance(keyDerivation));
+ } finally {
+ ThreadLocalConfigurationPropertiesHolder.clear();
+ }
+
+ }
+
+ @Test
+ public void testECDHBadKDF() {
+ try {
+ Properties props = new Properties();
+ props.setProperty("opensaml.config.ecdh.defaultKDF", "BADBADBAD");
+ ThreadLocalConfigurationPropertiesHolder.setProperties(props);
+
+ Map<String, KeyAgreementEncryptionConfiguration> kaConfigs = DefaultSecurityConfigurationBootstrap.buildKeyAgreementConfigurations();
+ Assert.assertTrue(kaConfigs.containsKey(JCAConstants.KEY_ALGO_EC));
+
+ KeyAgreementEncryptionConfiguration config = kaConfigs.get(JCAConstants.KEY_ALGO_EC);
+ KeyDerivation keyDerivation = config.getParameters().stream()
+ .filter(KeyDerivation.class::isInstance)
+ .map(KeyDerivation.class::cast)
+ .findFirst().orElse(null);
+ Assert.assertNull(keyDerivation);
+
+ } finally {
+ ThreadLocalConfigurationPropertiesHolder.clear();
+ }
+
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list