package tsun.com;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;

import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.transforms.params.InclusiveNamespaces;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class SignRequest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		org.apache.xml.security.Init.init();
		String keystoreType = "JKS";
        String keystoreFile = "c:\\ssoserver.jks";
        String keystorePass = "welcome1";
        String issuer = "ssoserver@demo2.autc.com";

        KeyStore keyStore = KeyStore.getInstance(keystoreType);
        FileInputStream fis = new FileInputStream(keystoreFile);
        
        keyStore.load(fis, keystorePass.toCharArray());

      //get the private key for signing.
        PrivateKey key = (PrivateKey) keyStore.getKey(issuer,
        		keystorePass.toCharArray());
        
        
        File f = new File("c://request.xml");
        System.out.println("Trying to verify " + f.toURL().toString());

        

        // Obtain a builder factory instance
        javax.xml.parsers.DocumentBuilderFactory dbf =
                javax.xml.parsers.DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
        
        // Create a document builder
        javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
        db.setErrorHandler(new org.apache.xml.security.utils.IgnoreAllErrorHandler());

        // parse the input document
        org.w3c.dom.Document doc = db.parse(new java.io.FileInputStream(f));
        Element root = doc.getDocumentElement();
		 
		 NodeList nodeList = doc.getElementsByTagNameNS("urn:oasis:names:tc:SAML:1.0:protocol", "Request");
		 Node node = nodeList.item(0);
		 if(node.getNodeType() == Node.ELEMENT_NODE){
		 	String URI = ((Element)node).getNamespaceURI();
		 	((Element)node).setIdAttributeNS(null, "RequestID", true);
		 }
		 
		XMLSignature sig = new XMLSignature(doc, "", XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
		// Create canonical XML

		Transforms transforms = new Transforms(doc);
		transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
		doc.createElementNS(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES);
		InclusiveNamespaces incNS = new InclusiveNamespaces(doc, "code ds kind rw saml samlp typens #default xsd xsi");
		transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, incNS.getElement());


		// Create canonicalized document to signature
		sig.addDocument("", transforms, MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1);


		try{
		    java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate)keyStore.getCertificate(issuer);
		    sig.addKeyInfo(cert);
		}catch(Exception e){
			System.out.println("Failed to add keyInfoL: " + e);
		}
		root.appendChild(sig.getElement());

		//produce a signature
		sig.sign(key);  // signs the document using the private key
		
		File f2 = new File("c:\\signed.xml");
		 FileOutputStream fos = new FileOutputStream(f2);
	        // Output the memory document using XMLUtils.
	        XMLUtils.outputDOMc14nWithComments(doc, fos);

	}

}
