author | Siddartha Pothapragada <Siddartha.Pothapragada@telekom.com> |
Tue, 09 Jun 2015 11:18:51 -0700 | |
changeset 247826 | a40b2c6672cd30671090ac3afc45ad46ec3c4c27 |
parent 247825 | a422730764e5cf43bae3f31fb2e32e8d9e0508e2 |
child 247831 | 13f8dcb5b7a5879aeac869b2bc74ac47b20c9c3d |
push id | 60814 |
push user | kwierso@gmail.com |
push date | Wed, 10 Jun 2015 02:29:27 +0000 |
treeherder | mozilla-inbound@bc32a90612e5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | allstars.chh, khuey, kwierso |
bugs | 1118102 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/secureelement/DOMSecureElement.js +++ b/dom/secureelement/DOMSecureElement.js @@ -27,16 +27,26 @@ XPCOMUtils.defineLazyServiceGetter(this, "nsISyncMessageSender"); XPCOMUtils.defineLazyGetter(this, "SE", function() { let obj = {}; Cu.import("resource://gre/modules/se_consts.js", obj); return obj; }); +// Extend / Inherit from Error object +function SEError(name, message) { + this.name = name || SE.ERROR_GENERIC; + this.message = message || ""; +} + +SEError.prototype = { + __proto__: Error.prototype, +}; + function PromiseHelpersSubclass(win) { this._window = win; } PromiseHelpersSubclass.prototype = { __proto__: DOMRequestIpcHelper.prototype, _window: null, @@ -69,21 +79,21 @@ PromiseHelpersSubclass.prototype = { // Get the context associated with this resolverId let context = this._context[resolverId]; delete this._context[resolverId]; return {resolver: resolver, context: context}; }, - rejectWithSEError: function rejectWithSEError(reason) { - return this.createSEPromise((resolverId) => { - debug("rejectWithSEError : " + reason); - this.takePromiseResolver(resolverId).reject(new Error(reason)); - }); + rejectWithSEError: function rejectWithSEError(name, message) { + let error = new SEError(name, message); + debug("rejectWithSEError - " + error.toString()); + + return this._window.Promise.reject(Cu.cloneInto(error, this._window)); } }; // Helper wrapper class to do promises related chores let PromiseHelpers; /** * Instance of 'SEReaderImpl' class is the connector to a secure element. @@ -150,18 +160,19 @@ SEReaderImpl.prototype = { } let resolver = PromiseHelpers.takePromiseResolver(resolverId); // Wait till all the promises are resolved Promise.all(promises).then(() => { this._sessions = []; resolver.resolve(); }, (reason) => { - resolver.reject(new Error(SE.ERROR_BADSTATE + - " Unable to close all channels associated with this reader")); + let error = new SEError(SE.ERROR_BADSTATE, + "Unable to close all channels associated with this reader"); + resolver.reject(Cu.cloneInto(error, this._window)); }); }); }, updateSEPresence: function updateSEPresence(isSEPresent) { if (!isSEPresent) { this.invalidate(); return; @@ -198,23 +209,16 @@ SESessionImpl.prototype = { _isClosed: false, _reader: null, classID: Components.ID("{2b1809f8-17bd-4947-abd7-bdef1498561c}"), contractID: "@mozilla.org/secureelement/session;1", QueryInterface: XPCOMUtils.generateQI([]), - // Private function - _checkClosed: function _checkClosed() { - if (this._isClosed) { - throw new Error(SE.ERROR_BADSTATE + " Session Already Closed!"); - } - }, - // Chrome-only function onChannelOpen: function onChannelOpen(channelCtx) { this._channels.push(channelCtx); }, // Chrome-only function onChannelClose: function onChannelClose(channelCtx) { let index = this._channels.indexOf(channelCtx); @@ -224,22 +228,25 @@ SESessionImpl.prototype = { }, initialize: function initialize(win, readerCtx) { this._window = win; this._reader = readerCtx; }, openLogicalChannel: function openLogicalChannel(aid) { - this._checkClosed(); + if (this._isClosed) { + return PromiseHelpers.rejectWithSEError(SE.ERROR_BADSTATE, + "Session Already Closed!"); + } let aidLen = aid ? aid.length : 0; if (aidLen < SE.MIN_AID_LEN || aidLen > SE.MAX_AID_LEN) { - return PromiseHelpers.rejectWithSEError(SE.ERROR_GENERIC + - " Invalid AID length - " + aidLen); + return PromiseHelpers.rejectWithSEError(SE.ERROR_ILLEGALPARAMETER, + "Invalid AID length - " + aidLen); } return PromiseHelpers.createSEPromise((resolverId) => { /** * @params for 'SE:OpenChannel' * * resolverId : ID that identifies this IPC request. * aid : AID that identifies the applet on SecureElement @@ -251,17 +258,20 @@ SESessionImpl.prototype = { aid: aid, type: this.reader.type, appId: this._window.document.nodePrincipal.appId }); }, this); }, closeAll: function closeAll() { - this._checkClosed(); + if (this._isClosed) { + return PromiseHelpers.rejectWithSEError(SE.ERROR_BADSTATE, + "Session Already Closed!"); + } return PromiseHelpers.createSEPromise((resolverId) => { let promises = []; for (let channel of this._channels) { if (!channel.isClosed) { promises.push(channel.close()); } } @@ -271,17 +281,17 @@ SESessionImpl.prototype = { this._isClosed = true; this._channels = []; // Notify parent of this session instance's closure, so that its // instance entry can be removed from the parent as well. this._reader.onSessionClose(this.__DOM_IMPL__); resolver.resolve(); }, (reason) => { resolver.reject(new Error(SE.ERROR_BADSTATE + - " Unable to close all channels associated with this session")); + "Unable to close all channels associated with this session")); }); }); }, invalidate: function invlidate() { this._isClosed = true; this._channels.forEach(ch => ch.invalidate()); this._channels = []; @@ -315,22 +325,16 @@ SEChannelImpl.prototype = { openResponse: [], type: null, classID: Components.ID("{181ebcf4-5164-4e28-99f2-877ec6fa83b9}"), contractID: "@mozilla.org/secureelement/channel;1", QueryInterface: XPCOMUtils.generateQI([]), - _checkClosed: function _checkClosed() { - if (this._isClosed) { - throw new Error(SE.ERROR_BADSTATE + " Channel Already Closed!"); - } - }, - // Chrome-only function onClose: function onClose() { this._isClosed = true; // Notify the parent this._session.onChannelClose(this.__DOM_IMPL__); }, initialize: function initialize(win, channelToken, isBasicChannel, @@ -344,38 +348,41 @@ SEChannelImpl.prototype = { this.openResponse = Cu.cloneInto(new Uint8Array(openResponse), win); this.type = isBasicChannel ? "basic" : "logical"; }, transmit: function transmit(command) { // TODO remove this once it will be possible to have a non-optional dict // in the WebIDL if (!command) { - return PromiseHelpers.rejectWithSEError(SE.ERROR_GENERIC + - " SECommand dict must be defined"); + return PromiseHelpers.rejectWithSEError(SE.ERROR_ILLEGALPARAMETER, + "SECommand dict must be defined"); } - this._checkClosed(); + if (this._isClosed) { + return PromiseHelpers.rejectWithSEError(SE.ERROR_BADSTATE, + "Channel Already Closed!"); + } let dataLen = command.data ? command.data.length : 0; if (dataLen > SE.MAX_APDU_LEN) { - return PromiseHelpers.rejectWithSEError(SE.ERROR_GENERIC + + return PromiseHelpers.rejectWithSEError(SE.ERROR_ILLEGALPARAMETER, " Command data length exceeds max limit - 255. " + " Extended APDU is not supported!"); } if ((command.cla & 0x80 === 0) && ((command.cla & 0x60) !== 0x20)) { if (command.ins === SE.INS_MANAGE_CHANNEL) { - return PromiseHelpers.rejectWithSEError(SE.ERROR_SECURITY + - ", MANAGE CHANNEL command not permitted"); + return PromiseHelpers.rejectWithSEError(SE.ERROR_SECURITY, + "MANAGE CHANNEL command not permitted"); } if ((command.ins === SE.INS_SELECT) && (command.p1 == 0x04)) { // SELECT by DF Name (p1=04) is not allowed - return PromiseHelpers.rejectWithSEError(SE.ERROR_SECURITY + - ", SELECT command not permitted"); + return PromiseHelpers.rejectWithSEError(SE.ERROR_SECURITY, + "SELECT command not permitted"); } debug("Attempting to transmit an ISO command"); } else { debug("Attempting to transmit GlobalPlatform command"); } return PromiseHelpers.createSEPromise((resolverId) => { /** @@ -392,17 +399,20 @@ SEChannelImpl.prototype = { apdu: command, channelToken: this._channelToken, appId: this._window.document.nodePrincipal.appId }); }, this); }, close: function close() { - this._checkClosed(); + if (this._isClosed) { + return PromiseHelpers.rejectWithSEError(SE.ERROR_BADSTATE, + "Channel Already Closed!"); + } return PromiseHelpers.createSEPromise((resolverId) => { /** * @params for 'SE:CloseChannel' * * resolverId : Id that identifies this IPC request. * channelToken: Token that identifies the current channel over which 'c-apdu' is being sent. @@ -578,29 +588,29 @@ SEManagerImpl.prototype = { context.onClose(); } resolver.resolve(); break; case "SE:GetSEReadersRejected": case "SE:OpenChannelRejected": case "SE:CloseChannelRejected": case "SE:TransmitAPDURejected": - let error = result.error || SE.ERROR_GENERIC; - resolver.reject(error); + let error = new SEError(result.error, result.reason); + resolver.reject(Cu.cloneInto(error, this._window)); break; case "SE:ReaderPresenceChanged": debug("Reader " + result.type + " present: " + result.isPresent); let reader = this._readers.find(r => r.type === result.type); if (reader) { reader.updateSEPresence(result.isPresent); } break; default: debug("Could not find a handler for " + message.name); - resolver.reject(); + resolver.reject(Cu.cloneInto(new SEError(), this._window)); break; } } }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ SEResponseImpl, SEChannelImpl, SESessionImpl, SEReaderImpl, SEManagerImpl ]);
--- a/dom/secureelement/gonk/se_consts.js +++ b/dom/secureelement/gonk/se_consts.js @@ -54,14 +54,15 @@ this.INS_GET_RESPONSE = 0xC0; this.ERROR_NONE = ""; this.ERROR_SECURITY = "SESecurityError"; this.ERROR_IO = "SEIoError"; this.ERROR_BADSTATE = "SEBadStateError"; this.ERROR_INVALIDCHANNEL = "SEInvalidChannelError"; this.ERROR_INVALIDAPPLICATION = "SEInvalidApplicationError"; this.ERROR_GENERIC = "SEGenericError"; this.ERROR_NOTPRESENT = "SENotPresentError"; +this.ERROR_ILLEGALPARAMETER = "SEIllegalParameterError"; this.TYPE_UICC = "uicc"; this.TYPE_ESE = "eSE"; // Allow this file to be imported via Components.utils.import(). this.EXPORTED_SYMBOLS = Object.keys(this);
--- a/dom/webidl/SecureElement.webidl +++ b/dom/webidl/SecureElement.webidl @@ -11,16 +11,17 @@ enum SEType { enum SEError { "SESecurityError", // Requested operation does not match the access control rules of the application. "SEIoError", // I/O Error while communicating with the secure element. "SEBadStateError", // Error occuring as a result of bad state. "SEInvalidChannelError", // Opening a channel failed because no channel is available. "SEInvalidApplicationError", // The requested application was not found on the secure element. "SENotPresentError", // Secure Element is not present + "SEIllegalParameterError", // Request operation does not have valid parameters. "SEGenericError" // Generic failures. }; enum SEChannelType { "basic", "logical" };