[java-opensaml] 10/19: Config-oriented params should be initializable, so can't be changed.

Brent Putman putmanb at georgetown.edu
Mon Mar 1 05:56:47 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=da57d9527b0c2772f9f29d29d7e83a6d43b2eb4e

commit da57d9527b0c2772f9f29d29d7e83a6d43b2eb4e
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Sun Dec 27 19:31:08 2020 -0500

    Config-oriented params should be initializable, so can't be changed.
---
 .../xmlsec/agreement/KeyAgreementParameters.java   | 15 ++++
 .../xmlsec/agreement/impl/DigestMethod.java        | 88 ++++++++++++++++++++++
 .../opensaml/xmlsec/agreement/impl/KANonce.java    | 38 ++++++----
 .../opensaml/xmlsec/derivation/impl/ConcatKDF.java |  4 +-
 .../opensaml/xmlsec/derivation/impl/PBKDF2.java    |  4 +-
 .../xmlsec/agreement/impl/DigestMethodTest.java    | 66 ++++++++++++++++
 .../impl/ECDHKeyAgreementProcessorTest.java        | 22 ++++--
 .../xmlsec/agreement/impl/KANonceTest.java         | 32 +++++---
 8 files changed, 240 insertions(+), 29 deletions(-)

diff --git a/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementParameters.java b/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementParameters.java
index 060610a13..caa1123d5 100644
--- a/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementParameters.java
+++ b/opensaml-xmlsec-api/src/main/java/org/opensaml/xmlsec/agreement/KeyAgreementParameters.java
@@ -22,6 +22,8 @@ import java.util.Collection;
 import javax.annotation.Nonnull;
 
 import net.shibboleth.utilities.java.support.collection.ClassIndexedSet;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.InitializableComponent;
 
 /**
  * Specialized collection type for holding sets of parameters to key agreement operations.
@@ -62,5 +64,18 @@ public class KeyAgreementParameters extends ClassIndexedSet<KeyAgreementParamete
             }
         }
     }
+    
+    /**
+     * A convenience method for initializing all parameters which are initializable.
+     * 
+     * @throws ComponentInitializationException 
+     */
+    public void initializeAll() throws ComponentInitializationException {
+        for (final KeyAgreementParameter param : this) {
+            if (InitializableComponent.class.isInstance(param)) {
+               InitializableComponent.class.cast(param).initialize();
+            }
+        }
+    }
 
 }
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/DigestMethod.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/DigestMethod.java
new file mode 100644
index 000000000..d5a7334e6
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/DigestMethod.java
@@ -0,0 +1,88 @@
+/*
+ * 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.impl;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.core.xml.XMLObject;
+import org.opensaml.core.xml.util.XMLObjectSupport;
+import org.opensaml.xmlsec.agreement.CloneableKeyAgreementParameter;
+import org.opensaml.xmlsec.agreement.XMLExpressableKeyAgreementParameter;
+
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+/**
+ * Key agreement parameter to support use of {@link org.opensaml.xmlsec.signature.DigestMethod} values.
+ */
+public class DigestMethod extends AbstractInitializableComponent
+    implements XMLExpressableKeyAgreementParameter, CloneableKeyAgreementParameter {
+    
+    /** Algorithm URI. */
+    @Nullable private String algorithm;
+    
+    /** {@inheritDoc} */
+    protected void doInitialize() throws ComponentInitializationException {
+        if (algorithm == null) {
+            throw new ComponentInitializationException("DigestMethod algorithm was null");
+        }
+    }
+
+    /**
+     * Get the algorithm URI.
+     * 
+     * @return the algorithm URI
+     */
+    @Nullable public String getAlgorithm() {
+        return algorithm;
+    }
+    
+    /**
+     * Set the algorithm URI.
+     * 
+     * @param newAlgorithm the algorithm URI
+     */
+    public void setAlgorithm(@Nullable final String newAlgorithm) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        algorithm = StringSupport.trimOrNull(newAlgorithm);
+    }
+
+    /** {@inheritDoc} */
+    public XMLObject buildXMLObject() {
+        final org.opensaml.xmlsec.signature.DigestMethod digestMethod =
+                (org.opensaml.xmlsec.signature.DigestMethod) XMLObjectSupport
+                    .buildXMLObject(org.opensaml.xmlsec.signature.DigestMethod.DEFAULT_ELEMENT_NAME);
+        
+        digestMethod.setAlgorithm(getAlgorithm());
+        return digestMethod;
+    }
+    
+    /** {@inheritDoc} */
+    public DigestMethod clone() {
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        try {
+            return (DigestMethod ) super.clone();
+        } catch (final CloneNotSupportedException e) {
+            // We know we are, so this will never happen
+            return null;
+        }
+    }
+
+}
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/KANonce.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/KANonce.java
index 97943ae63..838efbb47 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/KANonce.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/agreement/impl/KANonce.java
@@ -17,40 +17,51 @@
 
 package org.opensaml.xmlsec.agreement.impl;
 
-import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.util.XMLObjectSupport;
 import org.opensaml.xmlsec.agreement.CloneableKeyAgreementParameter;
 import org.opensaml.xmlsec.agreement.XMLExpressableKeyAgreementParameter;
 
-import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 
 /**
  * Key agreement parameter to support use of {@link org.opensaml.xmlsec.encryption.KANonce} values.
  */
-public class KANonce implements XMLExpressableKeyAgreementParameter, CloneableKeyAgreementParameter {
+public class KANonce extends AbstractInitializableComponent
+    implements XMLExpressableKeyAgreementParameter, CloneableKeyAgreementParameter {
     
     /** Base64-encoded nonce value. */
-    @Nonnull private String value;
+    @Nullable private String value;
+    
+    /** {@inheritDoc} */
+    protected void doInitialize() throws ComponentInitializationException {
+        if (value == null) {
+            throw new ComponentInitializationException("KANonce value was null");
+        }
+    }
 
     /**
-     * Constructor.
-     *
-     * @param newValue the new nonce value
+     * Get the Base64-encoded nonce value.
+     * 
+     * @return the nonce value
      */
-    public KANonce(@Nonnull final String newValue) {
-        value = Constraint.isNotNull(StringSupport.trimOrNull(newValue), "Nonce value was null or empty");
+    @Nullable public String getValue() {
+        return value;
     }
     
     /**
-     * Get the Base64-encoded nonce value.
+     * Set the Base64-encoded nonce value.
      * 
-     * @return the nonce value
+     * @param newValue the nonce value
      */
-    @Nonnull public String getValue() {
-        return value;
+    public void setValue(@Nullable final String newValue) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        value = StringSupport.trimOrNull(newValue);
     }
 
     /** {@inheritDoc} */
@@ -65,6 +76,7 @@ public class KANonce implements XMLExpressableKeyAgreementParameter, CloneableKe
     
     /** {@inheritDoc} */
     public KANonce clone() {
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
         try {
             return (KANonce ) super.clone();
         } catch (final CloneNotSupportedException e) {
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/ConcatKDF.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/ConcatKDF.java
index fb513af0d..bac1f2660 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/ConcatKDF.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/ConcatKDF.java
@@ -29,10 +29,12 @@ import org.opensaml.xmlsec.encryption.ConcatKDFParams;
 import org.opensaml.xmlsec.encryption.KeyDerivationMethod;
 import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
 
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+
 /**
  * Implementation of ConcatKDF key derivation as defined in XML Encryption 1.1.
  */
-public class ConcatKDF implements KeyDerivation, CloneableKeyAgreementParameter {
+public class ConcatKDF extends AbstractInitializableComponent implements KeyDerivation, CloneableKeyAgreementParameter {
 
     /** {@inheritDoc} */
     public String getAlgorithm() {
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/PBKDF2.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/PBKDF2.java
index 1691fdd5f..be3dc09e8 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/PBKDF2.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/derivation/impl/PBKDF2.java
@@ -29,10 +29,12 @@ import org.opensaml.xmlsec.encryption.ConcatKDFParams;
 import org.opensaml.xmlsec.encryption.KeyDerivationMethod;
 import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
 
+import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+
 /**
  * Implementation of PBKDF2 key derivation as defined in XML Encryption 1.1.
  */
-public class PBKDF2 implements KeyDerivation, CloneableKeyAgreementParameter {
+public class PBKDF2 extends AbstractInitializableComponent implements KeyDerivation, CloneableKeyAgreementParameter {
 
     /** {@inheritDoc} */
     public String getAlgorithm() {
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/DigestMethodTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/DigestMethodTest.java
new file mode 100644
index 000000000..172f53d45
--- /dev/null
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/DigestMethodTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.impl;
+
+import org.opensaml.core.testing.OpenSAMLInitBaseTestCase;
+import org.opensaml.core.xml.XMLObject;
+import org.opensaml.xmlsec.signature.support.SignatureConstants;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.UnmodifiableComponentException;
+
+/**
+ *
+ */
+public class DigestMethodTest extends OpenSAMLInitBaseTestCase  {
+    
+    @Test
+    public void basic() throws ComponentInitializationException {
+        DigestMethod digest = new DigestMethod();
+        digest.setAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA256);
+        digest.initialize();
+        Assert.assertEquals(digest.getAlgorithm(), SignatureConstants.ALGO_ID_DIGEST_SHA256);
+        
+        try {
+            digest.setAlgorithm("foo");
+            Assert.fail("Modify of initialzied component should have failed");
+        } catch (UnmodifiableComponentException e) {
+            // expected
+        }
+        
+        DigestMethod cloned  = digest.clone();
+        Assert.assertTrue(cloned.isInitialized());
+        Assert.assertEquals(cloned.getAlgorithm(), SignatureConstants.ALGO_ID_DIGEST_SHA256);
+        
+        XMLObject xmlObject = digest.buildXMLObject();
+        Assert.assertNotNull(xmlObject);
+        Assert.assertTrue(org.opensaml.xmlsec.signature.DigestMethod.class.isInstance(xmlObject));
+        org.opensaml.xmlsec.signature.DigestMethod xmlDigest = org.opensaml.xmlsec.signature.DigestMethod.class.cast(xmlObject);
+        Assert.assertEquals(xmlDigest.getAlgorithm(), SignatureConstants.ALGO_ID_DIGEST_SHA256);
+        
+    }
+    
+    @Test(expectedExceptions = ComponentInitializationException.class)
+    public void missingValue() throws ComponentInitializationException {
+        DigestMethod digest = new DigestMethod();
+        digest.initialize();
+    }
+    
+}
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 da02d01ff..4b9dc0e3d 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
@@ -19,6 +19,8 @@ package org.opensaml.xmlsec.agreement.impl;
 
 import java.security.KeyPair;
 import java.security.spec.ECGenParameterSpec;
+import java.util.ArrayList;
+import java.util.Collection;
 
 import org.opensaml.core.testing.OpenSAMLInitBaseTestCase;
 import org.opensaml.security.credential.Credential;
@@ -27,6 +29,7 @@ import org.opensaml.security.crypto.JCAConstants;
 import org.opensaml.security.crypto.KeySupport;
 import org.opensaml.xmlsec.agreement.KeyAgreementCredential;
 import org.opensaml.xmlsec.agreement.KeyAgreementException;
+import org.opensaml.xmlsec.agreement.KeyAgreementParameter;
 import org.opensaml.xmlsec.agreement.KeyAgreementParameters;
 import org.opensaml.xmlsec.derivation.impl.MockKeyDerivation;
 import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
@@ -53,7 +56,7 @@ public class ECDHKeyAgreementProcessorTest extends OpenSAMLInitBaseTestCase {
         
         KeyAgreementParameters params = new KeyAgreementParameters();
         params.add(new MockKeyDerivation()); 
-        params.add(new KANonce("someBase64")); 
+        params.addAll(getMockParams());
         
         KeyAgreementCredential keyAgreementCredential = processor.execute(recipientCredential,
                 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
@@ -98,7 +101,7 @@ public class ECDHKeyAgreementProcessorTest extends OpenSAMLInitBaseTestCase {
         KeyAgreementParameters params = new KeyAgreementParameters();
         params.add(new PrivateCredential(recipientCredential));
         params.add(new MockKeyDerivation()); 
-        params.add(new KANonce("someBase64")); 
+        params.addAll(getMockParams());
         
         KeyAgreementCredential keyAgreementCredential = processor.execute(originatorCredential,
                 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
@@ -140,7 +143,7 @@ public class ECDHKeyAgreementProcessorTest extends OpenSAMLInitBaseTestCase {
         
         KeyAgreementParameters params = new KeyAgreementParameters();
         params.add(new MockKeyDerivation()); 
-        params.add(new KANonce("someBase64")); 
+        params.addAll(getMockParams());
         
         processor.execute(publicCredential,
                 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
@@ -154,7 +157,7 @@ public class ECDHKeyAgreementProcessorTest extends OpenSAMLInitBaseTestCase {
         
         KeyAgreementParameters params = new KeyAgreementParameters();
         params.add(new MockKeyDerivation()); 
-        params.add(new KANonce("someBase64")); 
+        params.addAll(getMockParams());
         
         processor.execute(publicCredential,
                 "urn:test:InvalidBlockEncryption",
@@ -167,11 +170,20 @@ public class ECDHKeyAgreementProcessorTest extends OpenSAMLInitBaseTestCase {
         Credential publicCredential = CredentialSupport.getSimpleCredential(kp.getPublic(), null);
         
         KeyAgreementParameters params = new KeyAgreementParameters();
-        params.add(new KANonce("someBase64")); 
+        params.addAll(getMockParams());
         
         processor.execute(publicCredential,
                 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128,
                 params);
     }
+    
+    private Collection<KeyAgreementParameter> getMockParams() {
+        ArrayList<KeyAgreementParameter> params = new ArrayList<>();
+        KANonce nonce = new KANonce();
+        nonce.setValue("someBase64");
+        params.add(nonce);
+        return params;
+    }
+    
         
 }
diff --git a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/KANonceTest.java b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/KANonceTest.java
index b2dffd23a..dfc023502 100644
--- a/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/KANonceTest.java
+++ b/opensaml-xmlsec-impl/src/test/java/org/opensaml/xmlsec/agreement/impl/KANonceTest.java
@@ -22,7 +22,8 @@ import org.opensaml.core.xml.XMLObject;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.UnmodifiableComponentException;
 
 /**
  *
@@ -30,22 +31,35 @@ import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
 public class KANonceTest extends OpenSAMLInitBaseTestCase  {
     
     @Test
-    public void basic() {
-        KANonce nonce = new KANonce("   someBase64==   ");
+    public void basic() throws ComponentInitializationException {
+        KANonce nonce = new KANonce();
+        nonce.setValue("someBase64==   ");
+        nonce.initialize();
         Assert.assertEquals(nonce.getValue(), "someBase64==");
         
+        try {
+            nonce.setValue("foo");
+            Assert.fail("Modify of initialzied component should have failed");
+        } catch (UnmodifiableComponentException e) {
+            // expected
+        }
+        
+        KANonce cloned  = nonce.clone();
+        Assert.assertTrue(cloned.isInitialized());
+        Assert.assertEquals(cloned.getValue(), "someBase64==");
+        
         XMLObject xmlObject = nonce.buildXMLObject();
         Assert.assertNotNull(xmlObject);
         Assert.assertTrue(org.opensaml.xmlsec.encryption.KANonce.class.isInstance(xmlObject));
         org.opensaml.xmlsec.encryption.KANonce xmlNonce = org.opensaml.xmlsec.encryption.KANonce.class.cast(xmlObject);
         Assert.assertEquals(xmlNonce.getValue(), "someBase64==");
         
-        try {
-            new KANonce("    ");
-            Assert.fail("KANonce accepted illegal empty value");
-        } catch (ConstraintViolationException e) {
-            // expected, do nothing
-        }
+    }
+    
+    @Test(expectedExceptions = ComponentInitializationException.class)
+    public void missingValue() throws ComponentInitializationException {
+        KANonce nonce = new KANonce();
+        nonce.initialize();
     }
     
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list