diff --git a/Gruntfile.js b/Gruntfile.js index 8a1b78e12..3d3fb037f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -70,7 +70,6 @@ module.exports = function(grunt) { }, app: { src: [ - 'app/assets/javascripts/app/services/encryption/*.js', // this should come first 'app/assets/javascripts/app/*.js', 'app/assets/javascripts/app/controllers/**/*.js', 'app/assets/javascripts/app/models/**/*.js', @@ -83,9 +82,9 @@ module.exports = function(grunt) { lib: { src: [ + 'node_modules/standard-file-js/dist/sfjs.js', 'vendor/assets/bower_components/angular/angular.js', - 'vendor/assets/javascripts/lodash/lodash.custom.min.js', - 'vendor/assets/javascripts/crypto/*.js' + 'vendor/assets/javascripts/lodash/lodash.custom.min.js' ], dest: 'vendor/assets/javascripts/lib.js', }, diff --git a/app/assets/javascripts/app/app.js b/app/assets/javascripts/app/app.js index 4fc96cf34..b1abb4f75 100644 --- a/app/assets/javascripts/app/app.js +++ b/app/assets/javascripts/app/app.js @@ -1,18 +1,7 @@ 'use strict'; -var Neeto = window.Neeto = Neeto || {}; var SN = SN || {}; -// detect IE8 and above, and edge. -// IE and Edge do not support pbkdf2 in WebCrypto, therefore we need to use CryptoJS -var IEOrEdge = document.documentMode || /Edge/.test(navigator.userAgent); - -if(!IEOrEdge && (window.crypto && window.crypto.subtle)) { - Neeto.crypto = new SNCryptoWeb(); -} else { - Neeto.crypto = new SNCryptoJS(); -} - angular.module('app', []) function getParameterByName(name, url) { diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index dad9c0525..c72f59b16 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -296,9 +296,9 @@ class AccountMenu { }.bind(this) if(data.auth_params) { - Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: password}, data.auth_params), function(keys){ + SFJS.crypto.computeEncryptionKeysForUser(_.merge({password: password}, data.auth_params), function(keys){ try { - EncryptionHelper.decryptMultipleItems(data.items, keys, false); /* throws = false as we don't want to interrupt all decryption if just one fails */ + SFItemTransformer.decryptMultipleItems(data.items, keys, false); /* throws = false as we don't want to interrupt all decryption if just one fails */ // delete items enc_item_key since the user's actually key will do the encrypting once its passed off data.items.forEach(function(item){ item.enc_item_key = null; @@ -479,7 +479,7 @@ class AccountMenu { $scope.securityUpdateData.processing = true; var authParams = authManager.getAuthParams(); - Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: $scope.securityUpdateData.password}, authParams), function(keys){ + SFJS.crypto.computeEncryptionKeysForUser(_.merge({password: $scope.securityUpdateData.password}, authParams), function(keys){ if(keys.mk !== authManager.keys().mk) { alert("Invalid password. Please try again."); $timeout(function(){ diff --git a/app/assets/javascripts/app/models/api/item.js b/app/assets/javascripts/app/models/api/item.js index e6b43a057..caf061735 100644 --- a/app/assets/javascripts/app/models/api/item.js +++ b/app/assets/javascripts/app/models/api/item.js @@ -9,7 +9,7 @@ class Item { this.observers = []; if(!this.uuid) { - this.uuid = Neeto.crypto.generateUUID(); + this.uuid = SFJS.crypto.generateUUID(); } } diff --git a/app/assets/javascripts/app/models/local/itemParams.js b/app/assets/javascripts/app/models/local/itemParams.js index c669080bf..87f91df9e 100644 --- a/app/assets/javascripts/app/models/local/itemParams.js +++ b/app/assets/javascripts/app/models/local/itemParams.js @@ -39,7 +39,7 @@ class ItemParams { // Items should always be encrypted for export files. Only respect item.doNotEncrypt for remote sync params; var doNotEncrypt = this.item.doNotEncrypt() && !this.forExportFile; if(this.keys && !doNotEncrypt) { - var encryptedParams = EncryptionHelper.encryptItem(this.item, this.keys, this.version); + var encryptedParams = SFItemTransformer.encryptItem(this.item, this.keys, this.version); _.merge(params, encryptedParams); if(this.version !== "001") { @@ -47,7 +47,7 @@ class ItemParams { } } else { - params.content = this.forExportFile ? this.item.createContentJSONFromProperties() : "000" + Neeto.crypto.base64(JSON.stringify(this.item.createContentJSONFromProperties())); + params.content = this.forExportFile ? this.item.createContentJSONFromProperties() : "000" + SFJS.crypto.base64(JSON.stringify(this.item.createContentJSONFromProperties())); if(!this.forExportFile) { params.enc_item_key = null; params.auth_hash = null; diff --git a/app/assets/javascripts/app/services/actionsManager.js b/app/assets/javascripts/app/services/actionsManager.js index 85a30253b..f14c7e33a 100644 --- a/app/assets/javascripts/app/services/actionsManager.js +++ b/app/assets/javascripts/app/services/actionsManager.js @@ -63,7 +63,7 @@ class ActionsManager { this.httpManager.getAbsolute(action.url, {}, function(response){ action.error = false; var items = response.items || [response.item]; - EncryptionHelper.decryptMultipleItems(items, this.authManager.keys()); + SFItemTransformer.decryptMultipleItems(items, this.authManager.keys()); items = this.modelManager.mapResponseItemsToLocalModels(items, ModelManager.MappingSourceRemoteActionRetrieved); for(var item of items) { item.setDirty(true); @@ -82,7 +82,7 @@ class ActionsManager { this.httpManager.getAbsolute(action.url, {}, function(response){ action.error = false; - EncryptionHelper.decryptItem(response.item, this.authManager.keys()); + SFItemTransformer.decryptItem(response.item, this.authManager.keys()); var item = this.modelManager.createItem(response.item, true /* Dont notify observers */); customCallback({item: item}); diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index e90b92120..03bd61eb2 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -112,11 +112,7 @@ angular.module('app') // which accidentally used 60,000 iterations (now adjusted), which CryptoJS can't handle here (WebCrypto can however). // if user has high password cost and is using browser that doesn't support WebCrypto, // we want to tell them that they can't login with this browser. - if(cost > 5000) { - return Neeto.crypto instanceof SNCryptoWeb ? true : false; - } else { - return true; - } + return SFJS.crypto.supportsPasswordDerivationCost(cost); } this.login = function(url, email, password, ephemeral, extraParams, callback) { @@ -153,7 +149,7 @@ angular.module('app') return; } - Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: password}, authParams), function(keys){ + SFJS.crypto.computeEncryptionKeysForUser(_.merge({password: password}, authParams), function(keys){ var requestUrl = url + "/auth/sign_in"; var params = _.merge({password: keys.pw, email: email}, extraParams); @@ -202,7 +198,7 @@ angular.module('app') } this.register = function(url, email, password, ephemeral, callback) { - Neeto.crypto.generateInitialEncryptionKeysForUser({password: password, email: email}, function(keys, authParams){ + SFJS.crypto.generateInitialEncryptionKeysForUser({password: password, email: email}, function(keys, authParams){ var requestUrl = url + "/auth"; var params = _.merge({password: keys.pw, email: email}, authParams); @@ -221,7 +217,7 @@ angular.module('app') } this.changePassword = function(email, new_password, callback) { - Neeto.crypto.generateInitialEncryptionKeysForUser({password: new_password, email: email}, function(keys, authParams){ + SFJS.crypto.generateInitialEncryptionKeysForUser({password: new_password, email: email}, function(keys, authParams){ var requestUrl = storageManager.getItem("server") + "/auth/change_pw"; var params = _.merge({new_password: keys.pw}, authParams); diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index 484f0589c..4ebf7809e 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -716,7 +716,7 @@ class ComponentManager { console.log("Web|componentManager|registerComponentWindow", component); } component.window = componentWindow; - component.sessionKey = Neeto.crypto.generateUUID(); + component.sessionKey = SFJS.crypto.generateUUID(); this.sendMessageToComponent(component, { action: "component-registered", sessionKey: component.sessionKey, diff --git a/app/assets/javascripts/app/services/encryption/crypto.js b/app/assets/javascripts/app/services/encryption/crypto.js deleted file mode 100644 index 460bba70d..000000000 --- a/app/assets/javascripts/app/services/encryption/crypto.js +++ /dev/null @@ -1,108 +0,0 @@ -class SNCrypto { - - generateRandomKey(bits) { - return CryptoJS.lib.WordArray.random(bits/8).toString(); - } - - generateUUID() { - var crypto = window.crypto || window.msCrypto; - if(crypto) { - var buf = new Uint32Array(4); - crypto.getRandomValues(buf); - var idx = -1; - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - idx++; - var r = (buf[idx>>3] >> ((idx%8)*4))&15; - var v = c == 'x' ? r : (r&0x3|0x8); - return v.toString(16); - }); - } else { - var d = new Date().getTime(); - if(window.performance && typeof window.performance.now === "function"){ - d += performance.now(); //use high-precision timer if available - } - var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = (d + Math.random()*16)%16 | 0; - d = Math.floor(d/16); - return (c=='x' ? r : (r&0x3|0x8)).toString(16); - }); - return uuid; - } - } - - decryptText({ciphertextToAuth, contentCiphertext, encryptionKey, iv, authHash, authKey} = {}, requiresAuth) { - if(requiresAuth && !authHash) { - console.error("Auth hash is required."); - return; - } - - if(authHash) { - var localAuthHash = Neeto.crypto.hmac256(ciphertextToAuth, authKey); - if(authHash !== localAuthHash) { - console.error("Auth hash does not match, returning null."); - return null; - } - } - var keyData = CryptoJS.enc.Hex.parse(encryptionKey); - var ivData = CryptoJS.enc.Hex.parse(iv || ""); - var decrypted = CryptoJS.AES.decrypt(contentCiphertext, keyData, { iv: ivData, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); - return decrypted.toString(CryptoJS.enc.Utf8); - } - - encryptText(text, key, iv) { - var keyData = CryptoJS.enc.Hex.parse(key); - var ivData = CryptoJS.enc.Hex.parse(iv || ""); - var encrypted = CryptoJS.AES.encrypt(text, keyData, { iv: ivData, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); - return encrypted.toString(); - } - - generateRandomEncryptionKey() { - var salt = Neeto.crypto.generateRandomKey(512); - var passphrase = Neeto.crypto.generateRandomKey(512); - return CryptoJS.PBKDF2(passphrase, salt, { keySize: 512/32 }).toString(); - } - - firstHalfOfKey(key) { - return key.substring(0, key.length/2); - } - - secondHalfOfKey(key) { - return key.substring(key.length/2, key.length); - } - - base64(text) { - return window.btoa(text); - } - - base64Decode(base64String) { - return window.atob(base64String); - } - - sha256(text) { - return CryptoJS.SHA256(text).toString(); - } - - hmac256(message, key) { - var keyData = CryptoJS.enc.Hex.parse(key); - var messageData = CryptoJS.enc.Utf8.parse(message); - var result = CryptoJS.HmacSHA256(messageData, keyData).toString(); - return result; - } - - computeEncryptionKeysForUser({password, pw_salt, pw_cost} = {}, callback) { - this.generateSymmetricKeyPair({password: password, pw_salt: pw_salt, pw_cost: pw_cost}, function(keys){ - callback({pw: keys[0], mk: keys[1], ak: keys[2]}); - }.bind(this)); - } - - generateInitialEncryptionKeysForUser({email, password} = {}, callback) { - var pw_cost = this.defaultPasswordGenerationCost(); - var pw_nonce = this.generateRandomKey(512); - var pw_salt = this.sha256([email, pw_nonce].join(":")); - this.generateSymmetricKeyPair({password: password, pw_salt: pw_salt, pw_cost: pw_cost}, function(keys){ - callback({pw: keys[0], mk: keys[1], ak: keys[2]}, {pw_salt: pw_salt, pw_cost: pw_cost, version: "002"}); - }.bind(this)); - } -} - -export { SNCrypto } diff --git a/app/assets/javascripts/app/services/encryption/cryptojs.js b/app/assets/javascripts/app/services/encryption/cryptojs.js deleted file mode 100644 index 170c4f82f..000000000 --- a/app/assets/javascripts/app/services/encryption/cryptojs.js +++ /dev/null @@ -1,21 +0,0 @@ -class SNCryptoJS extends SNCrypto { - - /** Generates two deterministic keys based on one input */ - generateSymmetricKeyPair({password, pw_salt, pw_cost} = {}, callback) { - var output = CryptoJS.PBKDF2(password, pw_salt, { keySize: 768/32, hasher: CryptoJS.algo.SHA512, iterations: pw_cost }).toString(); - - var outputLength = output.length; - var splitLength = outputLength/3; - var firstThird = output.slice(0, splitLength); - var secondThird = output.slice(splitLength, splitLength * 2); - var thirdThird = output.slice(splitLength * 2, splitLength * 3); - callback([firstThird, secondThird, thirdThird]) - } - - defaultPasswordGenerationCost() { - return 3000; - } - } - - -export { SNCryptoJS } diff --git a/app/assets/javascripts/app/services/encryption/encryptionHelper.js b/app/assets/javascripts/app/services/encryption/encryptionHelper.js deleted file mode 100644 index c724de309..000000000 --- a/app/assets/javascripts/app/services/encryption/encryptionHelper.js +++ /dev/null @@ -1,163 +0,0 @@ -class EncryptionHelper { - - static _private_encryptString(string, encryptionKey, authKey, uuid, version) { - var fullCiphertext, contentCiphertext; - if(version === "001") { - contentCiphertext = Neeto.crypto.encryptText(string, encryptionKey, null); - fullCiphertext = version + contentCiphertext; - } else { - var iv = Neeto.crypto.generateRandomKey(128); - contentCiphertext = Neeto.crypto.encryptText(string, encryptionKey, iv); - var ciphertextToAuth = [version, uuid, iv, contentCiphertext].join(":"); - var authHash = Neeto.crypto.hmac256(ciphertextToAuth, authKey); - fullCiphertext = [version, authHash, uuid, iv, contentCiphertext].join(":"); - } - - return fullCiphertext; - } - - static encryptItem(item, keys, version = "002") { - var params = {}; - // encrypt item key - var item_key = Neeto.crypto.generateRandomEncryptionKey(); - if(version === "001") { - // legacy - params.enc_item_key = Neeto.crypto.encryptText(item_key, keys.mk, null); - } else { - params.enc_item_key = this._private_encryptString(item_key, keys.mk, keys.ak, item.uuid, version); - } - - // encrypt content - var ek = Neeto.crypto.firstHalfOfKey(item_key); - var ak = Neeto.crypto.secondHalfOfKey(item_key); - var ciphertext = this._private_encryptString(JSON.stringify(item.createContentJSONFromProperties()), ek, ak, item.uuid, version); - if(version === "001") { - var authHash = Neeto.crypto.hmac256(ciphertext, ak); - params.auth_hash = authHash; - } - - params.content = ciphertext; - return params; - } - - static encryptionComponentsFromString(string, encryptionKey, authKey) { - var encryptionVersion = string.substring(0, 3); - if(encryptionVersion === "001") { - return { - contentCiphertext: string.substring(3, string.length), - encryptionVersion: encryptionVersion, - ciphertextToAuth: string, - iv: null, - authHash: null, - encryptionKey: encryptionKey, - authKey: authKey - } - } else { - let components = string.split(":"); - return { - encryptionVersion: components[0], - authHash: components[1], - uuid: components[2], - iv: components[3], - contentCiphertext: components[4], - ciphertextToAuth: [components[0], components[2], components[3], components[4]].join(":"), - encryptionKey: encryptionKey, - authKey: authKey - } - } - } - - static decryptItem(item, keys) { - - if((item.content.startsWith("001") || item.content.startsWith("002")) && item.enc_item_key) { - // is encrypted, continue to below - } else { - // is base64 encoded - try { - item.content = JSON.parse(Neeto.crypto.base64Decode(item.content.substring(3, item.content.length))); - } catch (e) {} - - return; - } - - // decrypt encrypted key - var encryptedItemKey = item.enc_item_key; - var requiresAuth = true; - if(encryptedItemKey.startsWith("002") === false) { - // legacy encryption type, has no prefix - encryptedItemKey = "001" + encryptedItemKey; - requiresAuth = false; - } - var keyParams = this.encryptionComponentsFromString(encryptedItemKey, keys.mk, keys.ak); - - // return if uuid in auth hash does not match item uuid. Signs of tampering. - if(keyParams.uuid && keyParams.uuid !== item.uuid) { - if(!item.errorDecrypting) { item.errorDecryptingValueChanged = true;} - item.errorDecrypting = true; - return; - } - - var item_key = Neeto.crypto.decryptText(keyParams, requiresAuth); - - if(!item_key) { - if(!item.errorDecrypting) { item.errorDecryptingValueChanged = true;} - item.errorDecrypting = true; - return; - } - - // decrypt content - var ek = Neeto.crypto.firstHalfOfKey(item_key); - var ak = Neeto.crypto.secondHalfOfKey(item_key); - var itemParams = this.encryptionComponentsFromString(item.content, ek, ak); - - // return if uuid in auth hash does not match item uuid. Signs of tampering. - if(itemParams.uuid && itemParams.uuid !== item.uuid) { - if(!item.errorDecrypting) { item.errorDecryptingValueChanged = true;} - item.errorDecrypting = true; - return; - } - - if(!itemParams.authHash) { - // legacy 001 - itemParams.authHash = item.auth_hash; - } - - var content = Neeto.crypto.decryptText(itemParams, true); - if(!content) { - if(!item.errorDecrypting) { item.errorDecryptingValueChanged = true;} - item.errorDecrypting = true; - } else { - if(item.errorDecrypting == true) { item.errorDecryptingValueChanged = true;} - // Content should only be set if it was successfully decrypted, and should otherwise remain unchanged. - item.errorDecrypting = false; - item.content = content; - } - } - - static decryptMultipleItems(items, keys, throws) { - for (var item of items) { - - // 4/15/18: Adding item.content == null clause. We still want to decrypt deleted items incase - // they were marked as dirty but not yet synced. Not yet sure why we had this requirement. - if(item.deleted == true && item.content == null) { - continue; - } - - var isString = typeof item.content === 'string' || item.content instanceof String; - if(isString) { - try { - this.decryptItem(item, keys); - } catch (e) { - if(!item.errorDecrypting) { item.errorDecryptingValueChanged = true;} - item.errorDecrypting = true; - if(throws) { - throw e; - } - console.error("Error decrypting item", item, e); - continue; - } - } - } - } - -} diff --git a/app/assets/javascripts/app/services/encryption/webcrypto.js b/app/assets/javascripts/app/services/encryption/webcrypto.js deleted file mode 100644 index 21f5f446b..000000000 --- a/app/assets/javascripts/app/services/encryption/webcrypto.js +++ /dev/null @@ -1,122 +0,0 @@ -var subtleCrypto = window.crypto ? window.crypto.subtle : null; - -class SNCryptoWeb extends SNCrypto { - - /** - Overrides - */ - defaultPasswordGenerationCost() { - return 101000; - } - - /** Generates two deterministic keys based on one input */ - generateSymmetricKeyPair({password, pw_salt, pw_cost} = {}, callback) { - this.stretchPassword({password: password, pw_salt: pw_salt, pw_cost: pw_cost}, function(output){ - var outputLength = output.length; - var splitLength = outputLength/3; - var firstThird = output.slice(0, splitLength); - var secondThird = output.slice(splitLength, splitLength * 2); - var thirdThird = output.slice(splitLength * 2, splitLength * 3); - callback([firstThird, secondThird, thirdThird]) - }) - } - - /** - Internal - */ - - stretchPassword({password, pw_salt, pw_cost} = {}, callback) { - - this.webCryptoImportKey(password, function(key){ - - if(!key) { - console.log("Key is null, unable to continue"); - callback(null); - return; - } - - this.webCryptoDeriveBits({key: key, pw_salt: pw_salt, pw_cost: pw_cost}, function(key){ - if(!key) { - callback(null); - return; - } - - callback(key); - - }.bind(this)) - }.bind(this)) - } - - webCryptoImportKey(input, callback) { - subtleCrypto.importKey( - "raw", - this.stringToArrayBuffer(input), - {name: "PBKDF2"}, - false, - ["deriveBits"] - ) - .then(function(key){ - callback(key); - }) - .catch(function(err){ - console.error(err); - callback(null); - }); - } - - webCryptoDeriveBits({key, pw_salt, pw_cost} = {}, callback) { - subtleCrypto.deriveBits( - { - "name": "PBKDF2", - salt: this.stringToArrayBuffer(pw_salt), - iterations: pw_cost, - hash: {name: "SHA-512"}, - }, - key, - 768 - ) - .then(function(bits){ - var key = this.arrayBufferToHexString(new Uint8Array(bits)); - callback(key); - }.bind(this)) - .catch(function(err){ - console.error(err); - callback(null); - }); - } - - stringToArrayBuffer(string) { - // not available on Edge/IE - - if(window.TextEncoder) { - var encoder = new TextEncoder("utf-8"); - var result = encoder.encode(string); - return result; - } else { - string = unescape(encodeURIComponent(string)); - var buf = new ArrayBuffer(string.length); - var bufView = new Uint8Array(buf); - for (var i=0, strLen=string.length; i { - var cost = Neeto.crypto.defaultPasswordGenerationCost(); - var salt = Neeto.crypto.generateRandomKey(512); + var cost = SFJS.crypto.defaultPasswordGenerationCost(); + var salt = SFJS.crypto.generateRandomKey(512); var defaultParams = {pw_cost: cost, pw_salt: salt, version: "002"}; - Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: passcode}, defaultParams), function(keys) { + SFJS.crypto.computeEncryptionKeysForUser(_.merge({password: passcode}, defaultParams), function(keys) { defaultParams.hash = keys.pw; this._keys = keys; this._hasPasscode = true; diff --git a/app/assets/javascripts/app/services/storageManager.js b/app/assets/javascripts/app/services/storageManager.js index 83441e67f..9ff44f638 100644 --- a/app/assets/javascripts/app/services/storageManager.js +++ b/app/assets/javascripts/app/services/storageManager.js @@ -158,7 +158,7 @@ class StorageManager { decryptStorage() { var stored = JSON.parse(this.getItem("encryptedStorage", StorageManager.Fixed)); - EncryptionHelper.decryptItem(stored, this.encryptedStorageKeys); + SFItemTransformer.decryptItem(stored, this.encryptedStorageKeys); var encryptedStorage = new EncryptedStorage(stored); for(var key of Object.keys(encryptedStorage.storage)) { diff --git a/app/assets/javascripts/app/services/syncManager.js b/app/assets/javascripts/app/services/syncManager.js index 06affef76..18c515e07 100644 --- a/app/assets/javascripts/app/services/syncManager.js +++ b/app/assets/javascripts/app/services/syncManager.js @@ -407,7 +407,7 @@ class SyncManager { handleItemsResponse(responseItems, omitFields, source) { var keys = this.authManager.keys() || this.passcodeManager.keys(); - EncryptionHelper.decryptMultipleItems(responseItems, keys); + SFItemTransformer.decryptMultipleItems(responseItems, keys); var items = this.modelManager.mapResponseItemsToLocalModelsOmittingFields(responseItems, omitFields, source); // During the decryption process, items may be marked as "errorDecrypting". If so, we want to be sure @@ -450,7 +450,7 @@ class SyncManager { var mapping = unsaved[i]; var itemResponse = mapping.item; - EncryptionHelper.decryptMultipleItems([itemResponse], this.authManager.keys()); + SFItemTransformer.decryptMultipleItems([itemResponse], this.authManager.keys()); var item = this.modelManager.findItem(itemResponse.uuid); if(!item) { diff --git a/package-lock.json b/package-lock.json index 8555f1a06..a2088d598 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5996,6 +5996,12 @@ "integrity": "sha1-kQ9dKu17Ugxud3SZwfMuE5/eyxA=", "dev": true }, + "standard-file-js": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.0.14.tgz", + "integrity": "sha512-5Itu7w7qjdrUI+06Pq2aUCtCRdKt1oy3Ld3FzDDuZ6Cbyjb4g/oXqLDoQyoqdMmoqtGii+qt/QaYsSl7Ek5zgQ==", + "dev": true + }, "statuses": { "version": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", diff --git a/package.json b/package.json index 71547d01e..4cac3fbaf 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "karma-cli": "^1.0.1", "karma-jasmine": "^1.1.0", "karma-phantomjs-launcher": "^1.0.2", - "sn-stylekit": "1.0.12" + "sn-stylekit": "1.0.12", + "standard-file-js": "0.0.14" }, "license": "GPL-3.0" } diff --git a/vendor/assets/javascripts/crypto/aes.js b/vendor/assets/javascripts/crypto/aes.js deleted file mode 100755 index 827503cbd..000000000 --- a/vendor/assets/javascripts/crypto/aes.js +++ /dev/null @@ -1,35 +0,0 @@ -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, -r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< -32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>3]|=parseInt(a.substr(j, -2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}}, -q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w< -l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})(); -(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])}, -_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]), -f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f, -m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m, -E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/ -4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math); -(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a, -this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684, -1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})}, -decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d, -b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}(); -(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8, -16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;dd||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>> -8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t= -d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})(); diff --git a/vendor/assets/javascripts/crypto/hmac-sha256.js b/vendor/assets/javascripts/crypto/hmac-sha256.js deleted file mode 100755 index c822cfb1f..000000000 --- a/vendor/assets/javascripts/crypto/hmac-sha256.js +++ /dev/null @@ -1,18 +0,0 @@ -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -var CryptoJS=CryptoJS||function(h,s){var f={},g=f.lib={},q=function(){},m=g.Base={extend:function(a){q.prototype=this;var c=new q;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, -r=g.WordArray=m.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||k).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< -32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=m.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>3]|=parseInt(a.substr(b, -2),16)<<24-4*(b%8);return new r.init(d,c/2)}},n=l.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new r.init(d,c)}},j=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}}, -u=g.BufferedBlockAlgorithm=m.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var g=0;gn;){var j;a:{j=k;for(var u=h.sqrt(j),t=2;t<=u;t++)if(!(j%t)){j=!1;break a}j=!0}j&&(8>n&&(m[n]=l(h.pow(k,0.5))),r[n]=l(h.pow(k,1/3)),n++);k++}var a=[],f=f.SHA256=q.extend({_doReset:function(){this._hash=new g.init(m.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],g=b[2],j=b[3],h=b[4],m=b[5],n=b[6],q=b[7],p=0;64>p;p++){if(16>p)a[p]= -c[d+p]|0;else{var k=a[p-15],l=a[p-2];a[p]=((k<<25|k>>>7)^(k<<14|k>>>18)^k>>>3)+a[p-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+a[p-16]}k=q+((h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25))+(h&m^~h&n)+r[p]+a[p];l=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&g^f&g);q=n;n=m;m=h;h=j+k|0;j=g;g=f;f=e;e=k+l|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+g|0;b[3]=b[3]+j|0;b[4]=b[4]+h|0;b[5]=b[5]+m|0;b[6]=b[6]+n|0;b[7]=b[7]+q|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes; -d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=q.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=q._createHelper(f);s.HmacSHA256=q._createHmacHelper(f)})(Math); -(function(){var h=CryptoJS,s=h.enc.Utf8;h.algo.HMAC=h.lib.Base.extend({init:function(f,g){f=this._hasher=new f.init;"string"==typeof g&&(g=s.parse(g));var h=f.blockSize,m=4*h;g.sigBytes>m&&(g=f.finalize(g));g.clamp();for(var r=this._oKey=g.clone(),l=this._iKey=g.clone(),k=r.words,n=l.words,j=0;j>>2]|=(M[b>>>2]>>>24-8*(b%4)&255)<<24-8*((e+b)%4);else if(65535>>2]=M[b>>>2];else d.push.apply(d,M);this.sigBytes+=a;return this},clamp:function(){var D=this.words,d=this.sigBytes;D[d>>>2]&=4294967295<< -32-8*(d%4);D.length=a.ceil(d/4)},clone:function(){var a=l.clone.call(this);a.words=this.words.slice(0);return a},random:function(D){for(var d=[],b=0;b>>2]>>>24-8*(e%4)&255;b.push((c>>>4).toString(16));b.push((c&15).toString(16))}return b.join("")},parse:function(a){for(var d=a.length,b=[],e=0;e>>3]|=parseInt(a.substr(e, -2),16)<<24-4*(e%8);return new u.init(b,d/2)}},y=k.Latin1={stringify:function(a){var b=a.words;a=a.sigBytes;for(var c=[],e=0;e>>2]>>>24-8*(e%4)&255));return c.join("")},parse:function(a){for(var b=a.length,c=[],e=0;e>>2]|=(a.charCodeAt(e)&255)<<24-8*(e%4);return new u.init(c,b)}},z=k.Utf8={stringify:function(a){try{return decodeURIComponent(escape(y.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return y.parse(unescape(encodeURIComponent(a)))}}, -x=b.BufferedBlockAlgorithm=l.extend({reset:function(){this._data=new u.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=z.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(b){var d=this._data,c=d.words,e=d.sigBytes,l=this.blockSize,k=e/(4*l),k=b?a.ceil(k):a.max((k|0)-this._minBufferSize,0);b=k*l;e=a.min(4*b,e);if(b){for(var x=0;xm;m++)k[m]=a();b=b.SHA512=c.extend({_doReset:function(){this._hash=new l.init([new f.init(1779033703,4089235720),new f.init(3144134277,2227873595),new f.init(1013904242,4271175723),new f.init(2773480762,1595750129),new f.init(1359893119,2917565137),new f.init(2600822924,725511199),new f.init(528734635,4215389547),new f.init(1541459225,327033209)])},_doProcessBlock:function(a,b){for(var c=this._hash.words, -f=c[0],j=c[1],d=c[2],l=c[3],e=c[4],m=c[5],N=c[6],c=c[7],aa=f.high,O=f.low,ba=j.high,P=j.low,ca=d.high,Q=d.low,da=l.high,R=l.low,ea=e.high,S=e.low,fa=m.high,T=m.low,ga=N.high,U=N.low,ha=c.high,V=c.low,r=aa,n=O,G=ba,E=P,H=ca,F=Q,Y=da,I=R,s=ea,p=S,W=fa,J=T,X=ga,K=U,Z=ha,L=V,t=0;80>t;t++){var A=k[t];if(16>t)var q=A.high=a[b+2*t]|0,g=A.low=a[b+2*t+1]|0;else{var q=k[t-15],g=q.high,v=q.low,q=(g>>>1|v<<31)^(g>>>8|v<<24)^g>>>7,v=(v>>>1|g<<31)^(v>>>8|g<<24)^(v>>>7|g<<25),C=k[t-2],g=C.high,h=C.low,C=(g>>>19| -h<<13)^(g<<3|h>>>29)^g>>>6,h=(h>>>19|g<<13)^(h<<3|g>>>29)^(h>>>6|g<<26),g=k[t-7],$=g.high,B=k[t-16],w=B.high,B=B.low,g=v+g.low,q=q+$+(g>>>0>>0?1:0),g=g+h,q=q+C+(g>>>0>>0?1:0),g=g+B,q=q+w+(g>>>0>>0?1:0);A.high=q;A.low=g}var $=s&W^~s&X,B=p&J^~p&K,A=r&G^r&H^G&H,ka=n&E^n&F^E&F,v=(r>>>28|n<<4)^(r<<30|n>>>2)^(r<<25|n>>>7),C=(n>>>28|r<<4)^(n<<30|r>>>2)^(n<<25|r>>>7),h=u[t],la=h.high,ia=h.low,h=L+((p>>>14|s<<18)^(p>>>18|s<<14)^(p<<23|s>>>9)),w=Z+((s>>>14|p<<18)^(s>>>18|p<<14)^(s<<23|p>>>9))+(h>>> -0>>0?1:0),h=h+B,w=w+$+(h>>>0>>0?1:0),h=h+ia,w=w+la+(h>>>0>>0?1:0),h=h+g,w=w+q+(h>>>0>>0?1:0),g=C+ka,A=v+A+(g>>>0>>0?1:0),Z=X,L=K,X=W,K=J,W=s,J=p,p=I+h|0,s=Y+w+(p>>>0>>0?1:0)|0,Y=H,I=F,H=G,F=E,G=r,E=n,n=h+g|0,r=w+A+(n>>>0>>0?1:0)|0}O=f.low=O+n;f.high=aa+r+(O>>>0>>0?1:0);P=j.low=P+E;j.high=ba+G+(P>>>0>>0?1:0);Q=d.low=Q+F;d.high=ca+H+(Q>>>0>>0?1:0);R=l.low=R+I;l.high=da+Y+(R>>>0>>0?1:0);S=e.low=S+p;e.high=ea+s+(S>>>0

>>0?1:0);T=m.low=T+J;m.high=fa+W+(T>>>0>>0?1: -0);U=N.low=U+K;N.high=ga+X+(U>>>0>>0?1:0);V=c.low=V+L;c.high=ha+Z+(V>>>0>>0?1:0)},_doFinalize:function(){var a=this._data,b=a.words,c=8*this._nDataBytes,f=8*a.sigBytes;b[f>>>5]|=128<<24-f%32;b[(f+128>>>10<<5)+30]=Math.floor(c/4294967296);b[(f+128>>>10<<5)+31]=c;a.sigBytes=4*b.length;this._process();return this._hash.toX32()},clone:function(){var a=c.clone.call(this);a._hash=this._hash.clone();return a},blockSize:32});j.SHA512=c._createHelper(b);j.HmacSHA512=c._createHmacHelper(b)})(); -(function(){var a=CryptoJS,j=a.enc.Utf8;a.algo.HMAC=a.lib.Base.extend({init:function(a,b){a=this._hasher=new a.init;"string"==typeof b&&(b=j.parse(b));var f=a.blockSize,l=4*f;b.sigBytes>l&&(b=a.finalize(b));b.clamp();for(var u=this._oKey=b.clone(),k=this._iKey=b.clone(),m=u.words,y=k.words,z=0;z>>2]|=(p[b>>>2]>>>24-8*(b%4)&255)<<24-8*((f+b)%4);else if(65535>>2]=p[b>>>2];else c.push.apply(c,p);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< -32-8*(c%4);a.length=g.ceil(c/4)},clone:function(){var a=n.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b>>2]>>>24-8*(f%4)&255;b.push((d>>>4).toString(16));b.push((d&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f>>3]|=parseInt(a.substr(f, -2),16)<<24-4*(f%8);return new q.init(b,c/2)}},k=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f>>2]>>>24-8*(f%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f>>2]|=(a.charCodeAt(f)&255)<<24-8*(f%4);return new q.init(b,c)}},h=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(k.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return k.parse(unescape(encodeURIComponent(a)))}}, -u=d.BufferedBlockAlgorithm=n.extend({reset:function(){this._data=new q.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=h.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var b=this._data,d=b.words,f=b.sigBytes,l=this.blockSize,e=f/(4*l),e=a?g.ceil(e):g.max((e|0)-this._minBufferSize,0);a=e*l;f=g.min(4*a,f);if(a){for(var h=0;ha;a++){if(16>a)m[a]=d[e+a]|0;else{var c=m[a-3]^m[a-8]^m[a-14]^m[a-16];m[a]=c<<1|c>>>31}c=(l<<5|l>>>27)+j+m[a];c=20>a?c+((k&h|~k&g)+1518500249):40>a?c+((k^h^g)+1859775393):60>a?c+((k&h|k&g|h&g)-1894007588):c+((k^h^ -g)-899497514);j=g;g=h;h=k<<30|k>>>2;k=l;l=c}b[0]=b[0]+l|0;b[1]=b[1]+k|0;b[2]=b[2]+h|0;b[3]=b[3]+g|0;b[4]=b[4]+j|0},_doFinalize:function(){var d=this._data,e=d.words,b=8*this._nDataBytes,l=8*d.sigBytes;e[l>>>5]|=128<<24-l%32;e[(l+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(l+64>>>9<<4)+15]=b;d.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=d.clone.call(this);e._hash=this._hash.clone();return e}});g.SHA1=d._createHelper(j);g.HmacSHA1=d._createHmacHelper(j)})(); -(function(){var g=CryptoJS,j=g.enc.Utf8;g.algo.HMAC=g.lib.Base.extend({init:function(e,d){e=this._hasher=new e.init;"string"==typeof d&&(d=j.parse(d));var g=e.blockSize,n=4*g;d.sigBytes>n&&(d=e.finalize(d));d.clamp();for(var q=this._oKey=d.clone(),b=this._iKey=d.clone(),l=q.words,k=b.words,h=0;h>>2]|=(q[b>>>2]>>>24-8*(b%4)&255)<<24-8*((d+b)%4);else if(65535>>2]=q[b>>>2];else c.push.apply(c,q);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< -32-8*(c%4);a.length=e.ceil(c/4)},clone:function(){var a=f.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b>>2]>>>24-8*(d%4)&255;b.push((f>>>4).toString(16));b.push((f&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],d=0;d>>3]|=parseInt(a.substr(d, -2),16)<<24-4*(d%8);return new n.init(b,c/2)}},g=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],d=0;d>>2]>>>24-8*(d%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],d=0;d>>2]|=(a.charCodeAt(d)&255)<<24-8*(d%4);return new n.init(b,c)}},r=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(g.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return g.parse(unescape(encodeURIComponent(a)))}}, -k=j.BufferedBlockAlgorithm=f.extend({reset:function(){this._data=new n.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=r.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,b=c.words,d=c.sigBytes,f=this.blockSize,h=d/(4*f),h=a?e.ceil(h):e.max((h|0)-this._minBufferSize,0);a=h*f;d=e.min(4*a,d);if(a){for(var g=0;ga;a++){if(16>a)l[a]=f[n+a]|0;else{var c=l[a-3]^l[a-8]^l[a-14]^l[a-16];l[a]=c<<1|c>>>31}c=(h<<5|h>>>27)+j+l[a];c=20>a?c+((g&e|~g&k)+1518500249):40>a?c+((g^e^k)+1859775393):60>a?c+((g&e|g&k|e&k)-1894007588):c+((g^e^ -k)-899497514);j=k;k=e;e=g<<30|g>>>2;g=h;h=c}b[0]=b[0]+h|0;b[1]=b[1]+g|0;b[2]=b[2]+e|0;b[3]=b[3]+k|0;b[4]=b[4]+j|0},_doFinalize:function(){var f=this._data,e=f.words,b=8*this._nDataBytes,h=8*f.sigBytes;e[h>>>5]|=128<<24-h%32;e[(h+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(h+64>>>9<<4)+15]=b;f.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=j.clone.call(this);e._hash=this._hash.clone();return e}});e.SHA1=j._createHelper(m);e.HmacSHA1=j._createHmacHelper(m)})();