Hi Paul, The problem is that your Document is not namespace aware. Change the following line:
> docFactory.setNamespaceAware( false ); to > docFactory.setNamespaceAware( true ); Now you need to update your XPath expressions with the "ds" prefix, e.g.: "/aaa/ds:Signature", "/aaa/ds:Signature/ds:SignedInfo/ds:Reference/ds:DigestValue/text()", and finally pass in org.apache.xml.security.test.DSNamespaceContext to the executeXPath method as the NamespaceContext implementation. Then the XPaths work without the final transformation step. Colm. On Thu, Jan 26, 2012 at 10:21 PM, Paul <[email protected]> wrote: > > Sorry about not getting back to this issue - I was on vacation and then had > the > flu... > > I reworked the example to remove the p12 file and now everything is > standalone. > The only thing needed is an xmlsec jar file to use and in my test I was using > 1.4.5. > > I don't have a JIRA login so I thought I would post the complete code here: > > ------------------------------------------------------------- > import java.io.ByteArrayInputStream; > import java.io.ByteArrayOutputStream; > import java.io.File; > import java.io.FileInputStream; > import java.io.StringWriter; > import java.security.KeyPair; > import java.security.KeyPairGenerator; > import java.security.KeyStore; > import java.security.Security; > import java.security.cert.X509Certificate; > import java.util.ArrayList; > import java.util.Collections; > import java.util.List; > > import javax.xml.crypto.dsig.CanonicalizationMethod; > import javax.xml.crypto.dsig.DigestMethod; > import javax.xml.crypto.dsig.Reference; > import javax.xml.crypto.dsig.SignatureMethod; > import javax.xml.crypto.dsig.SignedInfo; > import javax.xml.crypto.dsig.Transform; > import javax.xml.crypto.dsig.XMLSignature; > import javax.xml.crypto.dsig.XMLSignatureFactory; > import javax.xml.crypto.dsig.dom.DOMSignContext; > import javax.xml.crypto.dsig.keyinfo.KeyInfo; > import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; > import javax.xml.crypto.dsig.keyinfo.KeyValue; > import javax.xml.crypto.dsig.keyinfo.X509Data; > import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; > import javax.xml.crypto.dsig.spec.TransformParameterSpec; > import javax.xml.namespace.NamespaceContext; > import javax.xml.namespace.QName; > import javax.xml.parsers.DocumentBuilder; > import javax.xml.parsers.DocumentBuilderFactory; > import javax.xml.transform.Transformer; > import javax.xml.transform.TransformerException; > import javax.xml.transform.TransformerFactory; > import javax.xml.transform.dom.DOMSource; > import javax.xml.transform.stream.StreamResult; > import javax.xml.xpath.XPath; > import javax.xml.xpath.XPathConstants; > import javax.xml.xpath.XPathExpression; > import javax.xml.xpath.XPathFactory; > > import org.w3c.dom.Document; > import org.w3c.dom.NodeList; > > > public class XmlSignerWithDoTransformIssue > { > public static void main( String[] args ) > { > try > { > Tester tester = new Tester(); > System.out.println( > "----------------------------------- > ------------------" ); > tester.signAndDoXpaths( true ); > System.out.println( > "----------------------------------- > ------------------" ); > tester.signAndDoXpaths( false ); > } > catch ( Exception ex ) > { > System.out.println( "ex = " + ex.toString() ); > ex.printStackTrace(); > } > } > } > > class Tester > { > > public void signAndDoXpaths( boolean doFinalTransform ) > throws Exception > { > > System.out.println( "running w/ doFinalTransform set to " + > doFinalTransform + "\n\n" ); > > String xml = > "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + > "<aaa>" + > " <bbb>PD94bWwgdm</bbb>" + > > "</aaa>"; > > DocumentBuilderFactory docFactory = > DocumentBuilderFactory.newInstance(); > docFactory.setNamespaceAware( false ); > DocumentBuilder builder = docFactory.newDocumentBuilder(); > Document doc = builder.parse( new ByteArrayInputStream( > xml.getBytes() ) ); > > XMLSignatureFactory fac = XMLSignatureFactory.getInstance > ("DOM"); > > Reference ref = fac.newReference > ("", fac.newDigestMethod(DigestMethod.SHA1, null), > Collections.singletonList > (fac.newTransform > (Transform.ENVELOPED, (TransformParameterSpec) null)), > null, null); > > SignedInfo si = fac.newSignedInfo > (fac.newCanonicalizationMethod > (CanonicalizationMethod.INCLUSIVE, > (C14NMethodParameterSpec) null), > fac.newSignatureMethod( SignatureMethod.RSA_SHA1, null), > Collections.singletonList(ref)); > > KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); > kpg.initialize(512); > KeyPair kp = kpg.generateKeyPair(); > > KeyInfoFactory kif = fac.getKeyInfoFactory(); > KeyValue kv = kif.newKeyValue(kp.getPublic()); > > KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); > > DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), > doc.getDocumentElement()); > > XMLSignature signature = fac.newXMLSignature(si, ki); > signature.sign(dsc); > > // Output the resulting document - this seems to be a critical > step that allows > // stuff like xpaths to work > if ( doFinalTransform == true ) > { > ByteArrayOutputStream baos = new ByteArrayOutputStream > (); > TransformerFactory tf = TransformerFactory.newInstance > (); > Transformer trans = tf.newTransformer(); > trans.transform( new DOMSource(doc), new StreamResult( > baos ) ); > String signedString = baos.toString(); > ByteArrayInputStream bais = new ByteArrayInputStream( > signedString.getBytes() ); > > doc = docFactory.newDocumentBuilder().parse( bais ); > } > > System.out.println( "xml signed successfully"); > > System.out.println( "xml:\n" + convertDocToString( doc ) ); > > String[] xpathList = new String[] > { > "/aaa/Signature", > "/aaa/Signature/SignedInfo/Reference/DigestValue/text > ()", > "/aaa/Signature/SignatureValue/text()", > "/aaa/Signature/KeyInfo/X509Data/X509Certificate/text > ()", > "/aaa/ns:Signature", > }; > > System.out.println( "\nrunning xpaths: \n" ); > > for ( String xPathFromList : xpathList ) > { > if ( xPathFromList.contains( "substring" ) || > xPathFromList.contains( "concat" ) ) > executeXPath( doc, xPathFromList, > XPathConstants.STRING, null ); > else > executeXPath( doc, xPathFromList, > XPathConstants.NODESET, null ); > } > } > > public Object executeXPath( Document doc, String strExpr, QName > xpathConstant, > NamespaceContext nsCtx ) throws Exception > { > Object result = null; > > System.out.println( "----" + strExpr + "----" ); > > XPathFactory xpathFactory = XPathFactory.newInstance(); > XPath xpath = xpathFactory.newXPath(); > > if ( nsCtx != null ) > xpath.setNamespaceContext( nsCtx ); > > XPathExpression expr = xpath.compile( strExpr ); > > if ( xpathConstant.equals( XPathConstants.NODESET ) ) > { > > result = expr.evaluate( doc, xpathConstant /* > XPathConstants.NODESET */ ); > > NodeList nodes = (NodeList) result; > int len = nodes.getLength(); > System.out.println( "num nodes = " + len ); > for (int i = 0; i < nodes.getLength(); i++) > { > System.out.println( nodes.item( i ).getNodeName > () ); > System.out.println( nodes.item( i > ).getNodeValue > () ); > //System.out.println( nodes.item( i > ).getBaseURI > () ); > //nodes.item( i ).get > } > > } > else if ( xpathConstant.equals( XPathConstants.NUMBER ) ) > { > result = expr.evaluate( doc, > xpathConstant /*XPathConstants.NUMBER */ ); > double dResult = Double.parseDouble( result.toString > () ); > System.out.println( "number = " + dResult ); > } > else if ( xpathConstant.equals( XPathConstants.STRING ) ) > { > result = expr.evaluate( doc, xpathConstant ); > String str = result.toString(); > System.out.println( "string = " + str ); > } > > System.out.println( "-----------------" ); > > return result; > } > > private String convertDocToString( Document doc ) > { > try > { > DOMSource domSource = new DOMSource( doc ); > StringWriter writer = new StringWriter(); > StreamResult result = new StreamResult( writer ); > TransformerFactory tf = TransformerFactory.newInstance > (); > Transformer transformer = tf.newTransformer(); > transformer.transform( domSource, result ); > writer.flush(); > return writer.toString(); > } > catch ( TransformerException ex ) > { > ex.printStackTrace(); > return null; > } > } > } > ----------------------------------------------------- > > > > thanks, > Paul. > > -- Colm O hEigeartaigh Talend Community Coder http://coders.talend.com
