 var promptSvc;

function Init()
{
    promptSvc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
	getService(Components.interfaces.nsIPromptService);
}
function Browse(element,flag)
{
  var nsIFilePicker = Components.interfaces.nsIFilePicker;
  var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);

  if (flag == 'load'){
      fp.init(window, "Select file for load", nsIFilePicker.modeOpen);
  } else {
      fp.init(window, "Select file for save", nsIFilePicker.modeSave);
  }

  fp.appendFilters(nsIFilePicker.filterAll);

  var res=fp.show();

  if (res==nsIFilePicker.returnOK || res==nsIFilePicker.returnReplace){
    if (fp.file && fp.file.path.length > 0) 
      {
	  document.getElementById(element).value = fp.file.path;
      }
  }
}


function SignFile()
{
    var content_file;
    var signature_file;
    var tmp;

    try {
	content_file = document.getElementById('file_from_sign').value;
	signature_file = document.getElementById('file_to_signature').value;

	if (content_file.length == 0){
	    promptSvc.alert(window, "Error", "You must insert a file to sign");
	    return;
	}
	if (signature_file.length == 0){
	    promptSvc.alert(window, "Error", "You must insert a file to save the signature");
	    return;
	}
	
	var cert;
	var picker = Components.classes["@mozilla.org/user_cert_picker;1"]
	    .createInstance(Components.interfaces.nsIUserCertPicker);

	var canceled = {value:0};
	try {
	    cert = picker.pickByUsage(window,
				      "",
				      4,
				      false, false, canceled);
	} catch(e) {
	    canceled.value = false;
	    cert = null;
	}

	if (canceled.value){
	    promptSvc.alert(window, "Error", "Aborted by user");
	    return;
	}
	if (!cert) {
	    promptSvc.alert(window, "Error", "No user certificates");
	    return;
	}
	
	var content_local_file = Components.classes["@mozilla.org/file/local;1"].
	    createInstance( Components.interfaces.nsILocalFile );
	content_local_file.initWithPath(content_file);
	var content_input = Components.classes["@mozilla.org/network/file-input-stream;1"].
	    createInstance(Components.interfaces.nsIFileInputStream);
	content_input.init(content_local_file,0x01,0444,tmp);
	
	var signature_local_file = Components.classes["@mozilla.org/file/local;1"].
	    createInstance( Components.interfaces.nsILocalFile );
	signature_local_file.initWithPath(signature_file);
	if (!signature_local_file.exists())
	    {
		signature_local_file.create(Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE,0644);
	    }
	var signature_output = Components.classes["@mozilla.org/network/file-output-stream;1"].
	    createInstance(Components.interfaces.nsIFileOutputStream);
	signature_output.init(signature_local_file,0x20|0x02,0644,null);
	
	var s;
	var aHash = Components.classes["@mozilla.org/secclab/nsCLABHash;1"].
	    createInstance(Components.interfaces.nsICLABHash);
	


	var scriptableInputStream = Components.classes["@mozilla.org/secclab/nsCLABScriptableInputStream;1"].
	    createInstance(Components.interfaces.nsICLABScriptableInputStream);
	aHash.create(Components.interfaces.nsICLABHash.HASH_AlgSHA1);
	aHash.begin();
	scriptableInputStream.init(content_input);
	var avail = scriptableInputStream.available();
	var aLeer;
	var out_len = {value:0};
	while(avail){
	    aLeer = (avail < 1000) ? avail : 1000;
	    s = scriptableInputStream.read(aLeer,out_len);
	    aHash.update(s,aLeer);
	    avail = scriptableInputStream.available();
	}
	scriptableInputStream.close();
	content_input.close();

	var length = {value:0};
	var h = aHash.end(length);
	
	
	var nsCLABCMSMessage = "@mozilla.org/secclab/nsCLABCMSMessage;1";
	var message = Components.classes[nsCLABCMSMessage].createInstance(Components.interfaces.nsICLABCMSMessage);
	message.createSigned(cert,cert,h,h.length);
	var encoder = Components.classes["@mozilla.org/secclab/nsCLABCMSEncoder;1"].
	    createInstance(Components.interfaces.nsICLABCMSEncoder);
	
	encoder.start(message,signature_output);
	encoder.finish();
	promptSvc.alert(window, "End", "End");
    } catch (e) {
	promptSvc.alert(window, "Error", e);
    }
}

function VerifyFile()
{
    var content_file;
    var signature_file;
    var tmp;

    try {
	signature_file = document.getElementById('file_from_signature').value;
	content_file = document.getElementById('file_from_content').value;

	if ((content_file.length == 0)){
	    promptSvc.alert(window, "Error", "You must insert a file of content");
	    return;
	}
	if (signature_file.length == 0){
	    promptSvc.alert(window, "Error", "You must insert a file of signature");
	    return;
	}

	
	var content_local_file = Components.classes["@mozilla.org/file/local;1"].
	    createInstance( Components.interfaces.nsILocalFile );
	content_local_file.initWithPath(content_file);
	var content_input = Components.classes["@mozilla.org/network/file-input-stream;1"].
	    createInstance(Components.interfaces.nsIFileInputStream);
	content_input.init(content_local_file,0x01,0444,tmp);
	
	var signature_local_file = Components.classes["@mozilla.org/file/local;1"].
	    createInstance( Components.interfaces.nsILocalFile );
	signature_local_file.initWithPath(signature_file);
	var signature_input = Components.classes["@mozilla.org/network/file-input-stream;1"].
	    createInstance(Components.interfaces.nsIFileInputStream);
	signature_input.init(signature_local_file,0x01,0444,tmp);	    
	
	var s;
	var aHash = Components.classes["@mozilla.org/secclab/nsCLABHash;1"].
	    createInstance(Components.interfaces.nsICLABHash);
	
	
	var scriptableInputStream = Components.classes["@mozilla.org/secclab/nsCLABScriptableInputStream;1"].
	    createInstance(Components.interfaces.nsICLABScriptableInputStream);
	aHash.create(Components.interfaces.nsICLABHash.HASH_AlgSHA1);
	aHash.begin();
	scriptableInputStream.init(content_input);
	var avail = scriptableInputStream.available();
	var aLeer;
	var out_len = {value:0};
	while(avail){
	    aLeer = (avail < 1000) ? avail : 1000;
	    s = scriptableInputStream.read(aLeer,out_len);
	    aHash.update(s,s.length);
	    avail = scriptableInputStream.available();
	}
	scriptableInputStream.close();
	content_input.close();
	
	var length = {value:0};
	var h = aHash.end(length);

	var decoder = Components.classes["@mozilla.org/secclab/nsCLABCMSDecoder;1"].
	    createInstance(Components.interfaces.nsICLABCMSDecoder);
	
	// decoder.start(output);
	decoder.start(null);
	
	scriptableInputStream.init(signature_input);
	var avail = scriptableInputStream.available();
	var aLeer;
	var out_len = {value:0};
	while(avail){
	    aLeer = (avail < 1000) ? avail : 1000;
	    s = scriptableInputStream.read(aLeer,out_len);
	    decoder.update(s,s.length);
	    avail = scriptableInputStream.available();
	}
	scriptableInputStream.close();	    
	signature_input.close();
	var message = decoder.finish();
	
	try {
	    message.verifyDetachedSignature(h,h.length);
	    promptSvc.alert(window,"Verify OK","Verify OK");	
	} catch(e){
	    promptSvc.alert(window,"Verify Error","Verify error");
	}
    } catch (e) {
	promptSvc.alert(window, "Error", e);
    }
}




function hex(v)
{
    var hexstring="0123456789ABCDEF";
    return hexstring[v];
}

function TestSign()
{
    var signString = Components.classes["@mozilla.org/secclab/nsCLABSignString;1"].
	createInstance(Components.interfaces.nsICLABSignString);
    var length = {value:0};
    var status = {value:0};
    try {
	var p7 = signString.signString(window,"5",1,status,length);
    } catch(e){
	if (status.value = Components.interfaces.nsICLABSignString.STATUS_CANCELLED_BY_USER)
	    alert("cancelado");
	else
	    alert("ERROR ("+ex+")");
    }

    local_file = Components.classes["@mozilla.org/file/local;1"].createInstance( Components.interfaces.nsILocalFile );
    local_file.initWithPath("/tmp/SignString.p7");
    if (!local_file.exists())
	{
	    local_file.create(Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE,0644);
	}
    output = Components.classes["@mozilla.org/network/file-output-stream;1"].
	createInstance(Components.interfaces.nsIFileOutputStream);
    output.init(local_file,0x20|0x02,0644,null);
    output.write(p7,p7.length);
    alert("fin");
}
function TestSignOld()
{
    try {
	var p = Components.classes["@mozilla.org/secclab/nsCLABHash;1"].
	    createInstance(Components.interfaces.nsICLABHash);
	
	p.create(Components.interfaces.nsICLABHash.HASH_AlgSHA1);
	p.begin();
	p.update("5",1);
	var length = {value:0};
	hash = p.end(length);
	var shash = "";
	//alert(hash.length);
	//alert(length.value);
	for (var i=0;i<hash.length;i++){
	    //	    hnible = hex(hash[i] >> 4);
	    //lnible = hex(hash[i] & 0x0f);
	    hnible = hex(hash.charCodeAt(i) >> 4);
	    lnible = hex(hash.charCodeAt(i) & 0x0f);
	    shash = shash + hnible + lnible;
	}
	alert(shash);

	alert("1");
	var certdb = Components.classes["@mozilla.org/security/x509certdb;1"].
	    getService(Components.interfaces.nsIX509CertDB);

	/*    var certcache = Components.classes["@mozilla.org/security/nsscertcache;1"].
	      createInstance(Components.interfaces.nsINSSCertCache);
	      
	      certcache.cacheAllCerts();
	*/
	
	alert("2");
	var userTreeView = Components.classes['@mozilla.org/security/nsCertTree;1'].
	    createInstance(Components.interfaces.nsICertTree);
	/* userTreeView.loadCertsFromCache(certcache,Components.Interfaces.nsIX509Cert.USER_CERT);*/
	userTreeView.loadCerts(Components.interfaces.nsIX509Cert.USER_CERT);
	
	if (userTreeView.rowCount == 0){
	    alert("no tienes certificados para firmar");
	    return;
	}
	alert("Numero de certificados:" + userTreeView.rowCount);
	var cert;
	for (var i=0; i<=userTreeView.rowCount; i++){
	    cert = userTreeView.getCert(i);
	    if (cert){
		var o2 = {};
		var o3 = {};
		alert(cert.commonName);
		break;
		//cert.getUsagesString(false, o2, o3);
		//alert(o3.value);
	    }
	}
	if (cert) {
	    var nsCLABCMSMessage = "@mozilla.org/secclab/nsCLABCMSMessage;1";
	    var message = Components.classes[nsCLABCMSMessage].createInstance(Components.interfaces.nsICLABCMSMessage);
	    message.createSigned(cert,cert,hash,hash.length);
	    var encoder = Components.classes["@mozilla.org/secclab/nsCLABCMSEncoder;1"].
		createInstance(Components.interfaces.nsICLABCMSEncoder);

	    local_file = Components.classes["@mozilla.org/file/local;1"].createInstance( Components.interfaces.nsILocalFile );
	    local_file.initWithPath("/tmp/nueva_prueba.p7");
	    if (!local_file.exists())
		{
		    local_file.create(Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE,0644);
		}
	    output = Components.classes["@mozilla.org/network/file-output-stream;1"].
		createInstance(Components.interfaces.nsIFileOutputStream);
	    output.init(local_file,0x20|0x02,0644,null);

	    encoder.start(message,output);
	    encoder.finish();

	}
	alert("fin");
	
    } catch(e){
	alert(e);
    }

}
