package testgenerator;

import iaik.ixsil.algorithms.CanonicalizationAlgorithm;
import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplCanonicalXML;
import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplCanonicalXMLWithComments;
import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplExclusiveCanonicalXML;
import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplExclusiveCanonicalXMLWithComments;
import iaik.ixsil.algorithms.DigestAlgorithmImplSHA1;
import iaik.ixsil.algorithms.SignatureAlgorithmImplECDSA;
import iaik.ixsil.algorithms.SignatureAlgorithmImplRSA;
import iaik.ixsil.algorithms.Transform;
import iaik.ixsil.core.Position;
import iaik.ixsil.core.Signer;
import iaik.ixsil.core.SignerManifest;
import iaik.ixsil.core.SignerReference;
import iaik.ixsil.core.SignerSignature;
import iaik.ixsil.core.SignerSignedInfo;
import iaik.ixsil.core.URIResolverParameters;
import iaik.ixsil.init.IXSILConstants;
import iaik.ixsil.keyinfo.KeyManagerImpl;
import iaik.ixsil.keyinfo.retrieval.KeyProviderImplRetrievalMethod;
import iaik.ixsil.keyinfo.retrieval.RetrievalMethod;
import iaik.ixsil.keyinfo.x509.KeyProviderImplX509Data;
import iaik.ixsil.keyinfo.x509.X509Data;
import iaik.ixsil.util.URI;
import iaik.pkcs.pkcs12.PKCS12;
import iaik.security.ecc.interfaces.ECDSAPrivateKey;
import iaik.utils.Base64OutputStream;
import java.io.ByteArrayOutputStream;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xml.serialize.DOMWriterImpl;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;


/**
 * @author Stevie (Admin)
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */
public class CreatePKCSSignature extends TestCases{
	
	private static final int canAlgCanXML = 1;
	private static final int canAlgCanXMLwithCom = 2;
	private static final int canAlgExcXML = 3;
	private static final int canAlgExcXMLwithCom = 4;
	
	private Document doc;
	public Signer signer;
	private SignerSignature signature;
	private SignerSignedInfo signedInfo;
	private PKCS12 pkcs12;
  private String x509CertString;
	public CreatePKCSSignature() throws Exception {
		iaik.security.provider.IAIK.addAsProvider();
		iaik.security.ecc.provider.ECCProvider.addAsProvider();
	}
	
	// Schritt 1
	
	public void init() throws Exception{
	pkcs12 = decryptPKCS12(
				configuration_.getProperty("PKCS12file"),
				configuration_.getProperty("PKCS12password"));

		// Create signature generator
		URI baseURI = new URI(IXSILConstants.DUMMY_ABSURI_);
		signer = new Signer(baseURI);

		// Configure signed information

		// Get interface for signed information
		signature = signer.getSignature();
		signedInfo = signer.getSignature().getSignerSignedInfo();
					
		// Set signature algorithm
		SignatureAlgorithmImplRSA signatureAlg =
			new SignatureAlgorithmImplRSA();
		RSAPrivateKey privateKey = getPrivateKey(pkcs12);
		signatureAlg.setSignerKey(privateKey);
		signedInfo.setSignatureAlgorithm(signatureAlg);		

	}
	public void init(String iD) throws Exception{
	pkcs12 = decryptPKCS12(
				configuration_.getProperty("PKCS12file"),
				configuration_.getProperty("PKCS12password"));

		// Create signature generator
		URI baseURI = new URI(IXSILConstants.DUMMY_ABSURI_);
		signer = new Signer(baseURI);

		// Configure signed information

		// Get interface for signed information
		signature = signer.getSignature();
		signedInfo = signer.getSignature().getSignerSignedInfo();
						
		// Set signature algorithm
		SignatureAlgorithmImplRSA signatureAlg =
			new SignatureAlgorithmImplRSA();
		RSAPrivateKey privateKey = getPrivateKey(pkcs12);
		signatureAlg.setSignerKey(privateKey);
		signedInfo.setSignatureAlgorithm(signatureAlg);		
		signature.setId(iD);
	}
	
  public void init(Document doc, Position position) throws Exception{
  pkcs12 = decryptPKCS12(
        configuration_.getProperty("PKCS12file"),
        configuration_.getProperty("PKCS12password"));

    // Create signature generator
    URI baseURI = new URI(IXSILConstants.DUMMY_ABSURI_);
    signer = new Signer(doc, baseURI, position);

    // Configure signed information

    // Get interface for signed information
    signature = signer.getSignature();
    signedInfo = signer.getSignature().getSignerSignedInfo();
          
    // Set signature algorithm
    SignatureAlgorithmImplRSA signatureAlg =
      new SignatureAlgorithmImplRSA();
    RSAPrivateKey privateKey = getPrivateKey(pkcs12);
    signatureAlg.setSignerKey(privateKey);
    signedInfo.setSignatureAlgorithm(signatureAlg);   

  }	
  
  public void init(Document doc, Position position,String iD) throws Exception{
  pkcs12 = decryptPKCS12(
        configuration_.getProperty("PKCS12file"),
        configuration_.getProperty("PKCS12password"));

    // Create signature generator
    URI baseURI = new URI(IXSILConstants.DUMMY_ABSURI_);
    signer = new Signer(doc, baseURI, position);

    // Configure signed information

    // Get interface for signed information
    signature = signer.getSignature();
    signedInfo = signer.getSignature().getSignerSignedInfo();
          
    // Set signature algorithm
    SignatureAlgorithmImplRSA signatureAlg =
      new SignatureAlgorithmImplRSA();
    RSAPrivateKey privateKey = getPrivateKey(pkcs12);
    signatureAlg.setSignerKey(privateKey);
    signedInfo.setSignatureAlgorithm(signatureAlg); 
    signature.setId(iD);  

  }	
	
	
	public void initECDSA() throws Exception{
	pkcs12 = decryptPKCS12(
				configuration_.getProperty("ECDSPKCS12file"),
				configuration_.getProperty("ECDSPKCS12password"));

		// Create signature generator
		URI baseURI = new URI(IXSILConstants.DUMMY_ABSURI_);
		signer = new Signer(baseURI);

		// Configure signed information

		// Get interface for signed information
		signature = signer.getSignature();
		signedInfo = signer.getSignature().getSignerSignedInfo();
						
		// Set signature algorithm
		SignatureAlgorithmImplECDSA signatureAlg = new SignatureAlgorithmImplECDSA();
		
		ECDSAPrivateKey privateKey = (ECDSAPrivateKey)pkcs12.getKeyBag().getPrivateKey();
		
		signatureAlg.setSignerKey(privateKey);
		signedInfo.setSignatureAlgorithm(signatureAlg);		
		
	    SignerSignature signature = signer.getSignature();
	    SignerSignedInfo signedInfo = signature.getSignerSignedInfo();

  	}

	// Schritt 2
	
	public void setCanoncialization(int CanonicalizationMethodNumber) throws Exception
	{
	// Set canonicalization algorithm			
		CanonicalizationAlgorithm calg = null;

		switch (CanonicalizationMethodNumber) 
		{
			case canAlgCanXML :
				calg = new CanonicalizationAlgorithmImplCanonicalXML(); break;
			case canAlgCanXMLwithCom :
				calg = new CanonicalizationAlgorithmImplCanonicalXMLWithComments(); break;
			case canAlgExcXML :
				calg = new CanonicalizationAlgorithmImplExclusiveCanonicalXML(); break;
			case canAlgExcXMLwithCom :
				calg = new CanonicalizationAlgorithmImplExclusiveCanonicalXMLWithComments(); break;
		}

		signedInfo.setCanonicalizationAlgorithm(calg);	
		
	}
	/**
	 * Method createReference.
	 * @param booelan env: if set, the data-string will be enveloped, else an uri pointing to data will be created
	 * @param data
	 * @throws Exception
	 */
	// Schritt 3.1
	
	public void createEnvelopedDataObject(String iD, String data) throws Exception
	{
			iaik.ixsil.core.Object object = null;
			object = signature.createObject(data);
			object.setId(iD);				
			signature.addObject(object);			
	}
	
	public void createEnvelopedDataObject(String iD, Element doc) throws Exception
	{
		iaik.ixsil.core.Object object = null;
	    object = signature.createObject(doc);
	    object.setId(iD);
	    signature.addObject(object);		
	}
	
	public void createReference(URI uri, URI type) throws Exception
	{
		SignerReference reference = signedInfo.createReference();

		reference.setURI(uri);
		reference.setType(type);
		DigestAlgorithmImplSHA1 digestAlg =
			new DigestAlgorithmImplSHA1();
			
		reference.setDigestAlgorithm(digestAlg);
		signedInfo.addReference(reference);
				
	}
	
	public void createReference(boolean env, String data, String iD) throws Exception
	{
		SignerReference reference = signedInfo.createReference();

			if (env) {
				iaik.ixsil.core.Object object = null;
				object = signature.createObject(data);
				object.setId("envelopedData");
				signature.addObject(object);				

				DigestAlgorithmImplSHA1 digestAlg =
					new DigestAlgorithmImplSHA1();					
				reference.setDigestAlgorithm(digestAlg);

				reference.setURI(
					new URI("#xpointer(id('envelopedData')/node())"));
			} else {
				// Create and configure reference
				URI refURI = null;
				String baseDir = configuration_.getProperty("baseDir");
				refURI = new URI(data);

				reference.setURI(refURI);
				if (iD!=null) 
					reference.setId(iD);
				DigestAlgorithmImplSHA1 digestAlg =
					new DigestAlgorithmImplSHA1();
				reference.setDigestAlgorithm(digestAlg);
			}
			
			signedInfo.addReference(reference);
				
	}
	public void createReference(boolean env, String data) throws Exception
	{
		createReference(env,data,null);
	}
	
	public void createETSIObjects(String data) throws Exception
	{
		SignerReference reference = signedInfo.createReference();
		
		URI refURI = null;
		refURI = new URI(data);
	
		reference.setURI(new URI("#xmlns(etsi=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('etsi-signed-1-1')/child::etsi:QualifyingProperties/child::etsi:SignedProperties)"));
		reference.setType(new URI("http://uri.etsi.org/01903/v1.1.1#SignedProperties"));
		DigestAlgorithmImplSHA1 digestAlg = new DigestAlgorithmImplSHA1();
		reference.setDigestAlgorithm(digestAlg);
	
		signedInfo.addReference(reference);
		
		iaik.ixsil.core.Object object = null;
	    object = signature.createObject(getElement("TEST"));
	    object.setId("etsi-signed-1-1");
	    signature.addObject(object);
	}
	
	public Element getElement(String data) throws Exception
	{
		String etsinamespace = "http://uri.etsi.org/01903/v1.1.1#";
		
		getX509Content();
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		//dbf.setNamespaceAware(true);
		//dbf.setValidating(true);
		
		Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		
		
		Element qualprop = doc.createElementNS(etsinamespace,"etsi:QualifyingProperties");
		qualprop.setAttributeNS(null,"Target","#signature-1-1");
		qualprop.setAttributeNS(IXSILConstants.NAMESPACE_URI_NAMESPACES_,"xmlns:etsi",etsinamespace);
		//qualprop.setPrefix("etsi");*/
		//qualprop.setAttributeNodeNS(doc.createAttributeNS(etsinamespace,"etsi"));
		Element signprop = doc.createElementNS(etsinamespace,"etsi:SignedProperties");
		Element signsigprop = doc.createElementNS(etsinamespace,"etsi:SignedSignatureProperties");
		Element signdataobjectprop = doc.createElementNS(etsinamespace,"etsi:SignedDataObjectProperties");
		Element signdate = doc.createElementNS(etsinamespace,"etsi:SigningTime");
		Text datevalue = doc.createTextNode("2003-05-10T00:01:01");
		Element signcert = doc.createElementNS(etsinamespace,"etsi:SigningCertificate");
		Element cert = doc.createElementNS(etsinamespace,"etsi:Cert");
		Element signpolyident = doc.createElementNS(etsinamespace,"etsi:SignaturePolicyIdentifier");
		Element signpolyimp = doc.createElementNS(etsinamespace,"etsi:SignaturePolicyImplied");
		Element certdig = doc.createElementNS(etsinamespace,"etsi:CertDigest");
		Element digmeth = doc.createElementNS(etsinamespace,"etsi:DigestMethod");
		digmeth.setAttribute("Algorithm","http://www.w3.org/2000/09/xmldsig#sha1");
		Element digvalue = doc.createElementNS(etsinamespace,"etsi:DigestValue");
		
		ByteArrayOutputStream fos = new ByteArrayOutputStream();
		Base64OutputStream base64os = new Base64OutputStream(fos);
		base64os.write(this.X509hash.getBytes());
		base64os.flush();

		Text dig_value = doc.createTextNode(fos.toString());
		Element is = doc.createElementNS(etsinamespace,"etsi:IssuerSerial");
		Element i = doc.createElement("dsig:X509IssuerName");
		Text i_value = doc.createTextNode(this.X509name);
		Element s = doc.createElement("dsig:X509SerialNumber");
		Text s_value = doc.createTextNode(this.X509number.toString());
		Element dataobjformat = doc.createElementNS(etsinamespace,"etsi:DataObjectFormat");
		dataobjformat.setAttribute("ObjectReference","#reference-1-1");
		Element mimetype = doc.createElementNS(etsinamespace,"etsi:MimeType");
		//mimetype.setNodeValue("text/plain");
		Text mimevalue = doc.createTextNode("text/html");
		
		qualprop.appendChild(signprop);
			signprop.appendChild(signsigprop);
				signsigprop.appendChild(signdate);
					signdate.appendChild(datevalue);
				signsigprop.appendChild(signcert);
					signcert.appendChild(cert);
						cert.appendChild(certdig);
							certdig.appendChild(digmeth);
							certdig.appendChild(digvalue);
								digvalue.appendChild(dig_value);
						cert.appendChild(is);
							is.appendChild(i);
								i.appendChild(i_value);
							is.appendChild(s);
								s.appendChild(s_value);
				signsigprop.appendChild(signpolyident);
					signpolyident.appendChild(signpolyimp);
			signprop.appendChild(signdataobjectprop);
				signdataobjectprop.appendChild(dataobjformat);
					dataobjformat.appendChild(mimetype);
						mimetype.appendChild(mimevalue);
				
		
		
		return qualprop;
	}
	
	
	
	public void createReferenceEnvElement(Element data) throws Exception
	{
		SignerReference reference = signedInfo.createReference();

				iaik.ixsil.core.Object object = null;
				object = signature.createObject(data);
				object.setId("envelopedData");
				signature.addObject(object);				

				DigestAlgorithmImplSHA1 digestAlg =
					new DigestAlgorithmImplSHA1();					
				reference.setDigestAlgorithm(digestAlg);

				reference.setURI(
					new URI("#xpointer(Data/node())"));
			
			
			signedInfo.addReference(reference);
				
	}	
	public void createReferenceWithTransforms(URI uriToData, Transform[] transforms) throws Exception
	{
		createReferenceWithTransforms(uriToData, transforms,null);
	}
	
		public void createReferenceWithTransforms(URI uriToData, Transform[] transforms, String iD) throws Exception
	{
		SignerReference reference = signedInfo.createReference();

				// Create and configure reference
				URI refURI = null;
				//String baseDir = configuration_.getProperty("baseDir");
				refURI = uriToData;
				
				reference.setURI(refURI);
				if (iD!=null)
				reference.setId(iD);
				
				DigestAlgorithmImplSHA1 digestAlg =
					new DigestAlgorithmImplSHA1();
				reference.setDigestAlgorithm(digestAlg);
	
			for (int trNr=0; trNr < transforms.length; trNr++)
			{
				reference.insertTransformAt(transforms[trNr],trNr);
				//transforms[trNr].transform();
			}
			
			signedInfo.addReference(reference);
			
	
	}	
	public Element createReferenceWithManifest(
		URI uriToData1, String iD1) throws Exception
	{
		return createReferencesWithManifest(uriToData1,iD1,null);
	}
	
	public Element createReferenceWithManifest(
		URI uriToData1, String iD1, String type) throws Exception
	{
		/*	  
		public void createReferenceWithManifest(
		URI uriToData1, String iD1,
		URI uriToData2, String iD2
		) throws Exception
		*/
		SignerReference reference = signedInfo.createReference();		
			SignerManifest manifest = signer.createManifest();
			SignerReference manifestRef = manifest.createReference();

			DigestAlgorithmImplSHA1 digestAlg = new DigestAlgorithmImplSHA1();
			manifestRef.setDigestAlgorithm(digestAlg);

			manifestRef.setURI(uriToData1);
			manifest.addReference(manifestRef);
			
			manifest.setId(iD1);
			iaik.ixsil.core.Object manifestObject =
				signature.createObject(manifest);
			signature.addObject(manifestObject);
			manifest.computeDigestValues();
			
			reference = signedInfo.createReference();
			reference.setURI(new URI("#xpointer(id('"+iD1+"'))"));
			if (type==null) 
			reference.setType(
				new URI(IXSILConstants.REFERENCETYPE_ATTR_VALUE_MANIFEST_));			
			else
			reference.setType(new URI(type));
			
			reference.setDigestAlgorithm(new DigestAlgorithmImplSHA1());

			// Add reference to signature
			signedInfo.addReference(reference);
			return manifest.toElement();
	}
	
	public Element createReferencesWithManifest(
		URI uriToData1, String iD1,
		URI uriToData2
		) throws Exception
	{
		/*	  
		public void createReferenceWithManifest(
		URI uriToData1, String iD1,
		URI uriToData2, String iD2
		) throws Exception
		*/
		SignerReference reference = signedInfo.createReference();		
			
			SignerManifest manifest = signer.createManifest();			
			
			
			DigestAlgorithmImplSHA1 digestAlg = new DigestAlgorithmImplSHA1();

			SignerReference manifestRef = manifest.createReference();
			manifestRef.setDigestAlgorithm(digestAlg);						
			manifestRef.setURI(uriToData1);
			manifest.addReference(manifestRef);
			
			if (uriToData2!=null)
			{
				SignerReference manifestRef2 = manifest.createReference();
				manifestRef2.setDigestAlgorithm(digestAlg);
				manifestRef2.setURI(uriToData2);
				manifest.addReference(manifestRef2);
			}
			manifest.setId(iD1);
			iaik.ixsil.core.Object manifestObject =
				signature.createObject(manifest);
			signature.addObject(manifestObject);
			manifest.computeDigestValues();

			reference = signedInfo.createReference();
			reference.setURI(new URI("#xpointer(id('"+iD1+"'))"));
			reference.setType(
				new URI(IXSILConstants.REFERENCETYPE_ATTR_VALUE_MANIFEST_));
			reference.setDigestAlgorithm(new DigestAlgorithmImplSHA1());

			// Add reference to signature
			signedInfo.addReference(reference);
			/*
			if (iD2!=null)
			{
			SignerReference reference2 = signedInfo.createReference();
			SignerManifest manifest2 = signer.createManifest();
			SignerReference manifestRef2 = manifest.createReference();

		
			manifestRef2.setDigestAlgorithm(digestAlg);

			manifestRef2.setURI(uriToData2);

			manifest2.addReference(manifestRef2);
			manifest2.setId(iD2);
			iaik.ixsil.core.Object manifestObject2 =
				signature.createObject(manifest2);
			signature.addObject(manifestObject2);
			manifest2.computeDigestValues();

			reference2 = signedInfo.createReference();
			reference2.setURI(new URI("#xpointer(id('"+iD1+"'))"));
			reference2.setType(
				new URI(IXSILConstants.REFERENCETYPE_ATTR_VALUE_MANIFEST_));
			reference2.setDigestAlgorithm(new DigestAlgorithmImplSHA1());

			// Add reference to signature
			signedInfo.addReference(reference2);
			
			}
			*/
			return manifest.toElement();
	}

public Element createReferencesWithManifest(
    URI uriToData1, String iD1,
    URI uriToData2, String type
    ) throws Exception
  {
    SignerReference reference = signedInfo.createReference();   
      
      SignerManifest manifest = signer.createManifest();      
      
      
      DigestAlgorithmImplSHA1 digestAlg = new DigestAlgorithmImplSHA1();

      SignerReference manifestRef = manifest.createReference();
      manifestRef.setDigestAlgorithm(digestAlg);            
      manifestRef.setURI(uriToData1);
      manifest.addReference(manifestRef);
      
      SignerReference manifestRef2 = manifest.createReference();
      manifestRef2.setDigestAlgorithm(digestAlg);
      manifestRef2.setURI(uriToData2);
      manifest.addReference(manifestRef2);
  
      manifest.setId(iD1);
      iaik.ixsil.core.Object manifestObject =
        signature.createObject(manifest);
      signature.addObject(manifestObject);
      manifest.computeDigestValues();

      reference = signedInfo.createReference();
      reference.setURI(new URI("#xpointer(id('"+iD1+"'))"));
      reference.setType(new URI(type));
      reference.setDigestAlgorithm(new DigestAlgorithmImplSHA1());

      // Add reference to signature
      signedInfo.addReference(reference);
      return manifest.toElement();
  }
	
	
	public void setKeyInformation() throws Exception 
	{
			// Create key information
		KeyManagerImpl keyManager = new KeyManagerImpl(signer.toDocument());

		
			X509Certificate[] certs = getCertificates(pkcs12);
			X509Data x509Data = new X509Data();
    
			for (int i = 0; i < certs.length; i++) {
				x509Data.insertHintAt(certs[i], i);
			}

			KeyProviderImplX509Data x509DataKeyProvider =
				new KeyProviderImplX509Data(signer.toDocument());

			x509DataKeyProvider.insertX509DataAt(x509Data, 0);

			// X509Data key information (certificate chain)
			keyManager.addKeyProvider(x509DataKeyProvider);

	    Element e = (Element)keyManager.getKeyInfo();
      NodeList nl = e.getChildNodes();
      x509CertString = ((new DOMWriterImpl(true)).writeToString(nl.item(0).getChildNodes().item(1)));
      if(x509CertString==null)
	      x509CertString = ((new DOMWriterImpl(true)).writeToString(nl.item(0).getChildNodes().item(0)));

		signer.getSignature().setKeyManager(keyManager);
		
		

	}
		public void setKeyInformation(String retrievalMethod) throws Exception 
	{		// Create key information
		KeyManagerImpl keyManager = new KeyManagerImpl(signer.toDocument());

		KeyProviderImplRetrievalMethod x509RetrievalMethod =
				new KeyProviderImplRetrievalMethod(signer.toDocument());

			URI fileURI = null;

			if (retrievalMethod == "XML")
				fileURI =
					new URI(
						"file:"
							+ configuration_.getProperty("baseDir")
							+ configuration_.getProperty("RetrievalURIXML"));
			else
				fileURI =
					new URI(
						"file:"
							+ configuration_.getProperty("baseDir")
							+ configuration_.getProperty("RetrievalURIRaw"));

			RetrievalMethod retMet =
				new RetrievalMethod(
					signer.toDocument(),
					new URIResolverParameters(fileURI));

			retMet.setURI(fileURI);

			if (retrievalMethod == "XML")
				retMet.setType(
					new URI(configuration_.getProperty("RetrievalTypeXML")));
			else
				retMet.setType(
					new URI(configuration_.getProperty("RetrievalTypeRaw")));

			x509RetrievalMethod.insertRetrievalMethodAt(retMet, 0);
			keyManager.addKeyProvider(x509RetrievalMethod);
		 Element e = (Element)keyManager.getKeyInfo();
      NodeList nl = e.getChildNodes();
      x509CertString = ((new DOMWriterImpl(true)).writeToString(nl.item(0).getChildNodes().item(0)));


		signer.getSignature().setKeyManager(keyManager);
	}
	
	public void setKeyInformation(int pos) throws Exception 
	{
			// Create key information
		KeyManagerImpl keyManager = new KeyManagerImpl(signer.toDocument());

		
			X509Certificate[] certs = getCertificates(pkcs12);
			X509Data x509Data = new X509Data();
    
			x509Data.insertHintAt(certs[pos], 0);


			KeyProviderImplX509Data x509DataKeyProvider =
				new KeyProviderImplX509Data(signer.toDocument());

			x509DataKeyProvider.insertX509DataAt(x509Data, 0);

			// X509Data key information (certificate chain)
			keyManager.addKeyProvider(x509DataKeyProvider);

			signer.getSignature().setKeyManager(keyManager);
			
			Element e = (Element)keyManager.getKeyInfo();
      NodeList nl = e.getChildNodes();
      x509CertString = ((new DOMWriterImpl(true)).writeToString(nl.item(0).getChildNodes().item(0)));
			
			//((Element)signer.getSignature().getSignatureDOMElement().getChildNodes().item(0)).setAttributeNS(IXSILConstants.NAMESPACE_URI_NAMESPACES_,"xmlns:data","http://uri.data.org");
			
			//display(signer.getSignature().getSignatureDOMElement());
	}
	
	private void display(Node base)
	{
		display(base,1);
	}
	
	private void display(Node base,int level)
	{
		String spacer = "";
		for(int counter=0;counter<level;counter++)
		{
			spacer+="  ";
		}		
	
		int att_size=0;	
		if(base.getAttributes()!=null)
		{
			att_size=base.getAttributes().getLength();
		}
		if(base.getNodeName().equals("#text"))
			System.out.println(spacer+base.getNodeName()+base.getChildNodes().getLength()+":"+att_size+" ("+base.getNodeValue()+")");
		else
			System.out.println(spacer+base.getNodeName()+base.getChildNodes().getLength()+":"+att_size);
		
		NamedNodeMap nnm = base.getAttributes();
		if(nnm!=null)
		{
			int size = nnm.getLength();
			for(int counter=0;counter<size;counter++)
			{
				display(nnm.item(counter),level+3);
			}
		}
		
		NodeList children = base.getChildNodes();
		int size = children.getLength();
		for(int counter=0;counter<size;counter++)
		{
			display(children.item(counter),level+1);
		}
	}
	
	public void setKeyInformation(boolean xpointer, URI fileURI, URI typeURI, Transform[] transforms) throws Exception 
	{		// Create key information
		KeyManagerImpl keyManager = new KeyManagerImpl(signer.toDocument());

		KeyProviderImplRetrievalMethod x509RetrievalMethod =
				new KeyProviderImplRetrievalMethod(signer.toDocument());
			
			RetrievalMethod retMet = null;
			
			if (xpointer) 
				{
					retMet = new RetrievalMethod(signer.toDocument(),null);
				}
			 	else
			 	{
			 		retMet = new RetrievalMethod(signer.toDocument(),new URIResolverParameters(fileURI));
			 	}
			 	
			 	
			
			retMet.setURI(fileURI);

		
			retMet.setType(typeURI);
			
			if (transforms!=null)
			{for (int trNr=0; trNr < transforms.length; trNr++)
			retMet.insertTransformAt(transforms[trNr],trNr);
			}
		

			x509RetrievalMethod.insertRetrievalMethodAt(retMet, 0);
			keyManager.addKeyProvider(x509RetrievalMethod);

 Element e = (Element)keyManager.getKeyInfo();
      NodeList nl = e.getChildNodes();
      x509CertString = ((new DOMWriterImpl(true)).writeToString(nl.item(0).getChildNodes().item(0)));
		

		signer.getSignature().setKeyManager(keyManager);

	
	}
	
/*	public Document createPKCS12Sig(
		String TestNumber,
		int CanonicalizationMethodNumber,
		String data,
		boolean env,
		boolean mani,
		String data2,
		boolean env2,
		String retrievalMethod)
		throws Exception {
		
		
		
		if (data2 != null) {
			reference = signedInfo.createReference();
			if (env2) {
				iaik.ixsil.core.Object object = null;
				object = signature.createObject(data2);
				object.setId("envelopedData2");
				signature.addObject(object);

				DigestAlgorithmImplSHA1 digestAlg =
					new DigestAlgorithmImplSHA1();
				reference.setDigestAlgorithm(digestAlg);

				reference.setURI(
					new URI("#xpointer(id('envelopedData2')/node())"));
			} else {
				// Create and configure reference
				URI refURI = null;
				String baseDir = configuration_.getProperty("baseDir");
				refURI = new URI(data2);

				reference.setURI(refURI);
				DigestAlgorithmImplSHA1 digestAlg =
					new DigestAlgorithmImplSHA1();
				reference.setDigestAlgorithm(digestAlg);
			}
			signedInfo.addReference(reference);
		}

		// Add reference to signature

		
	
		// Compute signature value
		signer.getSignature().sign();

		return signer.toDocument();
	}
*/	
	public Document returnSig() throws Exception {
    //signature.getObjects();
    
		signer.getSignature().sign();
		
		//((Element)signer.getSignature().getSignatureDOMElement().getChildNodes().item(0)).removeAttribute("xmlns:data");
		//display(((Element)signer.getSignature().getSignatureDOMElement().getChildNodes().item(0)));
		//.removeAttributeNS(IXSILConstants.NAMESPACE_URI_NAMESPACES_,"xmlns:data");
		
		return signer.toDocument();
		
	}
  public String getX509CertString() throws Exception{
    TestCases tc = new TestCases();

	if(x509CertString==null) return null;
    String result = TestCases.replaceString(x509CertString,"<?xml version=\"1.0\"?>","");
    if(x509CertString.indexOf("xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\"")!=-1)
	    result = TestCases.replaceString(result,"xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\"","");
	   
    return result; 
  }
}