I'm using OpenSAML to handle SAML (1 and 2) assertions, both encrypted and
plaintext. However, I'm getting the following exception when trying to
validate the signature on a SAML2 EncryptedAssertion after decrypting it
using OpenSAML:
org.opensaml.xml.validation.ValidationException: Unable to evaluate key
against signature
at
org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.ja
va:73)
at [...my code...]
Caused by: org.apache.xml.security.signature.XMLSignatureException: The
Reference for URI #_2517bd88-e4a5-44fe-bf28-e35cd38fb5c8 has no
XMLSignatureInput Original Exception was
org.apache.xml.security.signature.MissingResourceFailureException: The
Reference for URI #_2517bd88-e4a5-44fe-bf28-e35cd38fb5c8 has no
XMLSignatureInput Original Exception was
org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot
resolve element with ID _2517bd88-e4a5-44fe-bf28-e35cd38fb5c8
Original Exception was
org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot
resolve element with ID _2517bd88-e4a5-44fe-bf28-e35cd38fb5c8
Original Exception was
org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot
resolve element with ID _2517bd88-e4a5-44fe-bf28-e35cd38fb5c8
Original Exception was
org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot
resolve element with ID _2517bd88-e4a5-44fe-bf28-e35cd38fb5c8
at
org.apache.xml.security.signature.XMLSignature.checkSignatureValue(Unknown
Source)
at
org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.ja
va:68)
The strange thing is, the assertion contains all the mentioned references.
I'm trying to be a "good citizen" and use OpenSAML for all the decryption
and signature checking, so I'm pretty sure I'm not modifying the assertion
anywhere. Also, this problem doesn't occur for SAML1 assertions.
Here's the validation code I'm using:
KeyInfoCredentialResolver _resolver =3D SecurityTestHelper
.buildBasicInlineKeyInfoResolver();
KeyInfo _ki =3D sig.getKeyInfo();
CriteriaSet criteriaSet =3D new CriteriaSet(new
KeyInfoCriteria(_ki));
try {
for (Credential _cred :
_resolver.resolve(criteriaSet)) {
log.debug("found credential of type: "
+
_cred.getClass().getName());
log.debug("checking signature");
SignatureValidator _sigValidator =3D new
SignatureValidator(_cred);
try {
_sigValidator.validate(sig);
} catch (ValidationException ve) {
log.debug("validation failed.", ve);
throw new JICException("validating
the signature failed.",
ve);
}
log.debug("success!");
}
} catch (SecurityException se) {
throw new JICException("error resolving the
criteriaSet.", se);
}
from the method "void validateSignature(Signature sig) throws JICException"
at:
https://informationcard.svn.sourceforge.net/svnroot/informationcard/trunk/fr
amework/src/main/java/de/fraunhofer/fokus/jic/framework/impl/FrameworkImpl.j
ava
You can find the assertion (encrypted and decrypted) that the above stack
trace refers to at http://informationcard.sourceforge.net/temp/
I'd be grateful for any hints on what's wrong.
All the best,
--Christopher Taylor
--
Christopher Taylor (christoph...@fokus.fraunhofer.de)
Tel: +49 30 3463 9225
Fraunhofer Institute for Open Communication Systems (FOKUS) CC eGovernment
and Applications (ELAN)
Fraunhofer Institut für Offene Kommunikationssysteme (FOKUS)
Kompetenzzentrum eGovernment und Applikationen (ELAN)
Kaiserin-Augusta-Allee 31
10589 Berlin
Hi
I don't know if it's the same problem, but when I decrypt an assertion,
I have to marshall/unmarshall it after decryption before the signature
can be validated (I serialize to a string and read it back using an
unmarshaller).
Regards,
--
Joakim Recht
Trifork A/S, Margrethepladsen 4, 8000 Aarhus C, Denmark
Phone: +45 8732 8787 / Mobile: +45 2021 6257
http://www.trifork.com - E-mail: j...@trifork.com
That sounds like a bug. The earlier error relates to the DOM not recognizing
the Assertion ID as an ID attribute, so there may be a bug related to
establishing IDness under some conditions.
-- Scott
Hi,
decrypter.setRootInNewDocument(true) fixed it! Thanks Brent, Scott and Joakim for the suggestions!
I’m pretty new to OpenSAML (and SAML in general), but is verifying the signature on a decrypted assertion (or XMLObject in general) really so uncommon? I’d actually run across the documentation Brent mentions below, but didn’t realize it applied to my use case. Maybe adding a constructor which allows specifying this option (and adding the notice to its javadoc) would make it more obvious.
Anyway, thanks again!
--Chris
--
Christopher Taylor (christoph...@fokus.fraunhofer.de)
Tel: +49 30 3463 9225
Fraunhofer Institute for Open Communication Systems (FOKUS) CC eGovernment and Applications (ELAN)
Fraunhofer Institut für Offene Kommunikationssysteme (FOKUS) Kompetenzzentrum eGovernment und Applikationen (ELAN)
Kaiserin-Augusta-Allee 31
10589 Berlin
Why is it expensive? I thought Java had adoptNode implemented.
In my case, yes, xmlsec internally re-parses the XML after its been
decrypted.
-- Scott
Taylor, Christopher wrote:
> Hi,
>
>
>
> decrypter.setRootInNewDocument(true) fixed it! Thanks Brent, Scott and Joakim for the suggestions!
>
Great, glad it worked.
>
>
> I'm pretty new to OpenSAML (and SAML in general), but is verifying the signature on a decrypted assertion (or XMLObject in general) really so uncommon?
No, it's probably common, Assertions are often signed. But the other
things in SAML for example that can be encrypted (Attribute, NameID)
aren't signed. And in general XML Encryption usage for other things, I
don't think it would generally be the case that it's necessarily
common. It just depends on what you are doing, which is why it's an option.
> I'd actually run across the documentation Brent mentions below, but didn't realize it applied to my use case. Maybe adding a constructor which allows specifying this option (and adding the notice to its javadoc) would make it more obvious.
>
Well, maybe, but the class already has 3 args to its constructor. Our
project style guidelines are that we generally keep it to 5 or under.
My personal general rule is that if it's a fundamental requirement for
the class to function and no default is realistic, it's a constructor
arg. If it's an optional param, or one that can have a default, then
it's a standard accessor/mutator pair.
I suppose we could also look at changing the default in the SAML
Assertion when decrypting Assertions specifically, but that would make
the behavior asymmetrical. Or we could add overloaded method variants
in the SAML class that take the param that override the default, like
the primary decrypt* methods in the superclass.
Some cases however require the decrypted Element to exist as part of a Document's tree, e.g. ID resolution. So the Decrypter has an option to do that. It's turned off by default, b/c it's expensive relatively speaking and most cases probably don't require. But signature verification on the decrypted Assertion would.Why is it expensive? I thought Java had adoptNode implemented.