Przeglądaj źródła

Refactored converse-otr.js

- Removed password encryption of the key.
  It never properly worked and bloated the build through extra dependencies.
- Store the key and instance tag on the ChatBox model.
JC Brand 8 lat temu
rodzic
commit
ba9d3c36d5
5 zmienionych plików z 35 dodań i 125 usunięć
  1. 0 1
      bower.json
  2. 1 14
      config.js
  3. 0 1
      package.json
  4. 0 25
      spec/otr.js
  5. 34 84
      src/converse-otr.js

+ 0 - 1
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": {},

+ 1 - 14
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",
 

+ 0 - 1
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",

+ 0 - 25
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 <message> stanzas", mock.initConverse(function (_converse) {
             test_utils.openControlBox();
             test_utils.openContactsPanel(_converse);

+ 34 - 84
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;
-                }
-            });
         }
     });
 }));