forked from mirrors/gecko-dev
		
	 4a4c4fdfd4
			
		
	
	
		4a4c4fdfd4
		
	
	
	
	
		
			
			MozReview-Commit-ID: LxLDWlsIlSk --HG-- extra : rebase_source : 5762bdf08ff6c09c1b29f87366bddb552e4c74b2 extra : amend_source : 922a0c03722bd5a81daace7f0289ec3228191cfb
		
			
				
	
	
		
			144 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| XPCOMUtils.defineLazyModuleGetters(this, {
 | |
|   ctypes: "resource://gre/modules/ctypes.jsm",
 | |
|   NativeManifests: "resource://gre/modules/NativeManifests.jsm",
 | |
|   OS: "resource://gre/modules/osfile.jsm",
 | |
| });
 | |
| 
 | |
| XPCOMUtils.defineLazyServiceGetter(this, "pkcs11db",
 | |
|                                    "@mozilla.org/security/pkcs11moduledb;1",
 | |
|                                    "nsIPKCS11ModuleDB");
 | |
| 
 | |
| var {DefaultMap} = ExtensionUtils;
 | |
| 
 | |
| const findModuleByPath = function(path) {
 | |
|   let modules = pkcs11db.listModules();
 | |
|   for (let module of XPCOMUtils.IterSimpleEnumerator(modules, Ci.nsIPKCS11Module)) {
 | |
|     if (module && module.libName === path) {
 | |
|       return module;
 | |
|     }
 | |
|   }
 | |
|   return null;
 | |
| };
 | |
| 
 | |
| this.pkcs11 = class extends ExtensionAPI {
 | |
|   getAPI(context) {
 | |
|     let manifestCache = new DefaultMap(async name => {
 | |
|       let hostInfo = await NativeManifests.lookupManifest("pkcs11", name, context);
 | |
|       if (hostInfo) {
 | |
|         if (AppConstants.platform === "win") {
 | |
|           hostInfo.manifest.path = OS.Path.join(OS.Path.dirname(hostInfo.path), hostInfo.manifest.path);
 | |
|         }
 | |
|         let manifestLib = OS.Path.basename(hostInfo.manifest.path);
 | |
|         if (AppConstants.platform !== "linux") {
 | |
|           manifestLib = manifestLib.toLowerCase(manifestLib);
 | |
|         }
 | |
|         if (manifestLib !== ctypes.libraryName("nssckbi")) {
 | |
|           return hostInfo.manifest;
 | |
|         }
 | |
|       }
 | |
|       return Promise.reject({message: `No such PKCS#11 module ${name}`});
 | |
|     });
 | |
|     return {
 | |
|       pkcs11: {
 | |
|         /**
 | |
|           * Verify whether a given PKCS#11 module is installed.
 | |
|           *
 | |
|           * @param {string} name The name of the module, as specified in
 | |
|           *                      the manifest file.
 | |
|           * @returns {Promise} A Promise that resolves to true if the package
 | |
|           *                    is installed, or false if it is not. May be
 | |
|           *                    rejected if the module could not be found.
 | |
|           */
 | |
|         async isModuleInstalled(name) {
 | |
|           let manifest = await manifestCache.get(name);
 | |
|           return findModuleByPath(manifest.path) !== null;
 | |
|         },
 | |
|         /**
 | |
|           * Install a PKCS#11 module
 | |
|           *
 | |
|           * @param {string} name The name of the module, as specified in
 | |
|           *                      the manifest file.
 | |
|           * @param {integer} [flags = 0] Any flags to be passed on to the
 | |
|           *                              nsIPKCS11ModuleDB.addModule method
 | |
|           * @returns {Promise} When the Promise resolves, the module will have
 | |
|           *                    been installed. When it is rejected, the module
 | |
|           *                    either is already installed or could not be
 | |
|           *                    installed for some reason.
 | |
|           */
 | |
|         async installModule(name, flags = 0) {
 | |
|           let manifest = await manifestCache.get(name);
 | |
|           if (!manifest.description) {
 | |
|             return Promise.reject({message: `The description field in the manifest for PKCS#11 module ${name} must have a value`});
 | |
|           }
 | |
|           pkcs11db.addModule(manifest.description, manifest.path, flags, 0);
 | |
|         },
 | |
|         /**
 | |
|           * Uninstall a PKCS#11 module
 | |
|           *
 | |
|           * @param {string} name The name of the module, as specified in
 | |
|           *                      the manifest file.
 | |
|           * @returns {Promise}. When the Promise resolves, the module will have
 | |
|           *                     been uninstalled. When it is rejected, the
 | |
|           *                     module either was not installed or could not be
 | |
|           *                     uninstalled for some reason.
 | |
|           */
 | |
|         async uninstallModule(name) {
 | |
|           let manifest = await manifestCache.get(name);
 | |
|           let module = findModuleByPath(manifest.path);
 | |
|           if (!module) {
 | |
|             return Promise.reject({message: `The PKCS#11 module ${name} is not loaded`});
 | |
|           }
 | |
|           pkcs11db.deleteModule(module.name);
 | |
|         },
 | |
|         /**
 | |
|          * Get a list of slots for a given PKCS#11 module, with
 | |
|          * information on the token (if any) in the slot.
 | |
|          *
 | |
|          * The PKCS#11 standard defines slots as an abstract concept
 | |
|          * that may or may not have at most one token. In practice, when
 | |
|          * using PKCS#11 for smartcards (the most likely use case of
 | |
|          * PKCS#11 for Firefox), a slot corresponds to a cardreader, and
 | |
|          * a token corresponds to a card.
 | |
|          *
 | |
|          * @param {string} name The name of the PKCS#11 module, as
 | |
|          *                 specified in the manifest file.
 | |
|          * @returns {Promise} A promise that resolves to an array of objects
 | |
|          *                    with two properties.  The `name` object contains
 | |
|          *                    the name of the slot; the `token` object is null
 | |
|          *                    if there is no token in the slot, or is an object
 | |
|          *                    describing various properties of the token if
 | |
|          *                    there is.
 | |
|          */
 | |
|         async getModuleSlots(name) {
 | |
|           let manifest = await manifestCache.get(name);
 | |
|           let module = findModuleByPath(manifest.path);
 | |
|           if (!module) {
 | |
|             return Promise.reject({message: `The module ${name} is not installed`});
 | |
|           }
 | |
|           let rv = [];
 | |
|           for (let slot of XPCOMUtils.IterSimpleEnumerator(module.listSlots(), Ci.nsIPKCS11Slot)) {
 | |
|             let token = slot.getToken();
 | |
|             let slotobj = {
 | |
|               name: slot.name,
 | |
|               token: null,
 | |
|             };
 | |
|             if (slot.status != 1 /* SLOT_NOT_PRESENT */) {
 | |
|               slotobj.token = {
 | |
|                 name: token.tokenName,
 | |
|                 manufacturer: token.tokenManID,
 | |
|                 HWVersion: token.tokenHWVersion,
 | |
|                 FWVersion: token.tokenFWVersion,
 | |
|                 serial: token.tokenSerialNumber,
 | |
|                 isLoggedIn: token.isLoggedIn(),
 | |
|               };
 | |
|             }
 | |
|             rv.push(slotobj);
 | |
|           }
 | |
|           return rv;
 | |
|         },
 | |
|       },
 | |
|     };
 | |
|   }
 | |
| };
 |