diff --git a/bower.json b/bower.json index 929117da4..4f803cfe5 100644 --- a/bower.json +++ b/bower.json @@ -6,7 +6,6 @@ "devDependencies": { "bootstrap": "~3.2.0", "bourbon": "~4.2.6", - "crypto-js-evanvosberg": "https://github.com/evanvosberg/crypto-js.git#release-3.1.2-5", "fontawesome": "~4.1.0" }, "dependencies": {}, diff --git a/config.js b/config.js index e5d439470..2a134bbec 100644 --- a/config.js +++ b/config.js @@ -67,21 +67,8 @@ require.config({ "converse-vcard": "src/converse-vcard", // Off-the-record-encryption - "bigint": "node_modules/otr/vendor/bigint", + "bigint": "node_modules/otr/build/dep/bigint", "crypto": "node_modules/otr/build/dep/crypto", - "aes": "node_modules/crypto-js/aes", - "cipher-core": "node_modules/crypto-js/cipher-core", - "core": "node_modules/crypto-js/core", - "const": "node_modules/otr/lib/const", - "helpers": "node_modules/otr/lib/helpers", - "sha1": "node_modules/crypto-js/sha1", - "hmac": "node_modules/crypto-js/hmac", - "enc-base64": "node_modules/crypto-js/enc-base64", - "evpkdf": "node_modules/crypto-js/evpkdf", - "md5": "node_modules/crypto-js/md5", - "mode-ctr": "node_modules/crypto-js/mode-ctr", - "pad-nopadding": "node_modules/crypto-js/pad-nopadding", - "sha256": "node_modules/crypto-js/sha256", "salsa20": "node_modules/otr/build/dep/salsa20", "otr": "node_modules/otr/build/otr", diff --git a/package.json b/package.json index 3ccd00b72..847bb2423 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "backbone.overview": "0.0.3", "bower": "latest", "clean-css": "^3.4.19", - "crypto-js": "3.1.2-5", "eslint": "^3.14.1", "eslint-plugin-lodash": "^2.3.3", "greenkeeper": "^4.1.0", diff --git a/spec/otr.js b/spec/otr.js index c279546c7..25a190eeb 100644 --- a/spec/otr.js +++ b/spec/otr.js @@ -7,31 +7,6 @@ return describe("The OTR module", function() { - it("can store a session passphrase in session storage", mock.initConverse(function (_converse) { - // With no prebind, the user's XMPP password is used and nothing is - // stored in session storage. - test_utils.openControlBox(); - test_utils.openContactsPanel(_converse); - test_utils.createContacts(_converse, 'current'); - - var auth = _converse.authentication; - var pass = _converse.connection.pass; - _converse.authentication = "manual"; - _converse.connection.pass = 's3cr3t!'; - expect(_converse.otr.getSessionPassphrase()).toBe(_converse.connection.pass); - - // With prebind, a random passphrase is generated and stored in - // session storage. - _converse.authentication = "prebind"; - var pp = _converse.otr.getSessionPassphrase(); - expect(pp).not.toBe(_converse.connection.pass); - expect(pp).toBe(window.sessionStorage[b64_sha1(_converse.connection.jid)]); - - // Clean up - _converse.authentication = auth; - _converse.connection.pass = pass; - })); - it("will add processing hints to sent out encrypted stanzas", mock.initConverse(function (_converse) { test_utils.openControlBox(); test_utils.openContactsPanel(_converse); diff --git a/src/converse-otr.js b/src/converse-otr.js index 0981ec1ee..9987f5195 100644 --- a/src/converse-otr.js +++ b/src/converse-otr.js @@ -13,11 +13,9 @@ define(["converse-chatview", "tpl!toolbar_otr", - 'otr', - 'crypto', - 'aes' + 'otr' ], factory); -}(this, function (converse, tpl_toolbar_otr, otr, CryptoJS) { +}(this, function (converse, tpl_toolbar_otr, otr) { "use strict"; // Strophe methods for building stanzas @@ -33,7 +31,6 @@ )); var HAS_CRYPTO = HAS_CSPRNG && ( - (!_.isUndefined(CryptoJS)) && (!_.isUndefined(otr.OTR)) && (!_.isUndefined(otr.DSA)) ); @@ -59,14 +56,8 @@ // // New functions which don't exist yet can also be added. - _initialize: function () { - this.__super__._initialize.apply(this, arguments); - this.otr = new this.OTR(); - }, - registerGlobalEventHandlers: function () { this.__super__.registerGlobalEventHandlers(); - $(document).click(function () { if ($('.toggle-otr ul').is(':visible')) { $('.toggle-otr ul', this).slideUp(); @@ -81,9 +72,7 @@ initialize: function () { this.__super__.initialize.apply(this, arguments); if (this.get('box_id') !== 'controlbox') { - this.save({ - 'otr_status': this.get('otr_status') || UNENCRYPTED - }); + this.save({'otr_status': this.get('otr_status') || UNENCRYPTED}); } }, @@ -123,31 +112,34 @@ } } }, + + generatePrivateKey: function (instance_tag) { + var _converse = this.__super__._converse; + var key = new otr.DSA(); + var jid = _converse.connection.jid; + if (_converse.cache_otr_key) { + this.save({ + 'otr_priv_key': key.packPrivate(), + 'otr_instance_tag': instance_tag + }); + } + return key; + }, getSession: function (callback) { var _converse = this.__super__._converse, __ = _converse.__; - var cipher = CryptoJS.lib.PasswordBasedCipher; - var pass, instance_tag, saved_key, pass_check; + var instance_tag, saved_key; if (_converse.cache_otr_key) { - pass = _converse.otr.getSessionPassphrase(); - if (!_.isUndefined(pass)) { - instance_tag = window.sessionStorage[b64_sha1(this.id+'instance_tag')]; - saved_key = window.sessionStorage[b64_sha1(this.id+'priv_key')]; - pass_check = window.sessionStorage[b64_sha1(this.connection.jid+'pass_check')]; - if (saved_key && instance_tag && !_.isUndefined(pass_check)) { - var decrypted = cipher.decrypt(CryptoJS.algo.AES, saved_key, pass); - var key = otr.DSA.parsePrivate(decrypted.toString(CryptoJS.enc.Latin1)); - if (cipher.decrypt(CryptoJS.algo.AES, pass_check, pass).toString(CryptoJS.enc.Latin1) === 'match') { - // Verified that the passphrase is still the same - this.trigger('showHelpMessages', [__('Re-establishing encrypted session')]); - callback({ - 'key': key, - 'instance_tag': instance_tag - }); - return; // Our work is done here - } - } + instance_tag = this.get('otr_instance_tag'); + saved_key = otr.DSA.parsePrivate(this.get('otr_priv_key')); + if (saved_key && instance_tag) { + this.trigger('showHelpMessages', [__('Re-establishing encrypted session')]); + callback({ + 'key': saved_key, + 'instance_tag': instance_tag + }); + return; // Our work is done here } } // We need to generate a new key and instance tag @@ -157,10 +149,11 @@ null, true // show spinner ); + var that = this; window.setTimeout(function () { var instance_tag = otr.OTR.makeInstanceTag(); callback({ - 'key': _converse.otr.generatePrivateKey.call(this, instance_tag), + 'key': that.generatePrivateKey(instance_tag), 'instance_tag': instance_tag }); }, 500); @@ -466,6 +459,12 @@ var _converse = this._converse, __ = _converse.__; + this.updateSettings({ + allow_otr: true, + cache_otr_key: false, + use_otr_by_default: false + }); + // Add new HTML template _converse.templates.toolbar_otr = tpl_toolbar_otr; @@ -480,59 +479,10 @@ OTR_TRANSLATED_MAPPING[VERIFIED] = __('verified'); OTR_TRANSLATED_MAPPING[FINISHED] = __('finished'); - // For translations - __ = utils.__.bind(_converse); - // Configuration values for this plugin - var settings = { - allow_otr: true, - cache_otr_key: false, - use_otr_by_default: false - }; - _.extend(_converse.default_settings, settings); - _.extend(_converse, settings); - _.extend(_converse, _.pick(_converse.user_settings, _.keys(settings))); - // Only allow OTR if we have the capability _converse.allow_otr = _converse.allow_otr && HAS_CRYPTO; // Only use OTR by default if allow OTR is enabled to begin with _converse.use_otr_by_default = _converse.use_otr_by_default && _converse.allow_otr; - - // Backbone Models and Views - // ------------------------- - _converse.OTR = Backbone.Model.extend({ - // A model for managing OTR settings. - getSessionPassphrase: function () { - if (_converse.authentication === 'prebind') { - var key = b64_sha1(_converse.connection.jid), - pass = window.sessionStorage[key]; - if (_.isUndefined(pass)) { - pass = Math.floor(Math.random()*4294967295).toString(); - window.sessionStorage[key] = pass; - } - return pass; - } else { - return _converse.connection.pass; - } - }, - - generatePrivateKey: function (instance_tag) { - var key = new otr.DSA(); - var jid = _converse.connection.jid; - if (_converse.cache_otr_key) { - var cipher = CryptoJS.lib.PasswordBasedCipher; - var pass = this.getSessionPassphrase(); - if (!_.isUndefined(pass)) { - // Encrypt the key and set in sessionStorage. Also store instance tag. - window.sessionStorage[b64_sha1(jid+'priv_key')] = - cipher.encrypt(CryptoJS.algo.AES, key.packPrivate(), pass).toString(); - window.sessionStorage[b64_sha1(jid+'instance_tag')] = instance_tag; - window.sessionStorage[b64_sha1(jid+'pass_check')] = - cipher.encrypt(CryptoJS.algo.AES, 'match', pass).toString(); - } - } - return key; - } - }); } }); }));