package cat.cert;

import java.util.Hashtable;

import org.apache.xmlbeans.XmlAnyURI;
import org.apache.xmlbeans.XmlBase64Binary;
import org.apache.xmlbeans.XmlOptions;
import org.w3.x2000.x09.xmldsig.DigestMethodType;
import org.w3.x2000.x09.xmldsig.KeyInfoType;
import org.w3.x2000.x09.xmldsig.X509DataType;

import oasis.names.tc.dss._1_0.core.wsdl.SOAPport;
import oasis.names.tc.dss._1_0.core.wsdl.digitalSignatureServiceClient;
import x0CoreSchema.oasisNamesTcDss1.SignRequestDocument;
import x0CoreSchema.oasisNamesTcDss1.SignResponseDocument;
import x0CoreSchema.oasisNamesTcDss1.DocumentHashDocument.DocumentHash;
import x0CoreSchema.oasisNamesTcDss1.IncludeObjectDocument.IncludeObject;
import x0CoreSchema.oasisNamesTcDss1.InputDocumentsDocument.InputDocuments;
import x0CoreSchema.oasisNamesTcDss1.KeySelectorDocument.KeySelector;
import x0CoreSchema.oasisNamesTcDss1.OptionalInputsDocument.OptionalInputs;
import x0CoreSchema.oasisNamesTcDss1.SignRequestDocument.SignRequest;

public class CreacioSegellDeTemps {

	@SuppressWarnings("unchecked")
	public static void main(String args[]) throws Exception {

		// Configuració local
		Utils.setProxyConfiguration();
		
		// Dades de prova

		// Certificat amb que es generarà la signatura o timestamp
		byte[] certificate = Utils.readBase64File("cat\\cert\\docs\\timestamp-certificate.dat");
		
		// Digest
		byte[] digest = Utils.readBase64File("cat\\cert\\docs\\timestamp-digest1.dat");

		// Tipus de signatura disponibles
		// TimeStamp amb signatura CMS/CAdes: 	urn:ietf:rfc:3161
		// TimeStamp amb signatura XMLDsig: 	oasis:names:tc:dss:1.0:core:schema:XMLTimeStampToken
		// TimeStamp amb signatura XAdES:		oasis:names:tc:dss:1.0:core:schema:XAdESTimeStampToken
		String type = "urn:ietf:rfc:3161";

		// Inicialització del client
		digitalSignatureServiceClient proxy = new digitalSignatureServiceClient();
		SOAPport port = proxy.getdssPortSoap("http://psisbeta.catcert.net/psis/catcert/dss");

		// Composició del missatge

		// Definició dels namespaces correctes
		Hashtable prefixes = new Hashtable();
		prefixes.put("urn:oasis:names:tc:dss:1.0:core:schema","dss");
		prefixes.put("http://www.w3.org/2000/09/xmldsig#","ds");

		XmlOptions options= new XmlOptions();	
		options.setSaveSuggestedPrefixes(prefixes);

		// Creació del missatge DSS
		SignRequestDocument requestDocument = SignRequestDocument.Factory.newInstance(options);

		SignRequest request = requestDocument.addNewSignRequest();
		request.setProfile("urn:oasis:names:tc:dss:1.0:profiles:timestamping");

		// Creació de l'element amb el document per generar el timestamp
		InputDocuments inpDocuments = InputDocuments.Factory.newInstance();

		DocumentHash document = inpDocuments.addNewDocumentHash();
		document.setID("Doc1");
		document.setDigestValue(digest);
		
		DigestMethodType digestMethod = document.addNewDigestMethod();
		digestMethod.setAlgorithm("http://www.w3.org/2000/09/xmldsig#sha1");		
		
		request.setInputDocuments(inpDocuments);

		// Creació de l'element amb els paràmetres opcionals necessaris per generar el timestamp
		OptionalInputs optional = request.addNewOptionalInputs();

		KeySelector selector = optional.addNewKeySelector();

		KeyInfoType key = selector.addNewKeyInfo();

		X509DataType x509data = key.addNewX509Data();

		// S'afegeix el certificat de TSA de CATCert en Base64
		XmlBase64Binary b64certificate = x509data.addNewX509Certificate();
		b64certificate.setByteArrayValue(certificate);

		XmlAnyURI any = optional.addNewSignatureType();
		any.setStringValue(type);
		
		IncludeObject object = optional.addNewIncludeObject();
		object.setObjId("Doc1");
		object.setWhichDocument("Doc1");
		object.setHasObjectTagsAndAttributesSet(false);
		object.setCreateReference(true);

		// Visualització de la petició
		System.out.println(requestDocument.xmlText(options));

		// Execució del servei
		SignResponseDocument responseDocument = port.sign(requestDocument);

		// visualització de la resposta
		System.out.println(responseDocument.xmlText(options));

	}
}
