diff -r 64ef7cac24b0 components/nsCommandLineHandler.js
--- a/components/nsCommandLineHandler.js	Fri Oct 02 20:03:56 2009 +0200
+++ b/components/nsCommandLineHandler.js	Fri Oct 02 21:23:34 2009 +0200
@@ -2,9 +2,19 @@
 //@line 38 "/home/dave/mozilla/source/MOZILLA_1_9a8_RELEASE/mozilla/mccoy/components/src/nsCommandLineHandler.js"
 */
 
-const Cc = Components.classes;
+/*
 const Ci = Components.interfaces;
+*/
 const Cr = Components.results;
+
+var gRDF = null;
+try {
+  var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
+  loader.loadSubScript("chrome://mccoy/content/rdfserializer.js",this);
+  loader.loadSubScript("chrome://mccoy/content/mccoy.js",this);
+  gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].
+         getService(Components.interfaces.nsIRDFService);
+} catch(e){dump("import error : "+e+"\n");}
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
@@ -15,11 +25,162 @@
   handle: function(aCmdLine)
   {
     try {
+      // Force empty master password to avoid displaying security popup!
+      var pk11db = Components.classes["@mozilla.org/security/pk11tokendb;1"].getService(Components.interfaces.nsIPK11TokenDB);
+      var token = pk11db.findTokenByName("");
+      if (token.needsUserInit)
+        token.initPassword("");
+
       // Initialise the key service. Will prompt for password if there is one.
-      var ks = Cc["@toolkit.mozilla.org/keyservice;1"].
-               getService(Ci.nsIKeyService);
+      var ks = Components.classes["@toolkit.mozilla.org/keyservice;1"].
+               getService(Components.interfaces.nsIKeyService);
+      
+      function findKey(name) {
+        var enum = ks.enumerateKeys();
+ 	while(enum.hasMoreElements()) {
+	  var key = enum.getNext().QueryInterface(Components.interfaces.nsIKeyPair);
+	  if (key.name == name)
+	    return key;
+	}
+	return null;
+      }
+
+      function loadRdfFile(filePath) {
+	 //var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("CurWorkD", Components.interfaces.nsILocalFile);
+	var file = aCmdLine.workingDirectory.clone();
+	file.appendRelativePath(filePath);
+	if (!file.exists()) {
+		file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+		file.initWithPath(updateRdfPath);
+		if (!file.exists())
+			return null;
+	}
+	var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
+	var fileURL = ios.newFileURI(file);
+	return gRDF.GetDataSourceBlocking(fileURL.spec).QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
+      }
+      
+      // -createKey $name
+      var keyName = aCmdLine.handleFlagWithParam("createKey", false);
+      if (keyName) {
+        dump("Creating key with name : "+keyName+"\n");
+	if (findKey(keyName))
+	  return dump("This key already exists!\n");
+        var keypair = ks.createKeyPair(Components.interfaces.nsIKeyPair.KEYTYPE_RSA);
+        keypair.name = keyName;
+	dump("Public key : "+keypair.exportPublicKey()+"\n");
+	dump("The key has been successfully created!\n");
+      }
+
+      // -publicKey $name
+      var keyName = aCmdLine.handleFlagWithParam("publicKey", false);
+      if (keyName) {
+        var key=findKey(keyName);
+	if (key) {
+	  dump("Public key for '"+keyName+"' is : "+key.exportPublicKey()+"\n");
+	} else {
+	  dump("Unable to found key : "+keyName+"\n");
+	}
+      }
+
+      // -listKeys
+      var list = aCmdLine.handleFlag("listKeys", false);
+      if (list) {
+      	dump("Registered keys : \n");
+        var enum = ks.enumerateKeys();
+	while(enum.hasMoreElements()) {
+	  var key = enum.getNext().QueryInterface(Components.interfaces.nsIKeyPair);
+	  dump(" - "+key.name+"\n");
+	}
+	dump("\n");
+      }
+
+      
+      // -signRdf $file -key $name
+      var updateRdfPath = aCmdLine.handleFlagWithParam("signRdf", false);
+      if (updateRdfPath) {
+      	var keyName = aCmdLine.handleFlagWithParam("key",false);
+	if (!keyName)
+	  return dump("-signRdf must be called with -key argument!");
+	
+	var key = findKey(keyName);
+
+	if (!key)
+	  return dump("Unable to found the key : "+keyName+"\n");
+	dump("Sign < "+updateRdfPath+" > with key < "+keyName+" >\n");
+	var rdf = loadRdfFile(updateRdfPath);
+	if (!rdf)
+	  return dump("Unable to find this rdf file!\n");
+	
+	var addons = selectAddons(rdf);
+	for (var i = 0; i < addons.length; i++) {
+	  var resource = addons[i];
+	  dump("Sign addon : "+resource.Value+"\n");
+	  var data = getUpdateData(rdf, resource);
+	  var signature = gRDF.GetLiteral(key.signData(data, Components.interfaces.nsIKeyPair.HASHTYPE_SHA512));
+	  unassertAll(rdf, resource, EM_NS("signature"));
+	  rdf.Assert(resource, EM_NS("signature"), signature, true);
+	}
+	rdf.Flush();
+	gRDF.UnregisterDataSource(rdf);
+	dump("File signed!\n");
+      }
+
+      var installRdf = aCmdLine.handleFlagWithParam("installRdf", false);
+      if (installRdf) {
+      	var keyName = aCmdLine.handleFlagWithParam("key", false);
+	if (!keyName)
+	  return dump("-installRdf must be called with -key!\n");
+	var key = findKey(keyName);
+	if (!key)
+	  return dump("Unable to find key : "+keyName+"\n");
+        var rdf = loadRdfFile(installRdf);
+	var mftRes = gRDF.GetResource("urn:mozilla:install-manifest");
+	var keyArc = EM_NS("updateKey");
+	var key = gRDF.GetLiteral(key.exportPublicKey());
+	unassertAll(rdf, mftRes, keyArc);
+	rdf.Assert(mftRes, keyArc, key, true);
+	rdf.Flush();
+	gRDF.UnregisterDataSource(rdf);
+	dump("Public key inserted!\n");
+      }
+
+      var verifyRdf = aCmdLine.handleFlagWithParam("verifyRdf", false);
+      if (verifyRdf) {
+	var keyName = aCmdLine.handleFlagWithParam("key", false);
+        if (!keyName)
+          return dump("-installRdf must be called with -key!\n");
+        var key = findKey(keyName);
+        if (!key)
+          return dump("Unable to find key : "+keyName+"\n");
+	dump("Check rdf : "+verifyRdf+" with key "+keyName+"\n");
+	var rdf = loadRdfFile(verifyRdf);
+	var addons = selectAddons(rdf);
+	var pass = true;
+	for (var i = 0; i < addons.length; i++) {
+	    var resource = addons[i];
+	    var sig = getString(rdf, resource, "signature");
+	    if (sig) {
+	      var data = getUpdateData(rdf, resource);
+	      if (!key.verifyData(data, sig)) {
+        	dump("Bad Signature for addon : "+addons[i].Value+"\n");
+	        pass = false;
+	      }
+	    }
+	    else {
+	      dump("No signature for addon : "+addons[i].Value+"\n");
+	      pass = false;
+	    }
+	}
+	gRDF.UnregisterDataSource(rdf);
+	if (pass)
+          dump("Valid signature!\n");
+        else
+	  dump("Invalid signature!\n");
+      }
     }
     catch (e) {
+      dump("Exception : \n" + e + "\n" +e.stack);
       // Chances are the user cancelled the password dialog, either way it's bad
       throw Components.results.NS_ERROR_ABORT;
     }
@@ -30,7 +191,7 @@
   classDescription: "McCoy Command Line Handler",
   contractID: "@mozilla.org/mccoy/mccoy-clh;1",
   classID: Components.ID("{2a349418-834c-43c7-a139-de34c0d97c97}"),
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
+  QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]),
   _xpcom_categories: [{ category: "command-line-handler", entry: "x-mccoy" }]
 };
 

