diff --git a/core/src/main/java/org/springframework/security/saml/metadata/ExtendedMetadata.java b/core/src/main/java/org/springframework/security/saml/metadata/ExtendedMetadata.java index a1c6ac6dc..ffec8ae78 100755 --- a/core/src/main/java/org/springframework/security/saml/metadata/ExtendedMetadata.java +++ b/core/src/main/java/org/springframework/security/saml/metadata/ExtendedMetadata.java @@ -140,6 +140,12 @@ public class ExtendedMetadata implements Serializable, Cloneable { */ private boolean supportUnsolicitedResponse = true; + /** + * Algorithm used for creation of digest method of this entity. At the moment only used for metadata signatures. + * Only valid for local entities. + */ + private String digestMethodAlgorithm; + /** * Security profile to use for this local entity - MetaIOP (default) or PKIX. * @@ -573,4 +579,36 @@ public ExtendedMetadata clone() { } } + /** + * Returns digest method algorithm value + * @return String + */ + public String getDigestMethodAlgorithm() + { + return digestMethodAlgorithm; + } + + /** + * Sets the digest method algorithm to use when signing the SAML messages. + * This can be used, for example, when a strong algorithm is required (e.g. SHA 256 instead of SHA 128). + * If this property is null, then the {@link org.opensaml.xml.Configuration} default algorithm will be used instead. + * + * Value only applies to local entities. + * + * At the moment the value is only used for signatures on metadata. + * + * Typical values are: + * http://www.w3.org/2001/04/xmlenc#sha1 + * http://www.w3.org/2001/04/xmlenc#sha256 + * http://www.w3.org/2001/04/xmlenc#sha384 + * http://www.w3.org/2001/04/xmlenc#sha512 + * http://www.w3.org/2001/04/xmlenc#ripemd160 + * + * @param digestMethodAlgorithm The new digest method algorithm to use + * @see org.opensaml.xml.signature.SignatureConstants + */ + public void setDigestMethodAlgorithm(String digestMethodAlgorithm) + { + this.digestMethodAlgorithm = digestMethodAlgorithm; + } } \ No newline at end of file diff --git a/core/src/main/java/org/springframework/security/saml/util/SAMLUtil.java b/core/src/main/java/org/springframework/security/saml/util/SAMLUtil.java index a004f9034..da2a7de69 100644 --- a/core/src/main/java/org/springframework/security/saml/util/SAMLUtil.java +++ b/core/src/main/java/org/springframework/security/saml/util/SAMLUtil.java @@ -39,6 +39,7 @@ import org.opensaml.xml.XMLObjectBuilder; import org.opensaml.xml.io.Marshaller; import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.security.BasicSecurityConfiguration; import org.opensaml.xml.security.SecurityHelper; import org.opensaml.xml.security.credential.Credential; import org.opensaml.xml.signature.KeyInfo; @@ -447,13 +448,14 @@ public static Element marshallMessage(XMLObject message) throws MessageEncodingE * @param signableMessage object to sign * @param signingCredential credential to sign with * @param signingAlgorithm signing algorithm to use (optional). Leave null to use credential's default algorithm + * @param signingAlgorithm digest method algorithm to use (optional). Leave null to use credential's default algorithm * @param keyInfoGenerator name of generator used to create KeyInfo elements with key data * @throws org.opensaml.ws.message.encoder.MessageEncodingException * thrown if there is a problem marshalling or signing the message * @return marshalled and signed message */ @SuppressWarnings("unchecked") - public static Element marshallAndSignMessage(SignableXMLObject signableMessage, Credential signingCredential, String signingAlgorithm, String keyInfoGenerator) throws MessageEncodingException { + public static Element marshallAndSignMessage(SignableXMLObject signableMessage, Credential signingCredential, String signingAlgorithm, String digestMethodAlgorithm, String keyInfoGenerator) throws MessageEncodingException { if (signingCredential != null && !signableMessage.isSigned()) { @@ -467,8 +469,17 @@ public static Element marshallAndSignMessage(SignableXMLObject signableMessage, signature.setSigningCredential(signingCredential); + BasicSecurityConfiguration secConfig = null; + + if (digestMethodAlgorithm != null) + { + secConfig = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration(); + + secConfig.setSignatureReferenceDigestMethod(digestMethodAlgorithm); + } + try { - SecurityHelper.prepareSignatureParams(signature, signingCredential, null, keyInfoGenerator); + SecurityHelper.prepareSignatureParams(signature, signingCredential, secConfig, keyInfoGenerator); } catch (org.opensaml.xml.security.SecurityException e) { throw new MessageEncodingException("Error preparing signature for signing", e); } @@ -595,7 +606,8 @@ public static String getMetadataAsString(MetadataManager metadataManager, KeyMan Credential credential = keyManager.getCredential(extendedMetadata.getSigningKey()); String signingAlgorithm = extendedMetadata.getSigningAlgorithm(); String keyGenerator = extendedMetadata.getKeyInfoGeneratorName(); - element = SAMLUtil.marshallAndSignMessage(descriptor, credential, signingAlgorithm, keyGenerator); + String digestMethodAlgorithm = extendedMetadata.getDigestMethodAlgorithm(); + element = SAMLUtil.marshallAndSignMessage(descriptor, credential, signingAlgorithm, digestMethodAlgorithm, keyGenerator); } else { element = SAMLUtil.marshallMessage(descriptor); }