[java-opensaml] branch main updated: OSJ-439 - Add options for removal to Algorithm metadata filter

Codeberg noreply at shibboleth.net
Wed Jan 21 17:45:16 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-opensaml.

View the commit online:
https://codeberg.org/Shibboleth/java-opensaml/commit/163c8e016047ed7fbfd10f4996054392aa787be5

The following commit(s) were added to refs/heads/main by this push:
     new 163c8e016 OSJ-439 - Add options for removal to Algorithm metadata filter
163c8e016 is described below

commit 163c8e016047ed7fbfd10f4996054392aa787be5
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Jan 21 12:45:05 2026 -0500

    OSJ-439 - Add options for removal to Algorithm metadata filter
    
    https://shibboleth.atlassian.net/browse/OSJ-439
    
    Added 3 options for individual control of removal.
---
 .../resolver/filter/impl/AlgorithmFilter.java      | 156 ++++++++++++++++++---
 .../resolver/filter/impl/AlgorithmFilterTest.java  | 135 +++++++++++++++++-
 .../filter/impl/EntityDescriptorWithAlgorithms.xml |   4 +
 3 files changed, 272 insertions(+), 23 deletions(-)

diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java
index 4d7ec6b1b..563c8a5ea 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java
@@ -29,6 +29,7 @@ import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
 import org.opensaml.core.xml.io.MarshallingException;
 import org.opensaml.core.xml.io.UnmarshallingException;
+import org.opensaml.core.xml.schema.XSString;
 import org.opensaml.core.xml.util.XMLObjectSupport;
 import org.opensaml.saml.common.SAMLObjectBuilder;
 import org.opensaml.saml.ext.saml2alg.DigestMethod;
@@ -64,26 +65,73 @@ import net.shibboleth.shared.primitive.LoggerFactory;
  */
 public class AlgorithmFilter extends AbstractMetadataFilter {
 
+    /** Used as a value in place of an empty collection when removing only. */
+    @Nonnull @NotEmpty private static final String GUARD_VALUE = "_EMPTY";
+    
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AlgorithmFilter.class);
 
     /** Registry for sanity checking algorithms. */
     @Nullable private AlgorithmRegistry registry = AlgorithmSupport.getGlobalAlgorithmRegistry();
     
+    /** Flag controlling removal of existing DigestMethod extensions. */
+    private boolean removeExistingDigestMethods;
+
+    /** Flag controlling removal of existing SigningMethod extensions. */
+    private boolean removeExistingSigningMethods;
+
+    /** Flag controlling removal of existing EncryptionMethod extensions. */
+    private boolean removeExistingEncryptionMethods;
+    
     /** Rules for adding algorithms. */
     @Nonnull private Multimap<Predicate<EntityDescriptor>,XMLObject> applyMap;
     
     /** Builder for {@link Extensions}. */
     @Nonnull private final SAMLObjectBuilder<Extensions> extBuilder;
+    
+    /** Stands in for an empty collection when removing only. */
+    @Nonnull private final XSString guardObject;
 
     /** Constructor. */
     public AlgorithmFilter() {
+        guardObject = XMLObjectProviderRegistrySupport.getBuilderFactory().<XSString>ensureBuilder(
+                XSString.TYPE_NAME).buildObject(null, GUARD_VALUE, null);
+        guardObject.setValue(GUARD_VALUE);
         extBuilder = (SAMLObjectBuilder<Extensions>)
                 XMLObjectProviderRegistrySupport.getBuilderFactory().<Extensions>ensureBuilder(
                         Extensions.DEFAULT_ELEMENT_NAME);
         applyMap = ArrayListMultimap.create();
     }
     
+    /**
+     * Sets whether to remove existing DigestMethod extensions.
+     * 
+     * @param flag flag to set
+     */
+    public void setRemoveExistingDigestMethods(final boolean flag) {
+        checkSetterPreconditions();
+        removeExistingDigestMethods = flag;
+    }
+
+    /**
+     * Sets whether to remove existing SigningMethod extensions.
+     * 
+     * @param flag flag to set
+     */
+    public void setRemoveExistingSigningMethods(final boolean flag) {
+        checkSetterPreconditions();
+        removeExistingSigningMethods = flag;
+    }
+
+    /**
+     * Sets whether to remove existing EncryptionMethod extensions.
+     * 
+     * @param flag flag to set
+     */
+    public void setRemoveExistingEncryptionMethods(final boolean flag) {
+        checkSetterPreconditions();
+        removeExistingEncryptionMethods = flag;
+    }
     
 // Checkstyle: CyclomaticComplexity OFF
     /**
@@ -101,7 +149,7 @@ public class AlgorithmFilter extends AbstractMetadataFilter {
             .map(DigestMethod.class::cast)
             .map(DigestMethod::getAlgorithm)
             .distinct()
-            .forEach(uri -> checkDigestMethod(uri));
+            .forEach(this::checkDigestMethod);
 
         rules.values().stream()
             .flatMap(Collection::stream)
@@ -109,7 +157,7 @@ public class AlgorithmFilter extends AbstractMetadataFilter {
             .map(SigningMethod.class::cast)
             .map(SigningMethod::getAlgorithm)
             .distinct()
-            .forEach(uri -> checkSigningMethod(uri));
+            .forEach(this::checkSigningMethod);
 
         rules.values().stream()
             .flatMap(Collection::stream)
@@ -117,12 +165,14 @@ public class AlgorithmFilter extends AbstractMetadataFilter {
             .map(EncryptionMethod.class::cast)
             .map(EncryptionMethod::getAlgorithm)
             .distinct()
-            .forEach(uri -> checkEncryptionMethod(uri));
+            .forEach(this::checkEncryptionMethod);
 
         applyMap = ArrayListMultimap.create(rules.size(), 1);
         for (final Map.Entry<Predicate<EntityDescriptor>,Collection<XMLObject>> entry : rules.entrySet()) {
             if (entry.getKey() != null && entry.getValue() != null) {
-                applyMap.putAll(entry.getKey(), List.copyOf(entry.getValue()));
+                applyMap.putAll(entry.getKey(),
+                        entry.getValue().isEmpty() ? CollectionSupport.singletonList(guardObject)
+                                : CollectionSupport.copyToList(entry.getValue()));
             }
         }
     }
@@ -153,31 +203,43 @@ public class AlgorithmFilter extends AbstractMetadataFilter {
      * @param descriptor entity descriptor to filter
      */
     protected void filterEntityDescriptor(@Nonnull final EntityDescriptor descriptor) {
-        
+
         Set<String> existingDigests = CollectionSupport.emptySet();
         Set<String> existingSignings = CollectionSupport.emptySet();
         final Extensions exts = descriptor.getExtensions();
         if (exts != null) {
-            existingDigests = exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME)
-                    .stream()
-                    .filter(DigestMethod.class::isInstance)
-                    .map(DigestMethod.class::cast)
-                    .map(DigestMethod::getAlgorithm)
-                    .distinct()
-                    .collect(Collectors.toUnmodifiableSet());
-            existingSignings = exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME)
-                    .stream()
-                    .filter(SigningMethod.class::isInstance)
-                    .map(SigningMethod.class::cast)
-                    .map(SigningMethod::getAlgorithm)
-                    .distinct()
-                    .collect(Collectors.toUnmodifiableSet());
+            if (!removeExistingDigestMethods) {
+                existingDigests = exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME)
+                        .stream()
+                        .filter(DigestMethod.class::isInstance)
+                        .map(DigestMethod.class::cast)
+                        .map(DigestMethod::getAlgorithm)
+                        .distinct()
+                        .collect(Collectors.toUnmodifiableSet());
+            }
+            if (!removeExistingSigningMethods) {
+                existingSignings = exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME)
+                        .stream()
+                        .filter(SigningMethod.class::isInstance)
+                        .map(SigningMethod.class::cast)
+                        .map(SigningMethod::getAlgorithm)
+                        .distinct()
+                        .collect(Collectors.toUnmodifiableSet());
+            }
         }
         
         for (final Map.Entry<Predicate<EntityDescriptor>,Collection<XMLObject>> entry : applyMap.asMap().entrySet()) {
-            if (!entry.getValue().isEmpty() && entry.getKey().test(descriptor)) {
+            if (entry.getKey().test(descriptor)) {
+                
+                // Only acts if needed.
+                removeExistingMethods(descriptor);
                 
                 for (final XMLObject xmlObject : entry.getValue()) {
+                    // Check for guard object to break loop since we were only removing. 
+                    if (xmlObject instanceof XSString) {
+                        break;
+                    }
+                    
                     try {
                         if (xmlObject instanceof DigestMethod) {
                             if (existingDigests.contains(((DigestMethod) xmlObject).getAlgorithm())) {
@@ -251,6 +313,58 @@ public class AlgorithmFilter extends AbstractMetadataFilter {
         return extensions;
     }
     
+// Checkstyle: CyclomaticComplexity OFF
+    /**
+     * Performs removal of existing methods if directed.
+     * 
+     * @param descriptor descriptor to filter
+     */
+    protected void removeExistingMethods(@Nonnull final EntityDescriptor descriptor) {
+        Extensions exts = descriptor.getExtensions();
+        // Remove existing objects first (if directed).
+        if (exts != null) {
+            if (removeExistingDigestMethods) {
+                log.debug("Clearing existing entity-level DigestMethod extensions on EntityDescriptor '{}'",
+                        descriptor.getEntityID());
+                exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME).clear();
+            }
+            if (removeExistingSigningMethods) {
+                log.debug("Clearing existing entity-level SigningMethod extensions on EntityDescriptor '{}'",
+                        descriptor.getEntityID());
+                exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME).clear();
+            }
+        }
+        
+        if (removeExistingDigestMethods || removeExistingSigningMethods || removeExistingEncryptionMethods) {
+            for (final RoleDescriptor role : descriptor.getRoleDescriptors()) {
+                exts = role.getExtensions();
+                if (exts != null) {
+                    if (removeExistingDigestMethods) {
+                        log.debug("Clearing existing role-level DigestMethod extensions on EntityDescriptor '{}'",
+                                descriptor.getEntityID());
+                        exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME).clear();
+                    }
+                    if (removeExistingSigningMethods) {
+                        log.debug("Clearing existing role-level SigningMethod extensions on EntityDescriptor '{}'",
+                                descriptor.getEntityID());
+                        exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME).clear();
+                    }
+                }
+                if (removeExistingEncryptionMethods) {
+                    for (final KeyDescriptor key : role.getKeyDescriptors()) {
+                        if (key.getUse() == null || key.getUse() != UsageType.SIGNING) {
+                            log.debug(
+                                    "Clearing existing key-level EncryptionMethod extensions on EntityDescriptor '{}'",
+                                    descriptor.getEntityID());
+                            key.getEncryptionMethods().clear();
+                        }
+                    }
+                }
+            }
+        }
+    }
+ // Checkstyle: CyclomaticComplexity ON
+
     /**
      * Add {@link EncryptionMethod} extension to every {@link KeyDescriptor} found in
      * an entity.
@@ -280,7 +394,7 @@ public class AlgorithmFilter extends AbstractMetadataFilter {
                                 encryptionMethod.getAlgorithm(), descriptor.getEntityID());
                         existingMethods.add(XMLObjectSupport.cloneXMLObject(encryptionMethod));
                     } catch (final MarshallingException|UnmarshallingException e) {
-                        log.error("Error cloning XMLObject", e);
+                        log.error("Error cloning EncryptionMethod", e);
                     }
                 }
             }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java
index 00b35bbb5..62e07dbe7 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java
@@ -43,6 +43,7 @@ import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.xmlsec.encryption.MGF;
 import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
 import org.opensaml.xmlsec.signature.support.SignatureConstants;
+import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -102,7 +103,8 @@ public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predic
         final EncryptionMethod enc3 = buildXMLObject(EncryptionMethod.DEFAULT_ELEMENT_NAME);
         enc3.setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256);
 
-        final Collection<XMLObject> algs = List.of(digest1, digest2, signing1, signing2, enc1, digest3, signing3, enc2, enc3);
+        final Collection<XMLObject> algs =
+                CollectionSupport.listOf(digest1, digest2, signing1, signing2, enc1, digest3, signing3, enc2, enc3);
         
         final AlgorithmFilter filter = new AlgorithmFilter();
         filter.setRules(CollectionSupport.singletonMap(this, algs));
@@ -115,7 +117,7 @@ public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predic
         EntityIdCriterion crit = new EntityIdCriterion("https://foo.example.org/sp");
         EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(crit));
         assert entity != null;
-        final Extensions exts = entity.getExtensions();
+        Extensions exts = entity.getExtensions();
         assert exts != null;
         
         List<XMLObject> extElements = exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME);
@@ -135,6 +137,10 @@ public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predic
         assertEquals(((SigningMethod) signings.next()).getAlgorithm(), "foo");
 
         for (final RoleDescriptor role : entity.getRoleDescriptors()) {
+            exts = role.getExtensions();
+            Assert.assertEquals(exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME).size(), 1);
+            Assert.assertEquals(exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME).size(), 1);
+            
             for (final KeyDescriptor key : role.getKeyDescriptors()) {
                 final List<EncryptionMethod> methods = key.getEncryptionMethods();
                 assertEquals(methods.size(), 3);
@@ -154,7 +160,132 @@ public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predic
             }
         }
     }
+    
+    @Test
+    public void testWithRemoval() throws ComponentInitializationException, ResolverException {
+        
+        final DigestMethod digest2 = buildXMLObject(DigestMethod.DEFAULT_ELEMENT_NAME);
+        digest2.setAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA512);
+
+        final DigestMethod digest3 = buildXMLObject(DigestMethod.DEFAULT_ELEMENT_NAME);
+        digest3.setAlgorithm("foo");
+
+        final SigningMethod signing2 = buildXMLObject(SigningMethod.DEFAULT_ELEMENT_NAME);
+        signing2.setAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512);
+
+        final SigningMethod signing3 = buildXMLObject(SigningMethod.DEFAULT_ELEMENT_NAME);
+        signing3.setAlgorithm("foo");
+
+        final EncryptionMethod enc1 = buildXMLObject(EncryptionMethod.DEFAULT_ELEMENT_NAME);
+        enc1.setAlgorithm(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP11);
 
+        final org.opensaml.xmlsec.signature.DigestMethod embeddedDigest =
+                buildXMLObject(org.opensaml.xmlsec.signature.DigestMethod.DEFAULT_ELEMENT_NAME);
+        embeddedDigest.setAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA256);
+        enc1.getUnknownXMLObjects().add(embeddedDigest);
+        
+        final MGF mgf = buildXMLObject(MGF.DEFAULT_ELEMENT_NAME);
+        mgf.setAlgorithm(EncryptionConstants.ALGO_ID_MGF1_SHA256);
+        enc1.getUnknownXMLObjects().add(mgf);
+
+        final EncryptionMethod enc2 = buildXMLObject(EncryptionMethod.DEFAULT_ELEMENT_NAME);
+        enc2.setAlgorithm("foo");
+
+        final Collection<XMLObject> algs =
+                CollectionSupport.listOf(digest2, signing2, enc1, digest3, signing3, enc2);
+        
+        final AlgorithmFilter filter = new AlgorithmFilter();
+        filter.setRemoveExistingDigestMethods(true);
+        filter.setRemoveExistingSigningMethods(true);
+        filter.setRemoveExistingEncryptionMethods(true);
+        filter.setRules(CollectionSupport.singletonMap(this, algs));
+        filter.initialize();
+        
+        metadataProvider.setMetadataFilter(filter);
+        metadataProvider.setId("test");
+        metadataProvider.initialize();
+
+        EntityIdCriterion crit = new EntityIdCriterion("https://foo.example.org/sp");
+        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(crit));
+        assert entity != null;
+        Extensions exts = entity.getExtensions();
+        assert exts != null;
+        
+        List<XMLObject> extElements = exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME);
+        assertEquals(extElements.size(), 2);
+        
+        Iterator<XMLObject> digests = extElements.iterator();
+        assertEquals(((DigestMethod) digests.next()).getAlgorithm(), SignatureConstants.ALGO_ID_DIGEST_SHA512);
+        assertEquals(((DigestMethod) digests.next()).getAlgorithm(), "foo");
+
+        extElements = exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME);
+        assertEquals(extElements.size(), 2);
+        
+        Iterator<XMLObject> signings = extElements.iterator();
+        assertEquals(((SigningMethod) signings.next()).getAlgorithm(), SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512);
+        assertEquals(((SigningMethod) signings.next()).getAlgorithm(), "foo");
+
+        for (final RoleDescriptor role : entity.getRoleDescriptors()) {
+            exts = role.getExtensions();
+            if (exts != null) {
+                Assert.assertTrue(exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME).isEmpty());
+                Assert.assertTrue(exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME).isEmpty());
+            }
+
+            for (final KeyDescriptor key : role.getKeyDescriptors()) {
+                final List<EncryptionMethod> methods = key.getEncryptionMethods();
+                assertEquals(methods.size(), 2);
+                assertEquals(methods.get(0).getAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP11);
+                assertEquals(methods.get(1).getAlgorithm(), "foo");
+                
+                final List<XMLObject> encDigests = methods.get(0).getUnknownXMLObjects(
+                        org.opensaml.xmlsec.signature.DigestMethod.DEFAULT_ELEMENT_NAME);
+                assertEquals(encDigests.size(), 1);
+                assertEquals(((org.opensaml.xmlsec.signature.DigestMethod) encDigests.get(0)).getAlgorithm(),
+                        SignatureConstants.ALGO_ID_DIGEST_SHA256);
+
+                final List<XMLObject> mgfs = methods.get(0).getUnknownXMLObjects(MGF.DEFAULT_ELEMENT_NAME);
+                assertEquals(mgfs.size(), 1);
+                assertEquals(((MGF) mgfs.get(0)).getAlgorithm(), EncryptionConstants.ALGO_ID_MGF1_SHA256);
+            }
+        }
+    }
+
+    @Test
+    public void testRemovalOnly() throws ComponentInitializationException, ResolverException {
+        
+        final AlgorithmFilter filter = new AlgorithmFilter();
+        filter.setRemoveExistingDigestMethods(true);
+        filter.setRemoveExistingSigningMethods(true);
+        filter.setRemoveExistingEncryptionMethods(true);
+        filter.setRules(CollectionSupport.singletonMap(this, CollectionSupport.emptyList()));
+        filter.initialize();
+        
+        metadataProvider.setMetadataFilter(filter);
+        metadataProvider.setId("test");
+        metadataProvider.initialize();
+
+        EntityIdCriterion crit = new EntityIdCriterion("https://foo.example.org/sp");
+        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(crit));
+        assert entity != null;
+        Extensions exts = entity.getExtensions();
+        if (exts != null) {
+            Assert.assertTrue(exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME).isEmpty());
+            Assert.assertTrue(exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME).isEmpty());
+        }
+        
+        for (final RoleDescriptor role : entity.getRoleDescriptors()) {
+            exts = entity.getExtensions();
+            if (exts != null) {
+                Assert.assertTrue(exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME).isEmpty());
+                Assert.assertTrue(exts.getUnknownXMLObjects(SigningMethod.DEFAULT_ELEMENT_NAME).isEmpty());
+            }
+            for (final KeyDescriptor key : role.getKeyDescriptors()) {
+                Assert.assertTrue(key.getEncryptionMethods().isEmpty());
+            }
+        }
+    }
+    
     /** {@inheritDoc} */
     public boolean test(final EntityDescriptor input) {
         return input != null && "https://foo.example.org/sp".equals(input.getEntityID());
diff --git a/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntityDescriptorWithAlgorithms.xml b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntityDescriptorWithAlgorithms.xml
index cb24fb4ef..a8aba3d3f 100644
--- a/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntityDescriptorWithAlgorithms.xml
+++ b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntityDescriptorWithAlgorithms.xml
@@ -6,6 +6,10 @@
       <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
   </md:Extensions>
   <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+    <md:Extensions>
+      <alg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <alg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
+    </md:Extensions>
     <md:KeyDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
       <md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
       <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">

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


More information about the commits mailing list