Signing multiple objects?

Brad Cox bradjcox at gmail.com
Tue Nov 1 14:21:29 GMT 2011


Making progress; getting plausible signed envelopes and shooting now for
validation, but need a bit more help decoding the instructions at the very
bottom.

The first sentence is what sent me on the prior wild goose chase. As I read
this, "SAMLObject" means an instance of Envelope (right?). Problem is at
this point exists only as as Element, and I've so far been unable to
marshal that to an Envelope. And in any event Envelope doesn't have a
setSignature() method.

So what I have now works entirely at the DOM level which doesn't seem
right.

public void attachSamlAssertion(Document document)
 {
Element soapEnvelope = document.getDocumentElement();
Element soapHeader = DOMUtil.getSoapHeader(soapEnvelope);
 Element soapBody = DOMUtil.getSoapBody(soapEnvelope);

try
 {
SecurityMarshaller m3 = new SecurityMarshaller();
Element securityElmt = m3.marshall(newSecurity(), document);
 soapHeader.appendChild(securityElmt);

Signature signature = newSignature();
 SignatureMarshaller sigM = new SignatureMarshaller();
Element signatureElmt = sigM.marshall(signature, document);
 securityElmt.appendChild(signatureElmt);

TimestampMarshaller tsm = new TimestampMarshaller();
 Element timeStampElmt = tsm.marshall(newTimeStamp(), document);
securityElmt.appendChild(timeStampElmt);

MessageIDMarshaller mim= new MessageIDMarshaller();
Element msgIDElmt = mim.marshall(newMessageID(), document);
 securityElmt.appendChild(msgIDElmt);

Assertion assertion = newAssertion();
 AssertionMarshaller marshaller = new AssertionMarshaller();
Element assertionElmt = marshaller.marshall(assertion, document);
 securityElmt.appendChild(assertionElmt);

log.info("Unsigned Document\n{}", XMLHelper.prettyPrintXML(soapEnvelope));

Signer.signObject(signature);
log.info("Signed Envelope\n{}", XMLHelper.prettyPrintXML(soapEnvelope));
 // Worrisome but without it getDocumentElement == null
document.adoptNode(soapEnvelope);
 document.appendChild(soapEnvelope);
return;
}
 catch (Exception e)
{
throw new XacmlFault(e);
 }
}

Next I've been unable to decode Step#5 to generate a KeyInfo which I think
I'll need for validation (right?).

Fails with a null pointer on the line marked NPE -> below

public Signature newSignature()
{
 SignatureBuilder bldr = (SignatureBuilder)
factory.getBuilder(Signature.DEFAULT_ELEMENT_NAME);
Signature sig = (Signature) bldr.buildObject();
 Credential credential = signer.getCredential();
sig.setSigningCredential(credential);

sig.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
sig.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);

KeyInfoGeneratorManager kgm = new KeyInfoGeneratorManager();
KeyInfoGeneratorFactory kif = kgm.getFactory(credential);
NPE-> KeyInfoGenerator kig = kif.newInstance();
try
{
 KeyInfo ki = kig.generate(credential);
sig.setKeyInfo(ki);
// KeyInfoFactory kFactory = factory.getKeyInfoFactory();
// keyInfo = kFactory.newKeyInfo(Collections.singletonList
(kFactory.newX509Data
// (Collections.singletonList (entry.getCertificate ()))));
 }
catch (SecurityException ex)
{
 throw new XacmlFault("KeyInfo fault", ex);
}

URIContentReference contentReference = new URIContentReference("");

contentReference.getTransforms().add(SignatureConstants.TRANSFORM_ENVELOPED_SIGNATURE);
contentReference.getTransforms().add(SignatureConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);

contentReference.setDigestAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA1);
sig.getContentReferences().add(contentReference);
 return sig;
}

Here are the instructions I've been trying to follow. (Wouldn't a code
sample be easier?)

The first step in signing a SAMLObject is to create a Signature object and
attach it to the SAMLObject. Since all SAMLObjects that can be signed
implement the interface org.opensaml.common.SignableSAMLObject the code to
sign an object is always the same.


   1. Create a Signature object using the
      org.opensaml.xml.signature.impl.SignatureBuilder (this is found in
      the XMLTooling library). This will likely be obtained from a builder
      factory. See Creating SAML Objects from
Scratch<https://wiki.shibboleth.net/confluence/display/OpenSAML/OSTwoUsrManJavaCreateFromScratch>
      .
      2. Add the Credential containing the signing key using the
      Signature#setSigningCredential(Credential) method.
      3. Add the signature method algorithm URI with the method
      Signature#setSignatureAlgorithm(String). Note that the algorithm URI
      is dependent on the type of key contained with the signing credential.
      4. Add the canonicalization method algorithm URI with the method
      Signature#setCanonicalizationAlgorithm(String). Note that unless
      there is good reason to do otherwise, and the ramifications are
understood,
      the recommended canonicalization method for SAML signature use cases is
      exclusive canonicalization (with or without comments).
      5. If desired, add a KeyInfo containing information about the
      signature verification key using Signature#setKeyInfo(KeyInfo). The
      KeyInfo may be created manually, or may be generated dynamically from
      the signing credential using a KeyInfoGenerator, usually obtained
      from a KeyInfoGeneratorFactory via a KeyInfoGeneratorManager.
      6. Add the Signature to the SAMLObject using the
      setSignature(Signature) method. A SAMLObjectContentReference will
      automatically be added to the list of signature references exposed via
      Signature#getContentReferences(), so you should *NOT* explicitly add
      a reference to the signature. Note that the Signature contained
      within a signed element in SAML may contain only one Reference in the
      SignedInfo, per the SAML signature profile.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://shibboleth.net/pipermail/dev/attachments/20111101/a8fc3700/attachment.html 


More information about the dev mailing list