[OpenSAML] AttributeValue of type XSString or XSInteger causing signature validation to fail

774 views
Skip to first unread message

Jean-Michel Tremblay

unread,
Oct 22, 2010, 11:39:17 AM10/22/10
to mace-open...@internet2.edu
Hi,

I'm using OpenSAML 2.4.0 (Java) to generate SAML 2.0 requests and responses
back and forth between my junit test and my actual SAML service (also using
OpenSAML).

Both requests and responses are signed. Signature validation works well in
all cases so far except when a response contains an AttributeValue of type
XSString or XSInteger, in which case PKIXSignatureTrustEngine's validate()
method returns false. An attribute without value doesn't cause any problem.
And the same AttributeValue element with no "type" (no XML attribute) works
fine as well.

The attribute statement is marshalled as this:
<saml2:AttributeStatement>
<saml2:Attribute Name="IsAccountIdLookup"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
<saml2:Attribute Name="PartnerId"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xs:integer">32767</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>

Removing this part (before signing) works fine:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:integer"

The AttributeValue generation code looks like this:
private XSInteger makeAttributeValue(Integer value) {
XSIntegerBuilder integerBuilder =
(XSIntegerBuilder)builderFactory.getBuilder(XSInteger.TYPE_NAME);
XSInteger intValue =
integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME,
XSInteger.TYPE_NAME);
intValue.setValue(value);
return intValue;
}

The response (with some parts replaced with ...) looks like this :

<?xml version="1.0" encoding="UTF-8"?><saml2p:Response
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
Destination="http://localhost:8480/aaa/services/SAML2/SSO/POST/Response"
ID="_306bf472-0d00-40df-bf56-6ba96749cffc"
InResponseTo="_6e7576c1-da97-4bca-ac7f-f201cff39a78"
IssueInstant="2010-10-22T15:21:30.248Z" Version="2.0">
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">urn:...:saml:2.0</saml2:Is
suer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>
<ds:Reference URI="#_306bf472-0d00-40df-bf56-6ba96749cffc">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="xs"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>vflK1H4IHlQwPHv0/Wtx+DoiVA8=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509SubjectName>...</ds:X509SubjectName>
<ds:X509Certificate>...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml2p:Status>
<saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</saml2p:Status>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_9efae415-ae5c-4052-90e3-0d34799e32d6"
IssueInstant="2010-10-22T15:21:30.249Z" Version="2.0">
<saml2:Issuer>urn:...:saml:2.0</saml2:Issuer>
<saml2:Subject>
<saml2:NameID
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">DummyAuthex</sam
l2:NameID>
<saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml2:SubjectConfirmationData
InResponseTo="_6e7576c1-da97-4bca-ac7f-f201cff39a78"
NotBefore="2010-10-22T15:21:30.251Z" NotOnOrAfter="2010-10-22T15:23:30.251Z"
Recipient="urn:...:saml:2.0"/>
</saml2:SubjectConfirmation>
</saml2:Subject>
<saml2:AuthnStatement AuthnInstant="2010-10-22T15:21:30.252Z"
SessionIndex="8a59e200-29c2-4a01-bfcf-2e79f72aba80">
<saml2:AuthnContext>
<saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordPro
tectedTransport</saml2:AuthnContextClassRef>
</saml2:AuthnContext>
</saml2:AuthnStatement>
<saml2:AttributeStatement>
<saml2:Attribute Name="IsAccountIdLookup"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
<saml2:Attribute Name="PartnerId"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="xs:integer">32767</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
</saml2:Assertion>
</saml2p:Response>

Any help would be appreciated.

-JMT

Brent Putman

unread,
Oct 25, 2010, 7:02:58 PM10/25/10
to mace-open...@internet2.edu

On 10/22/10 11:39 AM, Jean-Michel Tremblay wrote:
> Hi,
>


> I'm using OpenSAML 2.4.0 (Java) to generate SAML 2.0 requests and responses
> back and forth between my junit test and my actual SAML service (also using
> OpenSAML).
>

So to be clear, both the signing and validation sides in the failure
case are using OpenSAML Java?

>
> Both requests and responses are signed. Signature validation works well in
> all cases so far except when a response contains an AttributeValue of type
> XSString or XSInteger, in which case PKIXSignatureTrustEngine's validate()
> method returns false. An attribute without value doesn't cause any problem.
> And the same AttributeValue element with no "type" (no XML attribute) works
> fine as well.


We routinely use xsi:type's in AttributeValues generated by the
Shibboleth IdP, and that gets validated fine by both Java OpenSAML and
other SAML impls (C++ OpenSAML, probably SimpleSAML, etc). So I'm
somewhat skeptical that the cause of the failure has anything to do with
the xsi:type and xsi namespace decl being present. It *might* possibly
have something to do with the exclusive c14n inclusive namespace prefix
handling, which is new in 2.4.0, but that's known to work also within
Shib. At the very least we'd need to see a lot more debug output from
both the signing and validating sides. See this wiki page for how to
get that from OpenSAML Java and C++:

https://spaces.internet2.edu/display/OpenSAML/OSTwoUserManSigErrors


Basically need to compare the canonicalized octets from both the signing
and validation sides.

Might also be useful to turn on debug logging for OpenSAML, to see what
the PKIX trust engine and related security code is actually doing. Lots
of things can go wrong with the PKIX validation approach.

>
> The attribute statement is marshalled as this:
> <saml2:AttributeStatement>
> <saml2:Attribute Name="IsAccountIdLookup"
> NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"/>
> <saml2:Attribute Name="PartnerId"
> NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
> <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:type="xs:integer">32767</saml2:AttributeValue>
> </saml2:Attribute>
> </saml2:AttributeStatement>
>

That AttributeValue looks perfectly fine, should not cause any error
like this.

> Removing this part (before signing) works fine:
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:integer"


Ok. The code is correctly populating the exclusive c14n Transform with
the inclusive prefix, based on what you sent:

> <ds:Transform
> Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
> <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
> PrefixList="xs"/>
> </ds:Transform>


This behavior has changed in 2.4.0. Previously it populated every
in-scope namespace prefix. Now it only populates the ones which are
non-visibly used.

>
> The AttributeValue generation code looks like this:
> private XSInteger makeAttributeValue(Integer value) {
> XSIntegerBuilder integerBuilder =
> (XSIntegerBuilder)builderFactory.getBuilder(XSInteger.TYPE_NAME);
> XSInteger intValue =
> integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME,
> XSInteger.TYPE_NAME);
> intValue.setValue(value);
> return intValue;
> }

That also looks fine.

Jean-Michel Tremblay

unread,
Nov 2, 2010, 2:56:47 PM11/2/10
to mace-open...@internet2.edu
(Sorry for late reply, I was finalizing the rest of the code.)

Yes, both the singing and validating parts use OpenSAML Java.

I tried the three other canonicalization algorithms
(SignatureConstants.ALGO_ID_C14N*), and I get the same error.

Here's the log on the validating side:
2010-11-02 14:26:07.407 [DEBUG] (main)
org.opensaml.xml.signature.impl.SignatureUnmarshaller - Starting to
unmarshall Apache XML-Security-based SignatureImpl element
2010-11-02 14:26:07.407 [DEBUG] (main)
org.opensaml.xml.signature.impl.SignatureUnmarshaller - Constructing Apache
XMLSignature object
2010-11-02 14:26:07.407 [DEBUG] (main)
org.opensaml.xml.signature.impl.SignatureUnmarshaller - Adding
canonicalization and signing algorithms, and HMAC output length to Signature
2010-11-02 14:26:07.407 [DEBUG] (main)
org.opensaml.xml.signature.impl.SignatureUnmarshaller - Adding KeyInfo to
Signature
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.security.SAMLSignatureProfileValidator - Saw Enveloped signature
transform
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.security.SAMLSignatureProfileValidator - Saw Exclusive C14N
signature transform
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.xml.signature.impl.BaseSignatureTrustEngine - Attempting to
verify signature and establish trust using KeyInfo-derived credentials
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver -
Found 0 key names: []
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver -
Processing KeyInfo child with qname:
{http://www.w3.org/2000/09/xmldsig#}X509Data
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver -
Provider org.opensaml.xml.security.keyinfo.provider.RSAKeyValueProvider
doesn't handle objects of type {http://www.w3.org/2000/09/xmldsig#}X509Data,
skipping
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver -
Provider org.opensaml.xml.security.keyinfo.provider.DSAKeyValueProvider
doesn't handle objects of type {http://www.w3.org/2000/09/xmldsig#}X509Data,
skipping
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver -
Processing KeyInfo child {http://www.w3.org/2000/09/xmldsig#}X509Data with
provider org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider
2010-11-02 14:26:07.412 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider -
Attempting to extract credential from an X509Data
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider - Found 1
X509Certificates
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider - Found 0
X509CRLs
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider - Single
certificate was present, treating as end-entity certificate
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver -
Credentials successfully extracted from child
{http://www.w3.org/2000/09/xmldsig#}X509Data by provider
org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver - A
total of 1 credentials were resolved
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.security.credential.criteria.EvaluableCredentialCriteriaRegis
try - Registry could not locate evaluable criteria for criteria class
org.opensaml.xml.security.keyinfo.KeyInfoCriteria
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.signature.SignatureValidator - Attempting to validate
signature using key from supplied credential
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.signature.SignatureValidator - Creating XMLSignature object
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.signature.SignatureValidator - Validating signature with
signature algorithm URI: http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
2010-11-02 14:26:07.415 [DEBUG] (main)
org.opensaml.xml.signature.SignatureValidator - Validation credential key
algorithm 'RSA', key instance class 'sun.security.rsa.RSAPublicKeyImpl'
2010-11-02 14:26:07.417 [DEBUG] (main)
org.opensaml.xml.signature.SignatureValidator - Signature did not validate
against the credential's key
2010-11-02 14:26:07.417 [DEBUG] (main)
org.opensaml.xml.signature.impl.BaseSignatureTrustEngine - Signature
validation using candidate validation credential failed
org.opensaml.xml.validation.ValidationException: Signature did not validate
against the credential's key
at
org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java
:78)
at
org.opensaml.xml.signature.impl.BaseSignatureTrustEngine.verifySignature(BaseS
ignatureTrustEngine.java:141)
at
org.opensaml.xml.signature.impl.BaseSignatureTrustEngine.validate(BaseSignatur
eTrustEngine.java:99)
at
org.opensaml.xml.signature.impl.PKIXSignatureTrustEngine.validate(PKIXSignatur
eTrustEngine.java:157)
at
org.opensaml.xml.signature.impl.PKIXSignatureTrustEngine.validate(PKIXSignatur
eTrustEngine.java:53)
at
com.rp.aaa.service.saml.SamlFacade.isSignatureValid(SamlFacade.java:486)
at
com.rp.aaa.test.integration.saml.SamlSingleSignOnTest.assertMsdpResponse(SamlS
ingleSignOnTest.java:1390)
at
com.rp.aaa.test.integration.saml.SamlSingleSignOnTest.assertMsdpResponse(SamlS
ingleSignOnTest.java:1350)
at
com.rp.aaa.test.integration.saml.SamlSingleSignOnTest.testWebLoginLogout_MainC
ase(SamlSingleSignOnTest.java:300)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.j
ava:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.ja
va:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.jav
a:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java
:41)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:
20)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
76)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestRefer
ence.java:46)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunn
er.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunn
er.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.ja
va:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.j
ava:197)
2010-11-02 14:26:07.418 [DEBUG] (main)
org.opensaml.xml.signature.impl.BaseSignatureTrustEngine - Failed to verify
signature and/or establish trust using any KeyInfo-derived credentials
2010-11-02 14:26:07.418 [DEBUG] (main)
org.opensaml.xml.signature.impl.PKIXSignatureTrustEngine - PKIX validation of
signature failed, unable to resolve valid and trusted signing key
2010-11-02 14:26:07.418 [ERROR] (main) com.rp.aaa.service.saml.SamlFacade -
Signature was either invalid or signing key could not be established as
trusted

Here's the log on the encoding side:
2010-11-02 14:26:07.302 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.common.SAMLObjectHelper - Examing signed object for content
references with exclusive canonicalization transform
2010-11-02 14:26:07.302 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.common.SAMLObjectHelper - Saw exclusive transform, declaring
non-visible namespaces on signed object
2010-11-02 14:26:07.303 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.xml.signature.impl.SignatureMarshaller - Starting to marshall
{http://www.w3.org/2000/09/xmldsig#}Signature
2010-11-02 14:26:07.303 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.xml.signature.impl.SignatureMarshaller - Creating XMLSignature
object
2010-11-02 14:26:07.303 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.xml.signature.impl.SignatureMarshaller - Adding content to
XMLSignature.
2010-11-02 14:26:07.304 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.common.impl.SAMLObjectContentReference - Adding list of
inclusive namespaces for signature exclusive canonicalization transform
2010-11-02 14:26:07.304 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.xml.signature.impl.SignatureMarshaller - Creating Signature DOM
element
2010-11-02 14:26:07.306 [DEBUG] (30720210@qtp-26267652-7)
org.opensaml.xml.signature.Signer - Computing signature over XMLSignature
object

The signature looks like this in this case (in the same Response I pasted in
my original post):


<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod

Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>


<ds:SignatureMethod
Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"/>

<ds:Reference URI="#_3aced2a3-4714-4db8-abb8-75ee5af15b5e">
<ds:Transforms>


<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="xs"/>
</ds:Transform>

</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>

<ds:DigestValue>udEl/gp4pPvURLjb0PQfLDW1yws=</ds:DigestValue>


</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509SubjectName>...</ds:X509SubjectName>
<ds:X509Certificate>...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>

I also sign and validate SSO and SLO requests without problems. Same for SLO
responses. Same for SSO Responses without attributes.

I don't know why, but the problem is really triggered/exposed when a response
contains attributes built from XSString/XSInteger.

To work around the problem, I'm replacing these methods:
private XSString makeAttributeValue(String value) {
XSStringBuilder stringBuilder =
(XSStringBuilder)builderFactory.getBuilder(XSString.TYPE_NAME);
XSString stringValue =
stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME,
XSString.TYPE_NAME);
stringValue.setValue(value);
return stringValue;
}

private XSInteger makeAttributeValue(Integer value) {
XSIntegerBuilder integerBuilder =
(XSIntegerBuilder)builderFactory.getBuilder(XSInteger.TYPE_NAME);
XSInteger intValue =
integerBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME,
XSInteger.TYPE_NAME);
intValue.setValue(value);
return intValue;
}

With this one:
private XSAny makeAttributeValue(Object value) {
XSAnyBuilder xsAnyBuilder =
(XSAnyBuilder)builderFactory.getBuilder(XSAny.TYPE_NAME);
XSAny attr =
xsAnyBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME);
attr.setTextContent(value.toString());
return attr;
}

But I need to support both.

Do the logs help? I can step in the code now in Eclipse, so maybe there's
something I should look for?

Scott Cantor

unread,
Nov 2, 2010, 3:29:14 PM11/2/10
to mace-open...@internet2.edu
> Do the logs help? I can step in the code now in Eclipse, so maybe there's
> something I should look for?

The signature debugging page in the wiki discusses the issues, you need to
get access to the digest octets on both ends and compare them. Nothing else
is relevant unless somebody eyeballs an issue in the XML and gets lucky.

-- Scott

JM Tremblay

unread,
Nov 2, 2010, 3:57:22 PM11/2/10
to mace-open...@internet2.edu
Ok, sorry.  With "log4j.logger.org.apache.xml.security=DEBUG", I do see extra end-of-lines before and after the <ec:InclusiveNamespaces> element in the  "Canonicalized SignedInfo. That doesn't look right.

Decoded:
2010-11-02 15:40:35.713 [DEBUG] (main) org.apache.xml.security.utils.SignerOutputStream  - Canonicalized SignedInfo:
2010-11-02 15:40:35.713 [DEBUG] (main) org.apache.xml.security.utils.SignerOutputStream  - <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema"><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"></ds:SignatureMethod><ds:Reference URI="#_91da63dc-d7cb-41da-a4fc-38ad3961d7fd"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"></ec:InclusiveNamespaces>
</ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>AatpaNfl3oViZ62EdVuSZdxQYUw=</ds:DigestValue></ds:Reference></ds:SignedInfo>

Encoded:
2010-11-02 15:40:35.607 [DEBUG] (29686429@qtp-1119464-7) org.apache.xml.security.utils.SignerOutputStream  - Canonicalized SignedInfo:
2010-11-02 15:40:35.607 [DEBUG] (29686429@qtp-1119464-7) org.apache.xml.security.utils.SignerOutputStream  - <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema"><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"></ds:SignatureMethod><ds:Reference URI="#_91da63dc-d7cb-41da-a4fc-38ad3961d7fd"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"></ec:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>AatpaNfl3oViZ62EdVuSZdxQYUw=</ds:DigestValue></ds:Reference></ds:SignedInfo>

Now I need to figure out if I have any control over that.

-JM

JM Tremblay

unread,
Nov 2, 2010, 4:24:36 PM11/2/10
to mace-open...@internet2.edu
Here's the  Canonicalized SignedInfo when I don't use XSString attributes.  The encoded/decoded SignedInfos match and don't have (require) any ec:InclusiveNamespaces element. That explains why the "xs" attributes trigger the problem.

2010-11-02 16:12:16.442 [DEBUG] (main) org.apache.xml.security.utils.SignerOutputStream  - Canonicalized SignedInfo:
2010-11-02 16:12:16.443 [DEBUG] (main) org.apache.xml.security.utils.SignerOutputStream  - <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"></ds:SignatureMethod><ds:Reference URI="#_2c0d4932-8ef2-4c76-bb16-002af7116998"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>cengJGzybQWVvmDYUmDRF42t8pw=</ds:DigestValue></ds:Reference></ds:SignedInfo>

2010-11-02 16:11:40.725 [DEBUG] (14534444@qtp-3324757-7) org.apache.xml.security.utils.SignerOutputStream  - Canonicalized SignedInfo:
2010-11-02 16:11:40.725 [DEBUG] (14534444@qtp-3324757-7) org.apache.xml.security.utils.SignerOutputStream  - <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"></ds:SignatureMethod><ds:Reference URI="#_2c0d4932-8ef2-4c76-bb16-002af7116998"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod><ds:DigestValue>cengJGzybQWVvmDYUmDRF42t8pw=</ds:DigestValue></ds:Reference></ds:SignedInfo>

JM

Brent Putman

unread,
Nov 2, 2010, 4:29:32 PM11/2/10
to mace-open...@internet2.edu

On 11/2/10 3:57 PM, JM Tremblay wrote:
> Ok, sorry. With "log4j.logger.org.apache.xml.security=DEBUG", I do
> see extra end-of-lines before and after the <ec:InclusiveNamespaces>
> element in the "Canonicalized SignedInfo. That doesn't look right.
>
>

Yes, that's interesting. Usually we see issues with the digester output
steam (the Reference that was signed), not the SignedInfo of the
Signature. That certainly explains why adding the xsi:type is producing
the error case: the xs:string or xs:integer is triggering the inclusion
of the InclusiveNamespaces element. With no xsi:type (and no other
non-visibly used namespace prefixes), you'd get no InclusiveNamespaces
in the output, and presumably no added newlines.


>
> Now I need to figure out if I have any control over that.
>


I guess the 2 things to look at are:

1) how are you serializing the DOM on the signing side? Are you using
our helper methods or your own code?

2) how are you deserializing and parsing on the validation side?

Using our serialization and parsing code we don't see this issue of the
newlines being added, so you might want to compare what you are doing to
our XMLHelper.writeNode(...) and ParserPool code.

--Brent

Brent Putman

unread,
Nov 2, 2010, 4:31:13 PM11/2/10
to mace-open...@internet2.edu

On 11/2/10 4:24 PM, JM Tremblay wrote:
> Here's the Canonicalized SignedInfo when I don't use XSString
> attributes. The encoded/decoded SignedInfos match and don't have
> (require) any ec:InclusiveNamespaces element. That explains why the
> "xs" attributes trigger the problem.
>
>

I just saw this after sending my last note, but this is exactly what I
anticipated.


JM Tremblay

unread,
Nov 2, 2010, 4:56:57 PM11/2/10
to mace-open...@internet2.edu
> 1) how are you serializing the DOM on the signing side?  Are you using
> our helper methods or your own code?

I was using some helper method we had already. It had indentiation
turned on, which I just commented out, and got rid of the issue
(SignedInfo has the InclusiveNamespaces without the extra newlines).
Transformer transformer = TransformerFactory.newInstance().newTransformer();
//transformer.setOutputProperty(OutputKeys.INDENT, "yes");
...

I didn't suspect this would be a problem. I thought canonicalization
on the parser side would get rid of any extra formatting. It did for
the digester output part, I suppose.

I'll probably change my code to use your helper methods instead.
Thanks guys for your help and your quick replies.

JM

Scott Cantor

unread,
Nov 2, 2010, 5:08:09 PM11/2/10
to mace-open...@internet2.edu
> I was using some helper method we had already. It had indentiation
> turned on, which I just commented out, and got rid of the issue
> (SignedInfo has the InclusiveNamespaces without the extra newlines).

We should have just asked, it's a bad habit to jump to the complex
possibilities.

> I didn't suspect this would be a problem. I thought canonicalization
> on the parser side would get rid of any extra formatting. It did for
> the digester output part, I suppose.

Whitespace is always significant to c14n, as you now know.

-- Scott

JM Tremblay

unread,
Nov 2, 2010, 6:23:23 PM11/2/10
to mace-open...@internet2.edu
> Whitespace is always significant to c14n, as you now know.

Well, I know it's significant after c14n . But I didn't expect the
OpenSAML parsing code to assume the SignedInfo was pre-canonicalized.
I thought it'd perform c14n on it, removing newlines.

JM

Jim Fox

unread,
Nov 2, 2010, 6:38:12 PM11/2/10
to mace-open...@internet2.edu

You mean remove every newline in your document? Newlines between
attributes of
an element are not significant, but newlines as text elements are, well,
text elements.

Jim

Scott Cantor

unread,
Nov 2, 2010, 10:44:26 PM11/2/10
to mace-open...@internet2.edu
> Well, I know it's significant after c14n . But I didn't expect the
> OpenSAML parsing code to assume the SignedInfo was pre-canonicalized.
> I thought it'd perform c14n on it, removing newlines.

That's my point, you're mistaking c14n for having something to do with
"removing newlines", which is not at all part of c14n. Newlines are
whitespace and are significant in XML. It doesn't matter where they are. It
isn't "correct" or "incorrect" to strip them from SignedInfo. If they're
there, they're signed and must be preserved.

Apache XML-Security itself produces specifically formatted DOM nodes itself.
We don't strip them or do anything with them, but if something else does
after signing, it will break. If something cares what they look like
beforehand, it can make changes as long as it does so before signing, but
after that, you preserve the XML byte for byte or your signature will break
90% of the time.

This is why the spec was essentially broken. It thought it knew what changes
people wanted to make to documents and accounted for them in c14n, but it
got it completely and utterly wrong, since most changes people expect will
be neutral are not.

-- Scott

Reply all
Reply to author
Forward
0 new messages