Odd behavior when signing SAML 1.1 Assertion w/ Advice
Stephen.CTR.Chappell at faa.gov
Stephen.CTR.Chappell at faa.gov
Thu Oct 9 08:00:03 EDT 2014
Good morning -
I've been working to port some legacy code that used CXF 2.3, WSS4J 1.5, and OpenSAML 1 up to CXF 2.7, WSS4J 1.6, and OpenSAML 2, and have run across a problem. The code in question issues and signs HOK SAML 1.1 assertions. This works fine when the assertion does not include an assertion in the advice. But when it does, the assertion is signed ok, but the assertion contained in the Advice (which was previously signed) is no longer signed. The signature tags are present, but contain little to no data, and no signature. Here's some examples.
First, a properly signed assertion, trimmed for brevity:
<Assertion ...>
<Conditions ...>...</Conditions>
<AuthenticationStatement>...</AuthenticationStatement>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#<http://www.w3.org/2001/10/xml-exc-c14n>"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#_C68DEF87FEAA142270141276838866611">
<ds:Transforms>...</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo>...</ds:KeyInfo>
</ds:Signature>
</Assertion>
Now, an assertion with advice. You can see the assertion is signed, but the assertion contained in the advice is not:
<Assertion ...>
<Conditions ...>...</Conditions>
<Advice>
<Assertion ...>
<Conditions ...>...</Conditions>
<AuthenticationStatement>...</AuthenticationStatement>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#<http://www.w3.org/2001/10/xml-exc-c14n>"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#_C68DEF87FEAA142270141276838866611">
<ds:Transforms>...</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue/>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue/>
<ds:KeyInfo>...</ds:KeyInfo>
</ds:Signature>
</Assertion>
</Advice>
<AuthenticationStatement>...</AuthenticationStatement>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#<http://www.w3.org/2001/10/xml-exc-c14n>"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#_C68DEF87FEAA142270141276838916432">
<ds:Transforms>...</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo>...</ds:KeyInfo>
</ds:Signature>
</Assertion>
The code I'm using to sign the assertion is based heavily on the WSS4J AssertionWrapper signAssertion code. Here it is:
protected final void signIt(org.opensaml.saml1.core.Assertion sa, String issuerKeyName, String issuerKeyPassword, Crypto issuerCrypto, boolean sendKeyValue, String canonicalizationAlgorithm, String signatureAlgorithm, String signatureDigestAlgorithm
) throws WSSecurityException
{
XMLObjectBuilder<Signature> builder = builderFactory.getBuilder(Signature.DEFAULT_ELEMENT_NAME);
Signature sig = (Signature) builder.buildObject(Signature.DEFAULT_ELEMENT_NAME);
sig.setCanonicalizationAlgorithm(canonicalizationAlgorithm);
CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
cryptoType.setAlias(issuerKeyName);
X509Certificate[] issuerCerts = issuerCrypto.getX509Certificates(cryptoType);
String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
PrivateKey privateKey = null;
try {
privateKey = issuerCrypto.getPrivateKey(issuerKeyName, issuerKeyPassword);
} catch ( Exception e ) {
throw new WSSecurityException(e.getMessage(), e);
}
sig.setSignatureAlgorithm(signatureAlgorithm);
BasicX509Credential signingCredential = new BasicX509Credential();
signingCredential.setEntityCertificate(issuerCerts[0]);
signingCredential.setPrivateKey(privateKey);
sig.setSigningCredential(signingCredential);
X509KeyInfoGeneratorFactory kiFactory = new X509KeyInfoGeneratorFactory();
if ( sendKeyValue == true ) {
kiFactory.setEmitPublicKeyValue(true);
} else {
kiFactory.setEmitEntityCertificate(true);
}
try {
KeyInfo keyInfo = kiFactory.newInstance().generate(signingCredential);
sig.setKeyInfo(keyInfo);
} catch ( org.opensaml.xml.security.SecurityException ex ) {
throw new WSSecurityException("Error generating KeyInfo from signing credential", ex);
}
sa.setSignature(sig);
SAMLObjectContentReference contentRef =
(SAMLObjectContentReference)sa.getContentReferences().get(0);
contentRef.setDigestAlgorithm(signatureDigestAlgorithm);
sa.releaseChildrenDOM(true);
sa.releaseDOM();
}
Obviously, something is not right here. Can someone point me in the right direction?
Stephen W. Chappell
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://shibboleth.net/pipermail/dev/attachments/20141009/28f1f0c0/attachment-0001.html
More information about the dev
mailing list