[java-opensaml] 19/19: Additional tweaks and tests around general key agreement and ECDH.
Brent Putman
putmanb at georgetown.edu
Mon Mar 1 05:56:56 UTC 2021
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch dev/OSJ-82
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=d4e4b86b6308a92ad3b43e8e59d4b301f36b406d
commit d4e4b86b6308a92ad3b43e8e59d4b301f36b406d
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Fri Feb 26 23:01:36 2021 -0500
Additional tweaks and tests around general key agreement and ECDH.
---
.../saml/common/testing/SAMLTestSupport.java | 6 +-
.../saml/saml2/encryption/tests/ECDHTest.java | 369 +++++++++++++++++++++
.../xmlsec/agreement/KeyAgreementSupport.java | 33 ++
.../AbstractDerivationKeyAgreementProcessor.java | 3 +
.../impl/ECDHKeyAgreementProcessorTest.java | 14 +
.../agreement/tests/KeyAgreementSupportTest.java | 122 +++++++
.../xmlsec/encryption/support/tests/ECDHTest.java | 237 +++++++++++++
.../xmlsec/testing/XMLSecurityTestingSupport.java | 6 +-
8 files changed, 788 insertions(+), 2 deletions(-)
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java
index 255209dea..64fe0e684 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java
@@ -43,12 +43,16 @@ public final class SAMLTestSupport {
* @return a new KeyInfoCredentialResolver instance
*/
public static KeyInfoCredentialResolver buildBasicInlineKeyInfoResolver() {
+ return new BasicProviderKeyInfoCredentialResolver(getBasicInlineKeyInfoProviders());
+ }
+
+ public static List<KeyInfoProvider> getBasicInlineKeyInfoProviders() {
List<KeyInfoProvider> providers = new ArrayList<>();
providers.add( new RSAKeyValueProvider() );
providers.add( new DSAKeyValueProvider() );
providers.add( new ECKeyValueProvider() );
providers.add( new InlineX509DataProvider() );
- return new BasicProviderKeyInfoCredentialResolver(providers);
+ return providers;
}
}
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/encryption/tests/ECDHTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/encryption/tests/ECDHTest.java
new file mode 100644
index 000000000..2cdb274c4
--- /dev/null
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/encryption/tests/ECDHTest.java
@@ -0,0 +1,369 @@
+/*
+ * 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.saml.saml2.encryption.tests;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.security.spec.ECGenParameterSpec;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opensaml.core.config.ConfigurationService;
+import org.opensaml.core.testing.XMLObjectBaseTestCase;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.saml.common.testing.SAMLTestSupport;
+import org.opensaml.saml.criterion.RoleDescriptorCriterion;
+import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.EncryptedAssertion;
+import org.opensaml.saml.saml2.encryption.Decrypter;
+import org.opensaml.saml.saml2.encryption.Encrypter;
+import org.opensaml.saml.saml2.encryption.Encrypter.KeyPlacement;
+import org.opensaml.saml.saml2.metadata.EncryptionMethod;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.KeyDescriptor;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml.security.SAMLMetadataKeyAgreementEncryptionConfiguration;
+import org.opensaml.saml.security.SAMLMetadataKeyAgreementEncryptionConfiguration.KeyWrap;
+import org.opensaml.saml.security.impl.MetadataCredentialResolver;
+import org.opensaml.saml.security.impl.SAMLMetadataEncryptionParametersResolver;
+import org.opensaml.security.credential.BasicCredential;
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.UsageType;
+import org.opensaml.security.credential.impl.CollectionCredentialResolver;
+import org.opensaml.security.crypto.KeySupport;
+import org.opensaml.xmlsec.DecryptionConfiguration;
+import org.opensaml.xmlsec.DecryptionParameters;
+import org.opensaml.xmlsec.DecryptionParametersResolver;
+import org.opensaml.xmlsec.EncryptionConfiguration;
+import org.opensaml.xmlsec.EncryptionParameters;
+import org.opensaml.xmlsec.EncryptionParametersResolver;
+import org.opensaml.xmlsec.criterion.DecryptionConfigurationCriterion;
+import org.opensaml.xmlsec.criterion.EncryptionConfigurationCriterion;
+import org.opensaml.xmlsec.derivation.impl.PBKDF2;
+import org.opensaml.xmlsec.encryption.EncryptedKey;
+import org.opensaml.xmlsec.encryption.KeyDerivationMethod;
+import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters;
+import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
+import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters;
+import org.opensaml.xmlsec.impl.BasicDecryptionConfiguration;
+import org.opensaml.xmlsec.impl.BasicDecryptionParametersResolver;
+import org.opensaml.xmlsec.impl.BasicEncryptionConfiguration;
+import org.opensaml.xmlsec.keyinfo.KeyInfoSupport;
+import org.opensaml.xmlsec.keyinfo.impl.KeyInfoProvider;
+import org.opensaml.xmlsec.keyinfo.impl.LocalKeyInfoCredentialResolver;
+import org.opensaml.xmlsec.keyinfo.impl.provider.AgreementMethodKeyInfoProvider;
+import org.opensaml.xmlsec.signature.KeyInfo;
+import org.opensaml.xmlsec.testing.XMLSecurityTestingSupport;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.w3c.dom.Element;
+
+import net.shibboleth.utilities.java.support.codec.EncodingException;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.xml.SerializeSupport;
+
+/**
+ *
+ */
+public class ECDHTest extends XMLObjectBaseTestCase {
+
+ private String targetFile;
+
+ private Credential recipientCredPrivate;
+ private Credential recipientCredPublic;
+ private String recipientCredKeyName = "RecipientCredName";
+
+ private CollectionCredentialResolver localCredentialResolver;
+ private LocalKeyInfoCredentialResolver localKeyInfoResolver;
+
+ private Encrypter encrypter;
+ private EncryptionParametersResolver encParamsResolver;
+ private CriteriaSet encCriteria;
+ private BasicEncryptionConfiguration encConfig;
+
+ private DecryptionParametersResolver decryptParamsResolver;
+ private CriteriaSet decryptCriteria;
+ private BasicDecryptionConfiguration decryptConfig;
+
+ private MetadataCredentialResolver mdCredResolver;
+
+ private RoleDescriptorCriterion roleDescCriterion;
+ private RoleDescriptor roleDesc;
+
+ private String targetEntityID = "urn:test:foo";
+
+
+ @BeforeClass
+ public void beforeClass() throws Exception {
+ targetFile = "/org/opensaml/saml/saml2/encryption/Assertion.xml";
+
+ KeyPair kp = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
+ recipientCredPrivate = new BasicCredential(kp.getPublic(), kp.getPrivate());
+ recipientCredPublic = new BasicCredential(kp.getPublic());
+
+ mdCredResolver = new MetadataCredentialResolver();
+ mdCredResolver.setKeyInfoCredentialResolver(SAMLTestSupport.buildBasicInlineKeyInfoResolver());
+ mdCredResolver.initialize();
+
+ encParamsResolver = new SAMLMetadataEncryptionParametersResolver(mdCredResolver);
+
+ decryptParamsResolver = new BasicDecryptionParametersResolver();
+
+ localCredentialResolver = new CollectionCredentialResolver(Set.of(recipientCredPrivate));
+
+ List<KeyInfoProvider> keyInfoProviders = new ArrayList<>(XMLSecurityTestingSupport.getBasicInlineKeyInfoProviders());
+ keyInfoProviders.add(new AgreementMethodKeyInfoProvider());
+ localKeyInfoResolver = new LocalKeyInfoCredentialResolver(keyInfoProviders, localCredentialResolver);
+ }
+
+ @BeforeMethod
+ public void beforeMethod() throws Exception {
+ roleDesc = buildRoleDescriptorSkeleton();
+ roleDescCriterion = new RoleDescriptorCriterion(roleDesc);
+
+ encConfig = new BasicEncryptionConfiguration();
+ EncryptionConfigurationCriterion encConfCrit = new EncryptionConfigurationCriterion(encConfig,
+ ConfigurationService.get(EncryptionConfiguration.class));
+ encCriteria = new CriteriaSet(encConfCrit, roleDescCriterion);
+
+ decryptConfig = new BasicDecryptionConfiguration();
+ decryptConfig.setDataKeyInfoCredentialResolver(localKeyInfoResolver);
+ decryptConfig.setKEKKeyInfoCredentialResolver(localKeyInfoResolver);
+
+ decryptCriteria = new CriteriaSet(new DecryptionConfigurationCriterion(decryptConfig,
+ ConfigurationService.get(DecryptionConfiguration.class)));
+ }
+
+ @Test
+ public void roundtripDirectDataEncryption() throws Exception {
+ KeyDescriptor kd = buildKeyDescriptor(recipientCredKeyName, UsageType.ENCRYPTION, recipientCredPublic.getPublicKey());
+ roleDesc.getKeyDescriptors().add(kd);
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128, null);
+ }
+
+ @Test
+ public void roundtripDirectDataEncryptionWithEncryptionMethod() throws Exception {
+ KeyDescriptor kd = buildKeyDescriptor(recipientCredKeyName, UsageType.ENCRYPTION, recipientCredPublic.getPublicKey());
+ kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM));
+ roleDesc.getKeyDescriptors().add(kd);
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM, null);
+ }
+
+ @Test
+ public void roundtripWithKeyWrapAlways() throws Exception {
+ KeyDescriptor kd = buildKeyDescriptor(recipientCredKeyName, UsageType.ENCRYPTION, recipientCredPublic.getPublicKey());
+ roleDesc.getKeyDescriptors().add(kd);
+
+ SAMLMetadataKeyAgreementEncryptionConfiguration kaConfig = new SAMLMetadataKeyAgreementEncryptionConfiguration();
+ kaConfig.setMetadataUseKeyWrap(KeyWrap.Always);
+ encConfig.setKeyAgreementConfigurations(Map.of("EC", kaConfig));
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128, EncryptionConstants.ALGO_ID_KEYWRAP_AES128);
+ }
+
+ @Test
+ public void roundtripWithKeyWrapAndEncryptionMethods() throws Exception {
+ KeyDescriptor kd = buildKeyDescriptor(recipientCredKeyName, UsageType.ENCRYPTION, recipientCredPublic.getPublicKey());
+ kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM));
+ kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYWRAP_AES256));
+ roleDesc.getKeyDescriptors().add(kd);
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM, EncryptionConstants.ALGO_ID_KEYWRAP_AES256);
+ }
+
+ @Test
+ public void roundtripWithPBKDF2() throws Exception {
+ KeyDescriptor kd = buildKeyDescriptor(recipientCredKeyName, UsageType.ENCRYPTION, recipientCredPublic.getPublicKey());
+ roleDesc.getKeyDescriptors().add(kd);
+
+ SAMLMetadataKeyAgreementEncryptionConfiguration kaConfig = new SAMLMetadataKeyAgreementEncryptionConfiguration();
+ PBKDF2 kdf = new PBKDF2();
+ kdf.initialize();
+ kaConfig.setParameters(Set.of(kdf));
+ encConfig.setKeyAgreementConfigurations(Map.of("EC", kaConfig));
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128, null, EncryptionConstants.ALGO_ID_KEYDERIVATION_PBKDF2);
+ }
+
+ @Test
+ public void roundtripWithKeyPlacementPeer() throws Exception {
+ KeyDescriptor kd = buildKeyDescriptor(recipientCredKeyName, UsageType.ENCRYPTION, recipientCredPublic.getPublicKey());
+ kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM));
+ kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYWRAP_AES256));
+ roleDesc.getKeyDescriptors().add(kd);
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM, EncryptionConstants.ALGO_ID_KEYWRAP_AES256, KeyPlacement.PEER);
+ }
+
+
+
+ //
+ // Helpers
+ //
+
+ private void testRoundtrip(String expectedDataAlgo, String expectedKEKAlgo, Encrypter.KeyPlacement keyPlacement) throws Exception {
+ testRoundtrip(expectedDataAlgo, expectedKEKAlgo, null, keyPlacement);
+ }
+
+ private void testRoundtrip(String expectedDataAlgo, String expectedKEKAlgo) throws Exception {
+ testRoundtrip(expectedDataAlgo, expectedKEKAlgo, null, KeyPlacement.INLINE);
+ }
+
+ private void testRoundtrip(String expectedDataAlgo, String expectedKEKAlgo, String expectedKDFAlgo) throws Exception {
+ testRoundtrip(expectedDataAlgo, expectedKEKAlgo, expectedKEKAlgo, KeyPlacement.INLINE);
+ }
+
+ private void testRoundtrip(String expectedDataAlgo, String expectedKEKAlgo, String expectedKDFAlgo, Encrypter.KeyPlacement keyPlacement) throws Exception {
+ // Encrypt
+ Assertion assertionOrig = (Assertion) unmarshallElement(targetFile);
+
+ EncryptionParameters encParams = encParamsResolver.resolveSingle(encCriteria);
+ Assert.assertNotNull(encParams);
+
+ DataEncryptionParameters dataEncParams = new DataEncryptionParameters(encParams);
+ List<KeyEncryptionParameters> kekParams = encParams.getKeyTransportEncryptionCredential() != null ?
+ List.of(new KeyEncryptionParameters(encParams, null)) : Collections.emptyList();
+
+ encrypter = new Encrypter(dataEncParams, kekParams);
+ encrypter.setKeyPlacement(keyPlacement);
+
+ EncryptedAssertion encryptedAssertionOrig = encrypter.encrypt(assertionOrig);
+ Assert.assertNotNull(encryptedAssertionOrig);
+ Assert.assertNotNull(encryptedAssertionOrig.getEncryptedData().getKeyInfo());
+
+ if (expectedDataAlgo != null) {
+ Assert.assertEquals(encryptedAssertionOrig.getEncryptedData().getEncryptionMethod().getAlgorithm(), expectedDataAlgo);
+ }
+
+ EncryptedKey encryptedKey = null;
+ switch(keyPlacement) {
+ case INLINE:
+ encryptedKey = !encryptedAssertionOrig.getEncryptedData().getKeyInfo().getEncryptedKeys().isEmpty()
+ ? encryptedAssertionOrig.getEncryptedData().getKeyInfo().getEncryptedKeys().get(0) : null;
+ break;
+ case PEER:
+ encryptedKey = !encryptedAssertionOrig.getEncryptedKeys().isEmpty()
+ ? encryptedAssertionOrig.getEncryptedKeys().get(0) : null;
+ break;
+ };
+
+ if (expectedKEKAlgo != null) {
+ Assert.assertNotNull(encryptedKey);
+ Assert.assertEquals(encryptedKey.getEncryptionMethod().getAlgorithm(), expectedKEKAlgo);
+ }
+
+ if (expectedKDFAlgo != null) {
+ KeyDerivationMethod kdm = null;
+ if (encryptedKey != null) {
+ kdm = (KeyDerivationMethod) encryptedKey.getKeyInfo().getAgreementMethods().get(0).getUnknownXMLObjects(KeyDerivationMethod.DEFAULT_ELEMENT_NAME).get(0);
+ } else {
+ kdm = (KeyDerivationMethod) encryptedAssertionOrig.getEncryptedData().getKeyInfo().getAgreementMethods().get(0).getUnknownXMLObjects(KeyDerivationMethod.DEFAULT_ELEMENT_NAME).get(0);
+ }
+ Assert.assertNotNull(kdm);
+ Assert.assertEquals(kdm.getAlgorithm(), expectedKDFAlgo);
+ }
+
+ // Serialize out and back in
+ Element domEncrypted = XMLObjectSupport.marshall(encryptedAssertionOrig);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ SerializeSupport.writeNode(domEncrypted, baos);
+ baos.flush();
+ byte[] bytesEncrypted = baos.toByteArray();
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytesEncrypted);
+ EncryptedAssertion encryptedAssertion = (EncryptedAssertion) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(), bais);
+ Assert.assertNotNull(encryptedAssertion);
+
+ // Decrypt
+ DecryptionParameters decryptParams = decryptParamsResolver.resolveSingle(decryptCriteria);
+
+ Decrypter decrypter = new Decrypter(decryptParams);
+
+ Assertion decryptedAssertion = decrypter.decrypt(encryptedAssertion);
+ Assert.assertNotNull(decryptedAssertion);
+
+ assertXMLEquals(assertionOrig.getDOM().getOwnerDocument(), decryptedAssertion);
+ }
+
+ private RoleDescriptor buildRoleDescriptorSkeleton() {
+ EntityDescriptor entityDesc = buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
+ entityDesc.setEntityID(targetEntityID);
+
+ SPSSODescriptor spSSODesc = buildXMLObject(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+ spSSODesc.setParent(entityDesc);
+
+ return spSSODesc;
+ }
+
+ private KeyDescriptor buildKeyDescriptor(String keyName, UsageType use, Object ... contentItems) {
+ KeyDescriptor keyDesc = buildXMLObject(KeyDescriptor.DEFAULT_ELEMENT_NAME);
+ KeyInfo keyInfo = buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME);
+
+ for (Object contentItem : contentItems) {
+ if (contentItem instanceof PublicKey) {
+ try {
+ KeyInfoSupport.addPublicKey(keyInfo, (PublicKey) contentItem);
+ } catch (EncodingException e) {
+ throw new RuntimeException("EncodingException adding public key to KeyInfo", e);
+ }
+ } else if (contentItem instanceof X509Certificate) {
+ try {
+ KeyInfoSupport.addCertificate(keyInfo, (X509Certificate) contentItem);
+ } catch (CertificateEncodingException e) {
+ throw new RuntimeException("CertificateEncodingException ading cert to KeyInfo", e);
+ }
+ } else {
+ throw new RuntimeException("Saw unknown KeyInfo content type: " + contentItem.getClass().getName());
+ }
+ }
+
+ if (keyName != null) {
+ KeyInfoSupport.addKeyName(keyInfo, keyName);
+ }
+
+ keyDesc.setKeyInfo(keyInfo);
+
+ if (use != null) {
+ keyDesc.setUse(use);
+ }
+
+ return keyDesc;
+ }
+
+ private EncryptionMethod buildEncryptionMethod(String algorithm) {
+ EncryptionMethod encMethod = buildXMLObject(EncryptionMethod.DEFAULT_ELEMENT_NAME);
+ encMethod.setAlgorithm(algorithm);
+ return encMethod;
+ }
+
+}
diff --git a/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementSupport.java b/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementSupport.java
index a8db46532..f42925508 100644
--- a/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementSupport.java
+++ b/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementSupport.java
@@ -25,6 +25,7 @@ import javax.annotation.Nullable;
import org.opensaml.core.config.ConfigurationService;
import org.opensaml.security.credential.Credential;
import org.opensaml.security.crypto.JCAConstants;
+import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
import org.opensaml.xmlsec.encryption.AgreementMethod;
import org.opensaml.xmlsec.encryption.EncryptedType;
import org.opensaml.xmlsec.encryption.EncryptionMethod;
@@ -101,6 +102,38 @@ public final class KeyAgreementSupport {
return et.getEncryptionMethod().getKeySize().getValue();
}
+ /**
+ * Validate the specified algorithm URI and key length for consistency.
+ *
+ * <p>
+ * If the algorithm URI does not imply a key length, then the specified key length must be non-null.
+ * If the algorithm URI does imply a key length and the optional specified key length is non-null,
+ * they must be the same length.
+ * </p>
+ *
+ *
+ * @param algorithmURI the algorithm URI
+ * @param specifiedKeyLength the optional specified key length
+ *
+ * @throws KeyAgreementException if algorithm and specified key lengths are not consistent
+ */
+ public static void validateKeyAlgorithmAndSize(@Nonnull final String algorithmURI,
+ @Nullable final Integer specifiedKeyLength) throws KeyAgreementException {
+
+ final Integer algoKeyLength = AlgorithmSupport.getKeyLength(algorithmURI);
+
+ if (algoKeyLength == null && specifiedKeyLength == null) {
+ throw new KeyAgreementException("Key length was not specified and key algorithm does not imply a length: "
+ + algorithmURI);
+ }
+
+ if (algoKeyLength != null && specifiedKeyLength != null && ! algoKeyLength.equals(specifiedKeyLength)) {
+ throw new KeyAgreementException(String.format("Algorithm URI '%s' key length (%d) "
+ + "does not match specified (%d)", algorithmURI, algoKeyLength, specifiedKeyLength));
+ }
+
+ }
+
/**
* Evaluate whether the specified credential contains a public key which supports key agreement.
*
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractDerivationKeyAgreementProcessor.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractDerivationKeyAgreementProcessor.java
index 81a6f667c..94bfcfde4 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractDerivationKeyAgreementProcessor.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/AbstractDerivationKeyAgreementProcessor.java
@@ -24,6 +24,7 @@ import javax.crypto.SecretKey;
import org.opensaml.xmlsec.agreement.KeyAgreementException;
import org.opensaml.xmlsec.agreement.KeyAgreementParameters;
import org.opensaml.xmlsec.agreement.KeyAgreementProcessor;
+import org.opensaml.xmlsec.agreement.KeyAgreementSupport;
import org.opensaml.xmlsec.derivation.KeyDerivation;
import org.opensaml.xmlsec.derivation.KeyDerivationException;
@@ -48,6 +49,8 @@ public abstract class AbstractDerivationKeyAgreementProcessor extends AbstractKe
final Integer keySize = parameters.contains(KeySize.class) ? parameters.get(KeySize.class).getSize() : null;
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(keyAlgorithm, keySize);
+
try {
return keyDerivation.derive(secret, keyAlgorithm, keySize);
} catch (final KeyDerivationException e) {
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java
index 4b9dc0e3d..0a909e659 100644
--- a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/ECDHKeyAgreementProcessorTest.java
@@ -177,6 +177,20 @@ public class ECDHKeyAgreementProcessorTest extends OpenSAMLInitBaseTestCase {
params);
}
+ @Test(expectedExceptions = KeyAgreementException.class)
+ public void specifiedKeySizeMismatch() throws Exception {
+ KeyPair kp = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
+ Credential publicCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
+
+ KeyAgreementParameters params = new KeyAgreementParameters();
+ params.add(new MockKeyDerivation());
+ params.add(new KeySize(256));
+
+ processor.execute(publicCredential,
+ EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
+ params);
+ }
+
private Collection<KeyAgreementParameter> getMockParams() {
ArrayList<KeyAgreementParameter> params = new ArrayList<>();
KANonce nonce = new KANonce();
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/tests/KeyAgreementSupportTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/tests/KeyAgreementSupportTest.java
new file mode 100644
index 000000000..2dd8f270b
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/tests/KeyAgreementSupportTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.agreement.tests;
+
+import java.security.KeyPair;
+import java.security.spec.ECGenParameterSpec;
+
+import org.opensaml.core.testing.XMLObjectBaseTestCase;
+import org.opensaml.security.credential.CredentialSupport;
+import org.opensaml.security.crypto.JCAConstants;
+import org.opensaml.security.crypto.KeySupport;
+import org.opensaml.xmlsec.agreement.KeyAgreementException;
+import org.opensaml.xmlsec.agreement.KeyAgreementSupport;
+import org.opensaml.xmlsec.agreement.impl.ECDHKeyAgreementProcessor;
+import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
+import org.opensaml.xmlsec.encryption.AgreementMethod;
+import org.opensaml.xmlsec.encryption.EncryptedData;
+import org.opensaml.xmlsec.encryption.EncryptionMethod;
+import org.opensaml.xmlsec.encryption.KeySize;
+import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
+import org.opensaml.xmlsec.signature.KeyInfo;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ *
+ */
+public class KeyAgreementSupportTest extends XMLObjectBaseTestCase {
+
+ @Test
+ public void getGlobalProcessorRegistry() throws Exception {
+ Assert.assertNotNull(KeyAgreementSupport.getGlobalProcessorRegistry());
+ }
+
+ @Test
+ public void getProcessor() throws Exception {
+ Assert.assertNotNull(KeyAgreementSupport.getProcessor(EncryptionConstants.ALGO_ID_KEYAGREEMENT_ECDH_ES));
+ Assert.assertTrue(ECDHKeyAgreementProcessor.class.isInstance(
+ KeyAgreementSupport.getProcessor(EncryptionConstants.ALGO_ID_KEYAGREEMENT_ECDH_ES)));
+ }
+
+ @Test
+ public void getExplicitKeySize() throws Exception {
+ AgreementMethod agreementMethod = buildXMLObject(AgreementMethod.DEFAULT_ELEMENT_NAME);
+ Assert.assertNull(KeyAgreementSupport.getExplicitKeySize(agreementMethod));
+
+ KeyInfo keyInfo = buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME);
+ keyInfo.getAgreementMethods().add(agreementMethod);
+ Assert.assertNull(KeyAgreementSupport.getExplicitKeySize(agreementMethod));
+
+ EncryptedData encryptedData = buildXMLObject(EncryptedData.DEFAULT_ELEMENT_NAME);
+ encryptedData.setKeyInfo(keyInfo);
+ Assert.assertNull(KeyAgreementSupport.getExplicitKeySize(agreementMethod));
+
+ EncryptionMethod encryptionMethod = buildXMLObject(EncryptionMethod.DEFAULT_ELEMENT_NAME);
+ encryptedData.setEncryptionMethod(encryptionMethod);
+ Assert.assertNull(KeyAgreementSupport.getExplicitKeySize(agreementMethod));
+
+ KeySize keySize = buildXMLObject(KeySize.DEFAULT_ELEMENT_NAME);
+ keySize.setValue(128);
+ encryptionMethod.setKeySize(keySize);
+ Assert.assertEquals(KeyAgreementSupport.getExplicitKeySize(agreementMethod), Integer.valueOf(128));
+ }
+
+ @Test
+ public void supportsKeyAgreement() throws Exception {
+ KeyPair ecKeyPair = KeySupport.generateKeyPair(JCAConstants.KEY_ALGO_EC, new ECGenParameterSpec("secp256r1"), null);
+ Assert.assertTrue(KeyAgreementSupport.supportsKeyAgreement(
+ CredentialSupport.getSimpleCredential(ecKeyPair.getPublic(), null)));
+
+ Assert.assertFalse(KeyAgreementSupport.supportsKeyAgreement(
+ AlgorithmSupport.generateKeyPairAndCredential(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP11, 2048, false)));
+ Assert.assertFalse(KeyAgreementSupport.supportsKeyAgreement(
+ AlgorithmSupport.generateKeyPairAndCredential(SignatureConstants.ALGO_ID_SIGNATURE_DSA_SHA256, 1024, false)));
+ }
+
+ @Test
+ public void validateKeyAlgorithmAndSize() throws Exception {
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM, null);
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM, 128);
+
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES, null);
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES, 192);
+
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(EncryptionConstants.ALGO_ID_KEYWRAP_AES128, null);
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(EncryptionConstants.ALGO_ID_KEYWRAP_AES128, 128);
+
+ // Non-length algorithm with non-null specified length should succeed
+ KeyAgreementSupport.validateKeyAlgorithmAndSize("SomeAlgo", 128);
+
+ try {
+ KeyAgreementSupport.validateKeyAlgorithmAndSize(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128, 256);
+ Assert.fail("Should have failed mismatched specified length");
+ } catch (KeyAgreementException e) {
+ // expected
+ }
+
+ try {
+ KeyAgreementSupport.validateKeyAlgorithmAndSize("SomeAlgo", null);
+ Assert.fail("Should have failed non-length URI and null specified length");
+ } catch (KeyAgreementException e) {
+ // expected
+ }
+ }
+
+}
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/encryption/support/tests/ECDHTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/encryption/support/tests/ECDHTest.java
new file mode 100644
index 000000000..f102eeafd
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/encryption/support/tests/ECDHTest.java
@@ -0,0 +1,237 @@
+/*
+ * 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.encryption.support.tests;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.security.KeyPair;
+import java.security.spec.ECGenParameterSpec;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opensaml.core.config.ConfigurationService;
+import org.opensaml.core.testing.XMLObjectBaseTestCase;
+import org.opensaml.core.xml.XMLObject;
+import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.security.credential.BasicCredential;
+import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.impl.CollectionCredentialResolver;
+import org.opensaml.security.crypto.KeySupport;
+import org.opensaml.xmlsec.DecryptionConfiguration;
+import org.opensaml.xmlsec.DecryptionParameters;
+import org.opensaml.xmlsec.DecryptionParametersResolver;
+import org.opensaml.xmlsec.EncryptionConfiguration;
+import org.opensaml.xmlsec.EncryptionParameters;
+import org.opensaml.xmlsec.EncryptionParametersResolver;
+import org.opensaml.xmlsec.criterion.DecryptionConfigurationCriterion;
+import org.opensaml.xmlsec.criterion.EncryptionConfigurationCriterion;
+import org.opensaml.xmlsec.derivation.impl.PBKDF2;
+import org.opensaml.xmlsec.encryption.EncryptedData;
+import org.opensaml.xmlsec.encryption.KeyDerivationMethod;
+import org.opensaml.xmlsec.encryption.support.DataEncryptionParameters;
+import org.opensaml.xmlsec.encryption.support.Decrypter;
+import org.opensaml.xmlsec.encryption.support.Encrypter;
+import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
+import org.opensaml.xmlsec.encryption.support.KeyAgreementEncryptionConfiguration;
+import org.opensaml.xmlsec.encryption.support.KeyEncryptionParameters;
+import org.opensaml.xmlsec.impl.BasicDecryptionConfiguration;
+import org.opensaml.xmlsec.impl.BasicDecryptionParametersResolver;
+import org.opensaml.xmlsec.impl.BasicEncryptionConfiguration;
+import org.opensaml.xmlsec.impl.BasicEncryptionParametersResolver;
+import org.opensaml.xmlsec.keyinfo.impl.KeyInfoProvider;
+import org.opensaml.xmlsec.keyinfo.impl.LocalKeyInfoCredentialResolver;
+import org.opensaml.xmlsec.keyinfo.impl.provider.AgreementMethodKeyInfoProvider;
+import org.opensaml.xmlsec.mock.SignableSimpleXMLObject;
+import org.opensaml.xmlsec.testing.XMLSecurityTestingSupport;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.w3c.dom.Element;
+
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.xml.SerializeSupport;
+
+/**
+ *
+ */
+public class ECDHTest extends XMLObjectBaseTestCase {
+
+ private String targetFile;
+
+ private Credential recipientCredPrivate;
+ private Credential recipientCredPublic;
+ private CollectionCredentialResolver localCredentialResolver;
+ private LocalKeyInfoCredentialResolver localKeyInfoResolver;
+
+ private Encrypter encrypter;
+ private EncryptionParametersResolver encParamsResolver;
+ private CriteriaSet encCriteria;
+ private BasicEncryptionConfiguration encConfig;
+
+ private DecryptionParametersResolver decryptParamsResolver;
+ private CriteriaSet decryptCriteria;
+ private BasicDecryptionConfiguration decryptConfig;
+
+ @BeforeClass
+ public void beforeClass() throws Exception {
+ targetFile = "/org/opensaml/xmlsec/encryption/support/SimpleEncryptionTest.xml";
+
+ KeyPair kp = KeySupport.generateKeyPair("EC", new ECGenParameterSpec("secp256r1"), null);
+ recipientCredPrivate = new BasicCredential(kp.getPublic(), kp.getPrivate());
+ recipientCredPublic = new BasicCredential(kp.getPublic());
+
+ encrypter = new Encrypter();
+ encParamsResolver = new BasicEncryptionParametersResolver();
+
+ decryptParamsResolver = new BasicDecryptionParametersResolver();
+
+ localCredentialResolver = new CollectionCredentialResolver(Set.of(recipientCredPrivate));
+
+ List<KeyInfoProvider> keyInfoProviders = new ArrayList<>(XMLSecurityTestingSupport.getBasicInlineKeyInfoProviders());
+ keyInfoProviders.add(new AgreementMethodKeyInfoProvider());
+ localKeyInfoResolver = new LocalKeyInfoCredentialResolver(keyInfoProviders, localCredentialResolver);
+ }
+
+ @BeforeMethod
+ public void beforeMethod() throws Exception {
+ encConfig = new BasicEncryptionConfiguration();
+ encCriteria = new CriteriaSet(new EncryptionConfigurationCriterion(encConfig,
+ ConfigurationService.get(EncryptionConfiguration.class)));
+
+ decryptConfig = new BasicDecryptionConfiguration();
+ decryptConfig.setDataKeyInfoCredentialResolver(localKeyInfoResolver);
+ decryptConfig.setKEKKeyInfoCredentialResolver(localKeyInfoResolver);
+
+ decryptCriteria = new CriteriaSet(new DecryptionConfigurationCriterion(decryptConfig,
+ ConfigurationService.get(DecryptionConfiguration.class)));
+ }
+
+ @Test
+ public void roundtripDirectDataEncryption() throws Exception {
+ encConfig.setDataEncryptionCredentials(List.of(recipientCredPublic));
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128, null);
+ }
+
+ @Test
+ public void roundtripDirectDataEncryptionWithAlgorithmOverrides() throws Exception {
+ encConfig.setDataEncryptionCredentials(List.of(recipientCredPublic));
+ encConfig.setDataEncryptionAlgorithms(List.of(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM));
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM, null);
+ }
+
+ @Test
+ public void roundtripWithKeyWrap() throws Exception {
+ encConfig.setKeyTransportEncryptionCredentials(List.of(recipientCredPublic));
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128, EncryptionConstants.ALGO_ID_KEYWRAP_AES128);
+ }
+
+ @Test
+ public void roundtripWithKeyWrapAndAlgorithmOverrides() throws Exception {
+ encConfig.setKeyTransportEncryptionCredentials(List.of(recipientCredPublic));
+ encConfig.setKeyTransportEncryptionAlgorithms(List.of(EncryptionConstants.ALGO_ID_KEYWRAP_AES256));
+ encConfig.setDataEncryptionAlgorithms(List.of(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM));
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM, EncryptionConstants.ALGO_ID_KEYWRAP_AES256);
+ }
+
+ @Test
+ public void roundtripWithPBKDF2() throws Exception {
+ encConfig.setDataEncryptionCredentials(List.of(recipientCredPublic));
+
+ KeyAgreementEncryptionConfiguration kaConfig = new KeyAgreementEncryptionConfiguration();
+ PBKDF2 kdf = new PBKDF2();
+ kdf.initialize();
+ kaConfig.setParameters(Set.of(kdf));
+ encConfig.setKeyAgreementConfigurations(Map.of("EC", kaConfig));
+
+ testRoundtrip(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128, null, EncryptionConstants.ALGO_ID_KEYDERIVATION_PBKDF2);
+ }
+
+ private void testRoundtrip(String expectedDataAlgo, String expectedKEKAlgo) throws Exception {
+ testRoundtrip(expectedDataAlgo, expectedKEKAlgo, null);
+ }
+
+ private void testRoundtrip(String expectedDataAlgo, String expectedKEKAlgo, String expectedKDFAlgo) throws Exception {
+ // Encrypt
+ SignableSimpleXMLObject sxoOrig = (SignableSimpleXMLObject) unmarshallElement(targetFile);
+
+ EncryptionParameters encParams = encParamsResolver.resolveSingle(encCriteria);
+ Assert.assertNotNull(encParams);
+
+ DataEncryptionParameters dataEncParams = new DataEncryptionParameters(encParams);
+ List<KeyEncryptionParameters> kekParams = encParams.getKeyTransportEncryptionCredential() != null ?
+ List.of(new KeyEncryptionParameters(encParams, null)) : Collections.emptyList();
+
+ EncryptedData encryptedDataOrig = encrypter.encryptElement(sxoOrig, dataEncParams, kekParams);
+ Assert.assertNotNull(encryptedDataOrig);
+ Assert.assertNotNull(encryptedDataOrig.getKeyInfo());
+
+ if (expectedDataAlgo != null) {
+ Assert.assertEquals(encryptedDataOrig.getEncryptionMethod().getAlgorithm(), expectedDataAlgo);
+ }
+
+ if (expectedKEKAlgo != null) {
+ Assert.assertNotNull(encryptedDataOrig.getKeyInfo().getEncryptedKeys().get(0));
+ Assert.assertEquals(encryptedDataOrig.getKeyInfo().getEncryptedKeys().get(0).getEncryptionMethod().getAlgorithm(), expectedKEKAlgo);
+ }
+
+ if (expectedKDFAlgo != null) {
+ KeyDerivationMethod kdm = null;
+ if (!encryptedDataOrig.getKeyInfo().getEncryptedKeys().isEmpty()) {
+ kdm = (KeyDerivationMethod) encryptedDataOrig.getKeyInfo().getEncryptedKeys().get(0).getKeyInfo().getAgreementMethods().get(0).getUnknownXMLObjects(KeyDerivationMethod.DEFAULT_ELEMENT_NAME).get(0);
+ } else {
+ kdm = (KeyDerivationMethod) encryptedDataOrig.getKeyInfo().getAgreementMethods().get(0).getUnknownXMLObjects(KeyDerivationMethod.DEFAULT_ELEMENT_NAME).get(0);
+ }
+ Assert.assertNotNull(kdm);
+ Assert.assertEquals(kdm.getAlgorithm(), expectedKDFAlgo);
+ }
+
+ // Serialize out and back in
+ Element domEncrypted = XMLObjectSupport.marshall(encryptedDataOrig);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ SerializeSupport.writeNode(domEncrypted, baos);
+ baos.flush();
+ byte[] bytesEncrypted = baos.toByteArray();
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytesEncrypted);
+ EncryptedData encryptedData = (EncryptedData) XMLObjectSupport.unmarshallFromInputStream(
+ XMLObjectProviderRegistrySupport.getParserPool(), bais);
+ Assert.assertNotNull(encryptedData);
+
+ // Decrypt
+ DecryptionParameters decryptParams = decryptParamsResolver.resolveSingle(decryptCriteria);
+
+ Decrypter decrypter = new Decrypter(decryptParams);
+
+ XMLObject decryptedXMLObject = decrypter.decryptData(encryptedData);
+ Assert.assertNotNull(decryptedXMLObject);
+ Assert.assertTrue(decryptedXMLObject instanceof SignableSimpleXMLObject);
+
+ assertXMLEquals(sxoOrig.getDOM().getOwnerDocument(), decryptedXMLObject);
+ }
+
+}
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/testing/XMLSecurityTestingSupport.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/testing/XMLSecurityTestingSupport.java
index 20f1ae487..1ae4500a7 100644
--- a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/testing/XMLSecurityTestingSupport.java
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/testing/XMLSecurityTestingSupport.java
@@ -42,12 +42,16 @@ public final class XMLSecurityTestingSupport {
* @return a new KeyInfoCredentialResolver instance
*/
public static KeyInfoCredentialResolver buildBasicInlineKeyInfoResolver() {
+ return new BasicProviderKeyInfoCredentialResolver(getBasicInlineKeyInfoProviders());
+ }
+
+ public static List<KeyInfoProvider> getBasicInlineKeyInfoProviders() {
List<KeyInfoProvider> providers = new ArrayList<>();
providers.add( new RSAKeyValueProvider() );
providers.add( new DSAKeyValueProvider() );
providers.add( new ECKeyValueProvider() );
providers.add( new InlineX509DataProvider() );
- return new BasicProviderKeyInfoCredentialResolver(providers);
+ return providers;
}
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list