<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
        {mso-style-priority:99;
        mso-style-link:"Balloon Text Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:8.0pt;
        font-family:"Tahoma","sans-serif";}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.BalloonTextChar
        {mso-style-name:"Balloon Text Char";
        mso-style-priority:99;
        mso-style-link:"Balloon Text";
        font-family:"Tahoma","sans-serif";}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Good morning –<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">First, a properly signed assertion, trimmed for brevity:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><Assertion …><o:p></o:p></p>
<p class="MsoNormal"> <Conditions …>...</Conditions><o:p></o:p></p>
<p class="MsoNormal"> <AuthenticationStatement>…</AuthenticationStatement><o:p></o:p></p>
<p class="MsoNormal"> <ds:Signature><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignedInfo><o:p></o:p></p>
<p class="MsoNormal"> <ds:CanonicalizationMethod Algorithm="<a href="http://www.w3.org/2001/10/xml-exc-c14n">http://www.w3.org/2001/10/xml-exc-c14n#</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignatureMethod Algorithm="<a href="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256">http://www.w3.org/2001/04/xmldsig-more#rsa-sha256</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:Reference URI="#_C68DEF87FEAA142270141276838866611"><o:p></o:p></p>
<p class="MsoNormal"> <ds:Transforms>…</ds:Transforms><o:p></o:p></p>
<p class="MsoNormal"> <ds:DigestMethod Algorithm="<a href="http://www.w3.org/2001/04/xmlenc#sha256">http://www.w3.org/2001/04/xmlenc#sha256</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:DigestValue>…</ds:DigestValue><o:p></o:p></p>
<p class="MsoNormal"> </ds:Reference><o:p></o:p></p>
<p class="MsoNormal"> </ds:SignedInfo><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignatureValue>...</ds:SignatureValue><o:p></o:p></p>
<p class="MsoNormal"> <ds:KeyInfo>…</ds:KeyInfo><o:p></o:p></p>
<p class="MsoNormal"> </ds:Signature><o:p></o:p></p>
<p class="MsoNormal"></Assertion><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Now, an assertion with advice. You can see the assertion is signed, but the assertion contained in the advice is not:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><Assertion …><o:p></o:p></p>
<p class="MsoNormal"> <Conditions …>…</Conditions><o:p></o:p></p>
<p class="MsoNormal"> <Advice><o:p></o:p></p>
<p class="MsoNormal"> <Assertion …><o:p></o:p></p>
<p class="MsoNormal"> <Conditions …>…</Conditions><o:p></o:p></p>
<p class="MsoNormal"> <AuthenticationStatement>…</AuthenticationStatement><o:p></o:p></p>
<p class="MsoNormal"> <ds:Signature><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignedInfo><o:p></o:p></p>
<p class="MsoNormal"> <ds:CanonicalizationMethod Algorithm="<a href="http://www.w3.org/2001/10/xml-exc-c14n">http://www.w3.org/2001/10/xml-exc-c14n#</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignatureMethod Algorithm="<a href="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256">http://www.w3.org/2001/04/xmldsig-more#rsa-sha256</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:Reference URI="#_C68DEF87FEAA142270141276838866611"><o:p></o:p></p>
<p class="MsoNormal"> <ds:Transforms>…</ds:Transforms><o:p></o:p></p>
<p class="MsoNormal"> <ds:DigestMethod Algorithm="<a href="http://www.w3.org/2000/09/xmldsig#sha1">http://www.w3.org/2000/09/xmldsig#sha1</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:DigestValue/><o:p></o:p></p>
<p class="MsoNormal"> </ds:Reference><o:p></o:p></p>
<p class="MsoNormal"> </ds:SignedInfo><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignatureValue/><o:p></o:p></p>
<p class="MsoNormal"> <ds:KeyInfo>…</ds:KeyInfo><o:p></o:p></p>
<p class="MsoNormal"> </ds:Signature><o:p></o:p></p>
<p class="MsoNormal"> </Assertion><o:p></o:p></p>
<p class="MsoNormal"> </Advice><o:p></o:p></p>
<p class="MsoNormal"> <AuthenticationStatement>…</AuthenticationStatement><o:p></o:p></p>
<p class="MsoNormal"> <ds:Signature><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignedInfo><o:p></o:p></p>
<p class="MsoNormal"> <ds:CanonicalizationMethod Algorithm="<a href="http://www.w3.org/2001/10/xml-exc-c14n">http://www.w3.org/2001/10/xml-exc-c14n#</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignatureMethod Algorithm="<a href="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256">http://www.w3.org/2001/04/xmldsig-more#rsa-sha256</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:Reference URI="#_C68DEF87FEAA142270141276838916432"><o:p></o:p></p>
<p class="MsoNormal"> <ds:Transforms>…</ds:Transforms><o:p></o:p></p>
<p class="MsoNormal"> <ds:DigestMethod Algorithm="<a href="http://www.w3.org/2001/04/xmlenc#sha256">http://www.w3.org/2001/04/xmlenc#sha256</a>"/><o:p></o:p></p>
<p class="MsoNormal"> <ds:DigestValue>…</ds:DigestValue><o:p></o:p></p>
<p class="MsoNormal"> </ds:Reference><o:p></o:p></p>
<p class="MsoNormal"> </ds:SignedInfo><o:p></o:p></p>
<p class="MsoNormal"> <ds:SignatureValue>...</ds:SignatureValue><o:p></o:p></p>
<p class="MsoNormal"> <ds:KeyInfo>…</ds:KeyInfo><o:p></o:p></p>
<p class="MsoNormal"> </ds:Signature><o:p></o:p></p>
<p class="MsoNormal"></Assertion><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The code I’m using to sign the assertion is based heavily on the WSS4J AssertionWrapper signAssertion code. Here it is:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">protected final void signIt(org.opensaml.saml1.core.Assertion sa, String issuerKeyName, String issuerKeyPassword, Crypto issuerCrypto, boolean sendKeyValue, String canonicalizationAlgorithm, String signatureAlgorithm, String signatureDigestAlgorithm<o:p></o:p></p>
<p class="MsoNormal">) throws WSSecurityException<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal"> XMLObjectBuilder<Signature> builder = builderFactory.getBuilder(Signature.DEFAULT_ELEMENT_NAME);<o:p></o:p></p>
<p class="MsoNormal"> Signature sig = (Signature) builder.buildObject(Signature.DEFAULT_ELEMENT_NAME);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> sig.setCanonicalizationAlgorithm(canonicalizationAlgorithm);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);<o:p></o:p></p>
<p class="MsoNormal"> cryptoType.setAlias(issuerKeyName);<o:p></o:p></p>
<p class="MsoNormal"> X509Certificate[] issuerCerts = issuerCrypto.getX509Certificates(cryptoType);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();<o:p></o:p></p>
<p class="MsoNormal"> PrivateKey privateKey = null;<o:p></o:p></p>
<p class="MsoNormal"> try {<o:p></o:p></p>
<p class="MsoNormal"> privateKey = issuerCrypto.getPrivateKey(issuerKeyName, issuerKeyPassword);<o:p></o:p></p>
<p class="MsoNormal"> } catch ( Exception e ) {<o:p></o:p></p>
<p class="MsoNormal"> throw new WSSecurityException(e.getMessage(), e);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> sig.setSignatureAlgorithm(signatureAlgorithm);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> BasicX509Credential signingCredential = new BasicX509Credential();<o:p></o:p></p>
<p class="MsoNormal"> signingCredential.setEntityCertificate(issuerCerts[0]);<o:p></o:p></p>
<p class="MsoNormal"> signingCredential.setPrivateKey(privateKey);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> sig.setSigningCredential(signingCredential);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> X509KeyInfoGeneratorFactory kiFactory = new X509KeyInfoGeneratorFactory();<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if ( sendKeyValue == true ) {<o:p></o:p></p>
<p class="MsoNormal"> kiFactory.setEmitPublicKeyValue(true);<o:p></o:p></p>
<p class="MsoNormal"> } else {<o:p></o:p></p>
<p class="MsoNormal"> kiFactory.setEmitEntityCertificate(true);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> try {<o:p></o:p></p>
<p class="MsoNormal"> KeyInfo keyInfo = kiFactory.newInstance().generate(signingCredential);<o:p></o:p></p>
<p class="MsoNormal"> sig.setKeyInfo(keyInfo);<o:p></o:p></p>
<p class="MsoNormal"> } catch ( org.opensaml.xml.security.SecurityException ex ) {<o:p></o:p></p>
<p class="MsoNormal"> throw new WSSecurityException("Error generating KeyInfo from signing credential", ex);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> sa.setSignature(sig);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> SAMLObjectContentReference contentRef = <o:p></o:p></p>
<p class="MsoNormal"> (SAMLObjectContentReference)sa.getContentReferences().get(0);<o:p></o:p></p>
<p class="MsoNormal"> contentRef.setDigestAlgorithm(signatureDigestAlgorithm);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> sa.releaseChildrenDOM(true);<o:p></o:p></p>
<p class="MsoNormal"> sa.releaseDOM();<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Obviously, something is not right here. Can someone point me in the right direction?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b>Stephen W. Chappell<o:p></o:p></b></p>
</div>
</body>
</html>