santuario-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul <ppa...@yahoo.com>
Subject Re: xmlsec test
Date Thu, 26 Jan 2012 22:21:48 GMT

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.



Mime
View raw message