UNPKG

com-intel-security-ita-cs

Version:
1,533 lines (1,480 loc) 57 kB
/****************************************************************************** "Copyright (c) 2015-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. " ******************************************************************************/ /** * This section has the helper functions */ /** * "Constants" definitions */ var MAX_SAFE_INTEGER_VALUE = 9007199254740991; // ((2^53)-1) /** * Helper associative array: * Associative array of the error code */ var errorMessageMap = { 1: 'File system error occurred', 2: 'Memory allocation failure', 3: 'Invalid storage identifier provided', 4: 'Number of owners is invalid', 5: 'Bad owner/creator persona provided', 6: 'Invalid data policy provided', 7: 'Bad data, tag or extra key length provided', 8: 'Data integrity violation detected', 9: 'Invalid instance ID provided', 10: 'Invalid storage type provided', 11: 'Storage Identifier Already In Use', 12: 'Argument type inconsistency detected', 13: 'Policy violation detected', 14: 'Invalid web owners list size', 16: 'Server not accessible error', 17: 'Communication timeout error', 18: 'Communication generic error', 19: 'Invalid descriptor structure', 20: 'Invalid descriptor path', 21: 'Invalid descriptor handle', 22: 'Invalid timeout', 23: 'Descriptors not supported for request format', 24: 'Invalid request format', 26: 'Invalid request body structure', 29: 'Bad URL', 30: 'Invalid HTTP method', 32: 'Invalid certificate format', 33: 'Communication authentication error', 34: 'Invalid argument size', 35: 'Incorrect state', 36: 'Action aborted', 37: 'Software component is missing', 1000: 'Internal error occurred', }; /** * Helper function: * Creates an internal error object */ function createInternalError() { return new errorObj(1000, 'Internal error occurred'); } /** * Helper function: * Converts error code (number or string that can be converted to number) to errorObj * @param {Number/String} strNum - the error code number (or string that can be converted to number) * @param {Function} success - the success callback to be called in case of success convert * @param {Function} fail - the fail callback to be called in case the error code can't be converted to errorObj (called only if success callback is provided) */ function successConvertToNumber(strNum, success, fail) { if (typeof success === 'function') { if (typeof strNum === 'string') { success(parseInt(strNum, 10)); } else if (typeof strNum === 'number') { success(strNum); } else if (typeof fail === 'function') { fail(createInternalError()); } } } /** * Helper function: * Wrapper function that calls the fail callback * @param {Number} code - the error code number (from bridge) or string (from JS) * @param {Function} fail - the fail callback */ function failInternal(code, fail) { if (typeof fail === 'function') { var errObj; if ((typeof code === 'number') && (errorMessageMap.hasOwnProperty(code))) { errObj = new errorObj(code, errorMessageMap[code]); } else if (typeof code === 'string') { for (var c in errorMessageMap) { if (errorMessageMap[c] === code) { errObj = new errorObj(Number(c), code); break; } } } if (typeof errObj === 'undefined') { errObj = createInternalError(); } fail(errObj); } } /** * Helper function: * Checks if val is a valid non-negative safe integer * @param {Number} val - number in which check should be performed */ function isValidNonNegativeSafeInteger(val) { return ((typeof val == 'number') && (!isNaN(parseInt(val))) && (isFinite(val)) && (Math.floor(val) === val) && (Math.abs(val) <= MAX_SAFE_INTEGER_VALUE) && (val >= 0)); } /** * Helper function: * Checks if arr is a valid array of unsigned integer * @param {Array} arr - array in which check should be performed */ function isValidNonNegativeSafeIntegersArray(arr) { if (arr instanceof Array === false) { return false; } for (var i = 0; i < arr.length; i++) { if (!isValidNonNegativeSafeInteger(arr[i])) { return false; } } return true; } /** * Helper function: * Checks if val is of valid boolean type. * @param {Number} val - the bool val to check */ function isBoolean(val) { return (typeof val == 'boolean'); } /** * Helper function: * Checks if val is a number with boolean value '1' or '0'. * @param {Number} val - the number val to check */ function isNumberBooleanValue(val) { return (val !== 0 && val !== 1); } /** * Helper function: * Checks if the object is empty {} * @param {Object} object - the object to check */ function isEmptyObject(object) { for (var element in object) { if (object.hasOwnProperty(element)) return false; } return true; } /* arg1 - array, contains the arguments passed to the API call (Options or InstanceID) funcAsync - function, the API function to call this function create and return a promise object that will reject when the API call fails, or resolve when the API call succeed. */ function _createPromise(arg1, funcAsync) { var deferred = Q.defer(); funcAsync( function(returnValue) { // success deferred.resolve(returnValue); }, function(errorMsg) { // failure deferred.reject(errorMsg); }, arg1); return deferred.promise; } /* Args - array, contains the arguments passed to the API call funcAsync - function, the function to call after dispatching type - string, the type of the first argument for this function ('Number' for instanceId and 'object' for options) This function gets the arguments from the API call, and do as follow: If only one argument passed and his type is the type we expecting (object type for “Options” and Number type for “instanceID”) we continue with the Promises methodology. In any other case, we Refers to the call as if it were with the old methodology. */ function _dispatch(Args, funcAsync, type) { if ( ((Args.length == 3) && (typeof Args[2] === type))) //if exactly one argument from the right type passed { funcAsync(Args[0], Args[1], Args[2]); //Refers to the call as if it were with the old methodology. return null; } else { return _createPromise(Args[0], funcAsync); //continue with the Promises methodology. } } var _internalSecurityServicesWebAPI = { APIVersion: { major: 2, minor: 0, patch: 1 }, baseURL: "https://192.55.233.1/", capability: "intel/security", defaultTimeout: 15000, endpointRAT: "resourceaccesstoken", // Endpoint URI for requesting the Resource Access Token (RAT) from CP resourceAccessToken: "", // The current active RAT acquisitionInProgress: false, // States whether or not there is a RAT acquisition is progress waitingPromises: [], // A queue with deferred objects of all the requests waiting for token renewal ("barrier") keepaliveInterval: 60000, // Time (in ms) between two keepalive requests endpointKeepalive: "/control/keepalive/", // The URI of the keepalive isKeepaliveRunning: false, // Interval handle /** * Adds the API version field to the sent object * @param target the object to which the version will be inserted */ addVersionToObject: function(target) { if((typeof(target) !== "object") || target.hasOwnProperty('APIVersion')) { return false; } else { target['APIVersion'] = _internalSecurityServicesWebAPI.APIVersion; return true; } }, /** * Wrapper function making CP requests using a XMLHttpRequest object * @param method HTTP method, e.g. GET, POST, etc... * @param endpoint Resource endpoint being requested * @param data Request body * @param token JSON Web Token header value * @param extraTimeout additional timeout for the request (in ms). If zero, default timeout will be used * @return a promise with function(responseArr) on success and function(HTTPStatus) on HTTP error */ xmlHttpRequestWrapper: function(method, endpoint, data, token, extraTimeout) { var deferred = Q.defer(); var postData = ""; try { var postData = JSON.stringify(data); } catch(e) { } var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if(xhr.status == 200) { var responseArr = safeJSONParse(xhr.responseText); deferred.resolve(responseArr); } else { deferred.reject(xhr.status); } } }; xhr.open(method, _internalSecurityServicesWebAPI.baseURL + endpoint, true); xhr.timeout = _internalSecurityServicesWebAPI.defaultTimeout + extraTimeout; xhr.setRequestHeader('x-jwstoken', token); xhr.send(postData); return deferred.promise; }, /** * Calls a security API function. If the RAT is about to expire or expired, it will be renewed. * @param megaFunction the mega function to execute * @param method the method to execute * @param data parameters to be sent, given in JSON * @param isVolatile states whether or not keepalive is required for this call * @param extraTimeout an optional additional timeout for the HTTP request. If not specified, the HTTP request will have default timeout * @return a promise which returns the response text on success and API error code on failure */ callAPI: function(megaFunction, method, data, isVolatile, extraTimeout) { var deferred = Q.defer(); if(!extraTimeout) { extraTimeout = 0; } if(!isValidNonNegativeSafeInteger(extraTimeout)) { deferred.reject('Internal error occurred'); return deferred.promise; } var uri = _internalSecurityServicesWebAPI.capability + "/" + megaFunction + "/" + method + "/"; _internalSecurityServicesWebAPI.obtainRAT(false) .then( function() { if(!_internalSecurityServicesWebAPI.addVersionToObject(data)) { throw 'Internal error occurred'; } return _internalSecurityServicesWebAPI.xmlHttpRequestWrapper("POST", uri, data, _internalSecurityServicesWebAPI.resourceAccessToken, extraTimeout) .then( function(responseArr) { if(!responseArr.hasOwnProperty('errorCode')) { responseArr.errorCode = 1000; } if(isVolatile && !_internalSecurityServicesWebAPI.isKeepaliveRunning && (responseArr.errorCode === 0)) { setInterval(_internalSecurityServicesWebAPI.doKeepalive, _internalSecurityServicesWebAPI.keepaliveInterval); _internalSecurityServicesWebAPI.isKeepaliveRunning = true; } deferred.resolve(responseArr); } ) .catch( function(status) { var errorMsg = 'Internal error occurred'; if((status == 0) || (status == 400)) { errorMsg = 'Software component is missing'; } throw errorMsg; } ); } ) .catch( function(error) { deferred.reject(error); } ); return deferred.promise; }, /** * Adds a deferred object to the barrier. * @param deferred the deferred object to be added */ addToBarrier: function(deferred) { _internalSecurityServicesWebAPI.waitingPromises.push(deferred); }, /** * Clears the barrier and releases all the deferred objects. * @param isSuccess if true, promises will be resolved. Otherwise, they will be rejected. * @param error if not success, this error will be forwarded (string or error code) */ releaseBarrier: function(isSuccess, error) { _internalSecurityServicesWebAPI.acquisitionInProgress = false; while(_internalSecurityServicesWebAPI.waitingPromises.length > 0) { var deferred = _internalSecurityServicesWebAPI.waitingPromises.shift(); if(isSuccess) { deferred.resolve(); } else { deferred.reject(error); } } }, /** * Obtains a new RAT. * @param force If true, a new RAT will be requested even if we already have one */ obtainRAT: function(force) { var deferred = Q.defer(); _internalSecurityServicesWebAPI.resourceAccessToken = localStorage.getItem("resourceAccessToken"); if(_internalSecurityServicesWebAPI.resourceAccessToken == null) { _internalSecurityServicesWebAPI.resourceAccessToken = ""; } if (!force && _internalSecurityServicesWebAPI.resourceAccessToken != "") { if(!_internalSecurityServicesWebAPI.isRATExpired()) { deferred.resolve(); return deferred.promise; } } _internalSecurityServicesWebAPI.addToBarrier(deferred); if(_internalSecurityServicesWebAPI.acquisitionInProgress) { return deferred.promise; } _internalSecurityServicesWebAPI.acquisitionInProgress = true; if (!Date.now) { Date.now = function () { return new Date().getTime(); } } var iat = Date.now(); var exp = iat + 5400000; var data = { 'iat': iat, 'explp': exp, 'cap': [_internalSecurityServicesWebAPI.capability], 'old-rat': _internalSecurityServicesWebAPI.resourceAccessToken, }; if(!_internalSecurityServicesWebAPI.addVersionToObject(data)) { releaseBarrier(false, 'Internal error occurred'); } else { _internalSecurityServicesWebAPI.xmlHttpRequestWrapper("POST", _internalSecurityServicesWebAPI.endpointRAT, data, "", 0) .then( function(responseArr) { _internalSecurityServicesWebAPI.resourceAccessToken = responseArr.ResourceAccessToken; localStorage.setItem("resourceAccessToken", _internalSecurityServicesWebAPI.resourceAccessToken); if (_internalSecurityServicesWebAPI.resourceAccessToken == null) { _internalSecurityServicesWebAPI.releaseBarrier(false, 'Internal error occurred'); } else { _internalSecurityServicesWebAPI.releaseBarrier(true); } } ) .catch( function(status) { var msg = 'Internal error occurred'; if(status == 0) { msg = 'Software component is missing'; } _internalSecurityServicesWebAPI.releaseBarrier(false, msg); } ); } return deferred.promise; }, /** * Checks if the current RAT is about to expire or has expired. * @return true if the RAT is about to expire, has expired or on error. */ isRATExpired: function() { try { var exptime = JSON.parse(atob(_internalSecurityServicesWebAPI.resourceAccessToken.split(".")[1])).explp; return Date.now() >= exptime - 5000; } catch(e) { return true; } }, doKeepalive: function() { _internalSecurityServicesWebAPI.obtainRAT(false).then( function() { var data = {}; if(_internalSecurityServicesWebAPI.addVersionToObject(data)) { var endpoint = _internalSecurityServicesWebAPI.capability + _internalSecurityServicesWebAPI.endpointKeepalive; _internalSecurityServicesWebAPI.xmlHttpRequestWrapper("POST", endpoint, data, _internalSecurityServicesWebAPI.resourceAccessToken, 0); } } ); }, }; /** * Helper function: * Call the success callback if it is a function, else do nothing. * @param {function} successCallback - the success callback function. * @param {*} (optional) val - value to call the callback with. */ function callSuccess(successCallback) { if(typeof successCallback === "function"){ if(arguments.length === 1){ successCallback(); }else if(arguments.length === 2){ successCallback(arguments[1]); }else{ throw 'Internal error occurred'; } } } /** * Helper function: * Checks if val is a number with boolean value '1' or '0'. * @param {Number} val - the number val to check */ function isNumberBooleanValue(val) { return (val !== 0 && val !== 1); } /** * Helper function: * Checks if the object is empty {} * @param {Object} object - the object to check */ function isEmptyObject(object) { for (var element in object) { if (object.hasOwnProperty(element)) return false; } return true; } /* arg1 - array, contains the arguments passed to the API call (Options or InstanceID) funcAsync - function, the API function to call this function create and return a promise object that will reject when the API call fails, or resolve when the API call succeed. */ function _createPromise(arg1, funcAsync) { var deferred = Q.defer(); funcAsync( function(returnValue) { // success deferred.resolve(returnValue); }, function(errorMsg) { // failure deferred.reject(errorMsg); }, arg1); return deferred.promise; } /* Args - array, contains the arguments passed to the API call funcAsync - function, the function to call after dispatching type - string, the type of the first argument for this function ('Number' for instanceId and 'object' for options) This function gets the arguments from the API call, and do as follow: If only one argument passed and his type is the type we expecting (object type for �Options� and Number type for �instanceID�) we continue with the Promises methodology. In any other case, we Refers to the call as if it were with the old methodology. */ function _dispatch(Args, funcAsync, type) { if ( ((Args.length == 3) && (typeof Args[2] === type))) //if exactly one argument from the right type passed { funcAsync(Args[0], Args[1], Args[2]); //Refers to the call as if it were with the old methodology. return null; } else { return _createPromise(Args[0], funcAsync); //continue with the Promises methodology. } } function safeJSONParse(jsonString) { var parsedString = ""; try { parsedString = JSON.parse(jsonString); } catch (err) { return ""; } return parsedString; } var IntelSecurityServicesSecureData = { isVolatile: true, createFromDataExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "createfromdata"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.instanceID); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, createFromSealedDataExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "createfromsealeddata"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.instanceID); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, changeExtraKeyExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "changeextrakey"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, getDataExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "getdata"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.retData); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, getSealedDataExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "getsealeddata"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.retData); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, getTagExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "gettag"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.retTag); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, getPolicyExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "getpolicy"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.policy); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, getOwnersExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "getowners"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.owners); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, getCreatorExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "getcreator"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.retCreator); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, getWebOwnersExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "getwebowners"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.retWebOwners); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, destroyExec: function(success, fail, service, action, args) { var megaFunction = "securedata"; var method = "destroy"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureData.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); } }; var IntelSecurityServicesSecureStorage = { isVolatile: false, readExec: function(success, fail, service, action, args) { var megaFunction = "securestorage"; var method = "read"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, true).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr.instanceID); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, writeExec: function(success, fail, service, action, args) { var megaFunction = "securestorage"; var method = "write"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureStorage.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, deleteExec: function(success, fail, service, action, args) { var megaFunction = "securestorage"; var method = "delete"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureStorage.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, }; var IntelSecurityServicesSecureTransport = { isVolatile: true, instanceIDToTimeout: { }, openExec: function(success, fail, service, action, args) { var megaFunction = "securetransport"; var method = "open"; var requestedTimeout = args.timeout; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureTransport.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { IntelSecurityServicesSecureTransport.instanceIDToTimeout[responseArr.instanceID] = requestedTimeout; callSuccess(success,responseArr.instanceID); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, setURLExec: function(success, fail, service, action, args) { var megaFunction = "securetransport"; var method = "seturl"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureTransport.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, setMethodExec: function(success, fail, service, action, args) { var megaFunction = "securetransport"; var method = "setmethod"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureTransport.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, setHeadersExec: function(success, fail, service, action, args) { var megaFunction = "securetransport"; var method = "setheaders"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureTransport.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, sendRequestExec: function(success, fail, service, action, args) { var megaFunction = "securetransport"; var method = "sendrequest"; var extraTimeout = 0; if(IntelSecurityServicesSecureTransport.instanceIDToTimeout.hasOwnProperty(args.instanceID)) { extraTimeout = IntelSecurityServicesSecureTransport.instanceIDToTimeout[args.instanceID]; } _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureTransport.isVolatile, extraTimeout).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success,responseArr); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, abortExec: function(success, fail, service, action, args) { var megaFunction = "securetransport"; var method = "abort"; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureTransport.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, destroyExec: function(success, fail, service, action, args) { var megaFunction = "securetransport"; var method = "destroy"; var instanceID = args.instanceID; _internalSecurityServicesWebAPI.callAPI(megaFunction, method, args, IntelSecurityServicesSecureTransport.isVolatile).then( function(responseArr) { if (responseArr.errorCode === 0) { delete IntelSecurityServicesSecureTransport.instanceIDToTimeout[instanceID]; callSuccess(success); } else { throw responseArr.errorCode; } } ).catch( function(msg) { fail(msg); } ); }, };//Secure Data Asynchronous API implementation var _internalSecureData = { createFromDataAsync: function(success, fail, options) { options = options || {}; var defaults = { data: '', tag: '', webOwners: [], extraKey: 0, appAccessControl: 0, deviceLocality: 0, sensitivityLevel: 0, noStore: false, noRead: false, creator: 0, owners: [0] }; for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } // check input type if ((typeof defaults.data !== 'string') || (typeof defaults.tag !== 'string') || (typeof defaults.webOwners !== 'object') || (!Array.isArray(defaults.webOwners)) || (!isValidNonNegativeSafeInteger(defaults.extraKey)) || (!isValidNonNegativeSafeInteger(defaults.appAccessControl)) || (!isValidNonNegativeSafeInteger(defaults.deviceLocality)) || (!isValidNonNegativeSafeInteger(defaults.sensitivityLevel)) || (!isBoolean(defaults.noStore)) || (!isBoolean(defaults.noRead)) || (!isValidNonNegativeSafeInteger(defaults.creator)) || (!isValidNonNegativeSafeIntegersArray(defaults.owners))) { failInternal('Argument type inconsistency detected', fail); } else { var webOwnersJSON = "[]"; try { if (defaults.webOwners != null) { for (var webOwner in defaults.webOwners) { if (typeof (defaults.webOwners[webOwner]) != "string") { failInternal('Argument type inconsistency detected', fail); return; } } } webOwnersJSON = JSON.stringify(defaults.webOwners); } catch (e) { failInternal('Argument type inconsistency detected', fail); return; } defaults.webOwnersJSON = webOwnersJSON; IntelSecurityServicesSecureData.createFromDataExec( function(instanceID) { successConvertToNumber(instanceID, success, fail); }, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataCreateFromData', defaults); } }, createFromSealedDataAsync: function(success, fail, options) { options = options || {}; var defaults = { sealedData: '', extraKey: 0 }; for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((typeof defaults.sealedData !== 'string') || (!isValidNonNegativeSafeInteger(defaults.extraKey))) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureData.createFromSealedDataExec( function(instanceID) { successConvertToNumber(instanceID, success, fail); }, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataCreateFromSealedData', defaults); } }, changeExtraKeyAsync: function(success, fail, options) { options = options || {}; var defaults = { instanceID: 0, extraKey: 0 }; for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if (!isValidNonNegativeSafeInteger(defaults.instanceID) || !isValidNonNegativeSafeInteger(defaults.extraKey)) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureData.changeExtraKeyExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataChangeExtraKey', defaults); } }, getDataAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureData.getDataExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataGetData', { instanceID: instanceID }); } }, getSealedDataAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureData.getSealedDataExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataGetSealedData', { instanceID: instanceID }); } }, getTagAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { var args = { instanceID: instanceID }; IntelSecurityServicesSecureData.getTagExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataGetTag', args); } }, getPolicyAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { var args = { instanceID: instanceID }; IntelSecurityServicesSecureData.getPolicyExec( function(policy) { if (isNumberBooleanValue(policy.noStore) || isNumberBooleanValue(policy.noRead)) { failInternal('Internal error occurred', fail); return; } policy.noStore = Boolean(policy.noStore); policy.noRead = Boolean(policy.noRead); success(policy); }, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataGetPolicy', args); } }, getOwnersAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { var args = { instanceID: instanceID }; IntelSecurityServicesSecureData.getOwnersExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataGetOwners', args); } }, getCreatorAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureData.getCreatorExec( function(instanceID) { successConvertToNumber(instanceID, success, fail); }, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataGetCreator', { instanceID: instanceID }); } }, getWebOwnersAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { var args = { instanceID: instanceID }; IntelSecurityServicesSecureData.getWebOwnersExec( function(webOwnersString) { try { var webOwnersArray = JSON.parse(webOwnersString); success(webOwnersArray); } catch (e) { failInternal("Internal error occurred", fail); } }, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataGetWebOwners', args); } }, destroyAsync: function(success, fail, instanceID) { if (!isValidNonNegativeSafeInteger(instanceID)) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureData.destroyExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureDataDestroy', { instanceID: instanceID }); } }, }; //Secure storage Asynchronous API implementation var _internalSecureStorage = { readAsync: function(success, fail, options) { options = options || {}; var defaults = { id: '', storageType: 0, extraKey: 0 }; for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((typeof defaults.id !== 'string') || (!isValidNonNegativeSafeInteger(defaults.storageType)) || (!isValidNonNegativeSafeInteger(defaults.extraKey))) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureStorage.readExec( function(instanceID) { successConvertToNumber(instanceID, success, fail); }, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureStorageRead', defaults); } }, writeAsync: function(success, fail, options) { options = options || {}; var defaults = { id: '', storageType: 0, instanceID: 0, }; for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((typeof defaults.id !== 'string') || (!isValidNonNegativeSafeInteger(defaults.storageType)) || (!isValidNonNegativeSafeInteger(defaults.instanceID))) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureStorage.writeExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureStorageWrite', defaults); } }, deleteAsync: function(success, fail, options) { options = options || {}; var defaults = { id: '', storageType: 0, }; for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((typeof defaults.id !== 'string') || (!isValidNonNegativeSafeInteger(defaults.storageType))) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureStorage.deleteExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureStorageDelete', defaults); } }, }; //Secure transport Asynchronous API implementation var _internalSecureTransport = { httpMethodType: { 'GET': 0, 'POST': 1, 'PUT': 2, 'DELETE': 3, 'HEAD': 4, 'OPTIONS': 5 }, requestFormatType: { 'GENERIC': 0, 'JSON': 1, 'XML': 2, }, openAsync: function(success, fail, options) { options = options || {}; //default value for the optional parameters var defaults = { url: '', method: 'GET', serverKey: '', timeout: 10000 }; //setting the default values in case they were not provided for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((typeof defaults.url !== 'string') || (typeof defaults.method !== 'string') || (typeof defaults.serverKey !== 'string') || (!isValidNonNegativeSafeInteger(defaults.timeout))) { failInternal('Argument type inconsistency detected', fail); } else if (_internalSecureTransport.httpMethodType.hasOwnProperty(defaults.method) === false) { failInternal('Invalid HTTP method', fail); } else { // convert method from string to number defaults.method = _internalSecureTransport.httpMethodType[defaults.method]; IntelSecurityServicesSecureTransport.openExec( function(instanceID) { successConvertToNumber(instanceID, success, fail); }, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureTransportOpen', defaults); } }, setURLAsync: function(success, fail, options) { options = options || {}; //default value for the optional parameters var defaults = { instanceID: 0, url: '', serverKey: '' }; //setting the default values in case they were not provided for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((!isValidNonNegativeSafeInteger(defaults.instanceID)) || (typeof defaults.serverKey !== 'string') || (typeof defaults.url !== 'string')) { failInternal('Argument type inconsistency detected', fail); } else { IntelSecurityServicesSecureTransport.setURLExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureTransportSetURL', defaults); } }, setMethodAsync: function(success, fail, options) { options = options || {}; //default value for the optional parameters var defaults = { instanceID: 0, method: '' }; //setting the default values in case they were not provided for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((!isValidNonNegativeSafeInteger(defaults.instanceID)) || (typeof defaults.method !== 'string')) { failInternal('Argument type inconsistency detected', fail); } else if (_internalSecureTransport.httpMethodType.hasOwnProperty(defaults.method) === false) { failInternal('Invalid HTTP method', fail); } else { // convert method from string to number defaults.method = _internalSecureTransport.httpMethodType[defaults.method]; IntelSecurityServicesSecureTransport.setMethodExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureTransportSetMethod', defaults); } }, setHeadersAsync: function(success, fail, options) { options = options || {}; //default value for the optional parameters var defaults = { instanceID: 0, headers: {} }; //setting the default values in case they were not provided for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((!isValidNonNegativeSafeInteger(defaults.instanceID)) || (typeof defaults.headers !== 'object')) { failInternal('Argument type inconsistency detected', fail); return; } if (Array.isArray(defaults.headers)) { failInternal('Argument type inconsistency detected', fail); return; } for (var key in defaults.headers) { if (typeof key !== 'string' || key === '' || typeof defaults.headers[key] !== 'string') { failInternal('Argument type inconsistency detected', fail); return; } } var headersJSON = ""; if (!isEmptyObject(defaults.headers)) { try { headersJSON = JSON.stringify(defaults.headers); } catch (e) { failInternal('Argument type inconsistency detected', fail); return; } } defaults.headers = headersJSON; IntelSecurityServicesSecureTransport.setHeadersExec( success, function(code) { failInternal(code, fail); }, 'IntelSecurity', 'SecureTransportSetHeaders', defaults); }, sendRequestAsync: function(success, fail, options) { options = options || {}; //default value for the optional parameters var defaults = { instanceID: 0, requestBody: '', requestFormat: 'GENERIC', secureDataDescriptors: [] }; //setting the default values in case they were not provided for (var key in defaults) { if (options[key] !== undefined) { defaults[key] = options[key]; } } if ((!isValidNonNegativeSafeInteger(defaults.instanceID)) || (typeof defaults.requestBody !== 'string') || (typeof defaults.requestFormat !== 'string') || (!(defaults.secureDataDescriptors instanceof Array))) { failInternal('Argument type inconsistency detected', fail); } else if (_internalSecureTransport.requestFormatType.hasOwnProperty(defaults.requestFormat) === false) { failInternal('Invalid request format', fail); } else { // convert format from string to number defaults.requestFormat = _internalSecureTransport.requestFormatType[defaults.requestFormat]; var secureDataDescriptorsJSON = null; try { secureDataDescriptorsJSON = JSON.stringify(defaults.secureDataDescriptors); } catch (e) {