Explorar o código

Finally able to send a message and decrypt it on the other side

Updates #497
JC Brand %!s(int64=7) %!d(string=hai) anos
pai
achega
3eb5e93f81
Modificáronse 2 ficheiros con 27 adicións e 36 borrados
  1. 2 2
      src/converse-chatboxes.js
  2. 25 34
      src/converse-omemo.js

+ 2 - 2
src/converse-chatboxes.js

@@ -551,8 +551,8 @@
                         }
                     }
                     const result = this.getMessageAttributesFromStanza(message, original_stanza)
-                    if (result instanceof Promise) {
-                        return new Promise((resolve, reject) => result.then(attrs => resolve(_create(attrs))).catch(reject));
+                    if (typeof result.then === "function") {
+                        return new Promise((resolve, reject) => result.then(attrs => resolve(_create(attrs))));
                     } else {
                         const message = _create(result)
                         return Promise.resolve(message);

+ 25 - 34
src/converse-omemo.js

@@ -228,16 +228,11 @@
                         }).then(out => (new TextDecoder()).decode(out));
                 },
 
-                decryptFromKeyAndTag (key_and_tag, obj) {
-                    const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
-                    return this.decryptMessage(_.extend(obj, {'key': aes_data.key, 'tag': aes_data.tag}));
-                },
-
                 reportDecryptionError (e) {
                     const { _converse } = this.__super__,
                           { __ } = _converse;
                     this.messages.create({
-                        'message': __("Sorry, could not decrypt a received OMEMO message due to an error.") + ` ${e.message}`,
+                        'message': __("Sorry, could not decrypt a received OMEMO message due to an error.") + `${e.name} ${e.message}`,
                         'type': 'error',
                     });
                     _converse.log(e, Strophe.LogLevel.ERROR);
@@ -260,34 +255,28 @@
                         // that it won't be used again by a different client. If the client already has a session
                         // with the sender's device, it MUST replace this session with the newly built session.
                         // The client MUST delete the private key belonging to the PreKey after use.
-                        //
-                        // TODO: republish bundle information with old prekey removed and with new prekey
-                        // TODO: The client MUST delete the private key belonging to the PreKey after use.
                         return session_cipher.decryptPreKeyWhisperMessage(libsignal_payload.body, 'binary')
                             .then(key_and_tag => {
-                                debugger;
-                                return this.decryptFromKeyAndTag(key_and_tag, attrs.encrypted)
-                            })
-                            .then((f) => {
-                                debugger;
-                                // TODO remove newly used key before
-                                // republishing
+                                const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
+                                return this.decryptMessage(_.extend(attrs.encrypted, {'key': aes_data.key, 'tag': aes_data.tag}));
+                            }).then(plaintext => {
+                                // TODO remove newly used key before republishing
                                 _converse.omemo.publishBundle()
-                            })
-                            .catch((e) => {
-                                debugger;
+                                return _.extend(attrs, {'plaintext': plaintext});
+                            }).catch((e) => {
                                 this.reportDecryptionError(e);
-                                return Promise.resolve(attrs);
+                                return attrs;
                             });
                     } else {
                         return session_cipher.decryptWhisperMessage(libsignal_payload.body, 'binary')
-                            .then(key_and_tag => this.decryptFromKeyAndTag(key_and_tag, attrs.encrypted))
-                            .then(plaintext => _.extend(attrs, {'plaintext': plaintext}))
-                            .catch((e) => {
-                                debugger;
-                                this.reportDecryptionError(e);
-                                return Promise.resolve(attrs);
-                            });
+                            .then(key_and_tag => {
+                                const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
+                                return this.decryptMessage(_.extend(attrs.encrypted, {'key': aes_data.key, 'tag': aes_data.tag}));
+                            }).then(plaintext => _.extend(attrs, {'plaintext': plaintext}))
+                              .catch((e) => {
+                                  this.reportDecryptionError(e);
+                                  return attrs;
+                              });
                     }
                 },
 
@@ -341,16 +330,14 @@
                             'tagLength': TAG_LENGTH
                         }
                         return window.crypto.subtle.encrypt(algo, key, new TextEncoder().encode(plaintext));
-                    }).then((ciphertext) => {
+                    }).then(ciphertext => {
                         return window.crypto.subtle.exportKey("jwk", key)
-                            .then((key_obj) => {
+                            .then(key_obj => {
                                 const tag = u.arrayBufferToBase64(ciphertext.slice(ciphertext.byteLength - ((TAG_LENGTH + 7) >> 3)));
-                                console.log('XXXX: Base64 TAG is '+tag);
-                                console.log('YYY: KEY is '+key_obj.k);
                                 return Promise.resolve({
                                     'key': key_obj.k,
                                     'tag': tag,
-                                    'key_and_tag': btoa(key_obj.k + tag),
+                                    'key_and_tag': key_obj.k + tag,
                                     'payload': u.arrayBufferToBase64(ciphertext),
                                     'iv': u.arrayBufferToBase64(iv)
                                 });
@@ -391,6 +378,9 @@
                     const body = __("This is an OMEMO encrypted message which your client doesn’t seem to support. "+
                                     "Find more information on https://conversations.im/omemo");
 
+                    if (!message.get('message')) {
+                        throw new Error("No message body to encrypt!");
+                    }
                     const stanza = $msg({
                             'from': _converse.connection.jid,
                             'to': this.get('jid'),
@@ -406,7 +396,7 @@
                             .c('encrypted', {'xmlns': Strophe.NS.OMEMO})
                                 .c('header', {'sid':  _converse.omemo_store.get('device_id')});
 
-                    return this.encryptMessage(message).then(obj => {
+                    return this.encryptMessage(message.get('message')).then(obj => {
                         // The 16 bytes key and the GCM authentication tag (The tag
                         // SHOULD have at least 128 bit) are concatenated and for each
                         // intended recipient device, i.e. both own devices as well as
@@ -426,7 +416,8 @@
                 sendMessage (attrs) {
                     const { _converse } = this.__super__,
                           { __ } = _converse;
-                    if (this.get('omemo_active')) {
+
+                    if (this.get('omemo_active') && attrs.message) {
                         const message = this.messages.create(attrs);
                         this.getBundlesAndBuildSessions()
                             .then(devices => this.createOMEMOMessageStanza(message, devices))