diff --git a/app/Bundle.php b/app/Bundle.php index 650460e3f..a49949f89 100644 --- a/app/Bundle.php +++ b/app/Bundle.php @@ -20,8 +20,10 @@ class Bundle extends Model $this->jid = $jid; $this->bundle_id = $bundleId; - $this->prekeypublic = (string)$bundle->signedPreKeyPublic; - $this->prekeysignature = (string)$bundle->signedPreKeySignature; + $this->signedprekeypublic = (string)$bundle->signedPreKeyPublic; + $this->signedprekeyid = (int)$bundle->signedPreKeyPublic->attributes()->signedPreKeyId; + $this->signedprekeysignature = (string)$bundle->signedPreKeySignature; + $this->identitykey = (string)$bundle->identityKey; $prekeys = []; @@ -38,8 +40,9 @@ class Bundle extends Model return ( isset($this->attributes['prekeys']) && $this->attributes['prekeys'] == $bundle->attributes['prekeys'] - && $this->attributes['prekeypublic'] == $bundle->attributes['prekeypublic'] - && $this->attributes['prekeysignature'] == $bundle->attributes['prekeysignature'] + && $this->attributes['signedprekeypublic'] == $bundle->attributes['signedprekeypublic'] + && $this->attributes['signedprekeyid'] == $bundle->attributes['signedprekeyid'] + && $this->attributes['signedprekeysignature'] == $bundle->attributes['signedprekeysignature'] && $this->attributes['identitykey'] == $bundle->attributes['identitykey'] ); } diff --git a/app/MessageOmemoHeader.php b/app/MessageOmemoHeader.php index da8d2357b..9f2b02acb 100644 --- a/app/MessageOmemoHeader.php +++ b/app/MessageOmemoHeader.php @@ -19,7 +19,7 @@ class MessageOmemoHeader public function set($stanza) { - $this->sid = (string)$stanza->encrypted->header->attributes()->sid; + $this->sid = (int)$stanza->encrypted->header->attributes()->sid; $this->iv = (string)$stanza->encrypted->header->iv; $this->payload = (string)$stanza->encrypted->payload; diff --git a/app/widgets/Chat/chat.js b/app/widgets/Chat/chat.js index 6e616a5fa..28400b4e3 100644 --- a/app/widgets/Chat/chat.js +++ b/app/widgets/Chat/chat.js @@ -136,8 +136,8 @@ var Chat = { sendMessage: function() { var textarea = Chat.getTextarea(); - var text = textarea.value; + var muc = Boolean(textarea.dataset.muc); var mucReceipts = false; var jid = textarea.dataset.jid; @@ -233,8 +233,8 @@ var Chat = { sessions = Object.values(sessions); sessions = sessions.map(devices => devices.includes(String(localDeviceId))); - ChatOmemo.getContactState(jid).then(enabled => { - let state = 'no'; + ChatOmemo.getContactState(jid).then(enabled => { + let state = 'no'; if (enabled) { /** @@ -243,18 +243,16 @@ var Chat = { * 2 some sessions need to be built, build then encrypt */ if (sessions.length > 0) { - if (sessions.every(good => good)) { - state = 'yes'; - } else { - state = 'build'; - } + state = (sessions.every(good => good)) + ? 'yes' + : 'build'; } } else { state = 'disabled'; } Chat.setOmemoState(state); - }); + }); }); }, setOmemoState: function(state) diff --git a/app/widgets/ChatOmemo/ChatOmemo.php b/app/widgets/ChatOmemo/ChatOmemo.php index 208c2ca06..ed56a49a1 100644 --- a/app/widgets/ChatOmemo/ChatOmemo.php +++ b/app/widgets/ChatOmemo/ChatOmemo.php @@ -133,8 +133,9 @@ class ChatOmemo extends \Movim\Widget\Base $pickedKey = array_rand($bundle->prekeys); return [ 'identitykey' => $bundle->identitykey, - 'prekeypublic' => $bundle->prekeypublic, - 'prekeysignature' => $bundle->prekeysignature, + 'signedprekeypublic' => $bundle->signedprekeypublic, + 'signedprekeyid' => $bundle->signedprekeyid, + 'signedprekeysignature' => $bundle->signedprekeysignature, 'prekey' => ['id' => $pickedKey, 'value' => $bundle->prekeys[$pickedKey]] ]; } diff --git a/app/widgets/ChatOmemo/chatomemo.js b/app/widgets/ChatOmemo/chatomemo.js index 2b01f6cf0..2772ee488 100644 --- a/app/widgets/ChatOmemo/chatomemo.js +++ b/app/widgets/ChatOmemo/chatomemo.js @@ -19,12 +19,11 @@ var ChatOmemo = { const identityKeyPair = await KeyHelper.generateIdentityKeyPair(); const bundle = {}; - const identityKey = MovimUtils.arrayBufferToBase64(identityKeyPair.pubKey); const localDeviceId = await store.getLocalRegistrationId(); const deviceId = localDeviceId ?? KeyHelper.generateRegistrationId(); - bundle['identityKey'] = identityKey; + bundle['identityKey'] = MovimUtils.arrayBufferToBase64(identityKeyPair.pubKey); bundle['deviceId'] = deviceId; store.setLocalRegistrationId(deviceId); @@ -88,28 +87,30 @@ var ChatOmemo = { Promise.all(promises).then(results => { Chat.setOmemoState('yes'); Chat.disableSending(); - Chat.sendMessage(); + + if (Chat.getTextarea().value.length > 0) { + Chat.sendMessage(); + } }); }, - handlePreKey: function (jid, deviceId, preKey) { + handlePreKey: async function (jid, deviceId, preKey) { var store = new ChatOmemoStorage(); var address = new libsignal.SignalProtocolAddress(jid, deviceId); var sessionBuilder = new libsignal.SessionBuilder(store, address); - var promise = sessionBuilder.processPreKey({ - registrationId: 0, + registrationId: parseInt(deviceId, 10), identityKey: MovimUtils.base64ToArrayBuffer(preKey.identitykey), signedPreKey: { - keyId: 1, - publicKey: MovimUtils.base64ToArrayBuffer(preKey.prekeypublic), - signature: MovimUtils.base64ToArrayBuffer(preKey.prekeysignature) + keyId: parseInt(preKey.signedprekeyid, 10), + publicKey: MovimUtils.base64ToArrayBuffer(preKey.signedprekeypublic), + signature: MovimUtils.base64ToArrayBuffer(preKey.signedprekeysignature) }, preKey: { keyId: preKey.prekey.id, publicKey: MovimUtils.base64ToArrayBuffer(preKey.prekey.value) } - }) + }); promise.then(function onsuccess() { console.log('success ' + jid + ':' + deviceId); @@ -190,7 +191,7 @@ var ChatOmemo = { let plainKey; try { - plainKey = await this.decryptDevice(atob(key.payload), key.prekey, message.jidfrom, message.omemoheader.sid); + plainKey = await this.decryptDevice(MovimUtils.base64ToArrayBuffer(key.payload), key.prekey, message.jidfrom, message.omemoheader.sid); } catch (err) { console.log('Error during decryption: ' + err); return; @@ -269,7 +270,7 @@ var ChatOmemo = { }); }, encryptDevice: function (plaintext, jid, deviceId) { - var address = new libsignal.SignalProtocolAddress(jid, deviceId); + var address = new libsignal.SignalProtocolAddress(jid, parseInt(deviceId, 10)); var store = new ChatOmemoStorage(); var sessionCipher = new libsignal.SessionCipher(store, address); @@ -277,16 +278,15 @@ var ChatOmemo = { .then(payload => ({ 'payload': payload, 'device': deviceId })); }, decryptDevice: async function(ciphertext, preKey, jid, deviceId) { - var address = new libsignal.SignalProtocolAddress(jid, deviceId); + var address = new libsignal.SignalProtocolAddress(jid, parseInt(deviceId, 10)); var store = new ChatOmemoStorage(); var sessionCipher = new libsignal.SessionCipher(store, address); - let plaintextBuffer; if (preKey) { - plaintextBuffer = await sessionCipher.decryptPreKeyWhisperMessage(ciphertext, 'binary'); + plaintextBuffer = await sessionCipher.decryptPreKeyWhisperMessage(ciphertext, 'binary'); } else { - plaintextBuffer = await sessionCipher.decryptWhisperMessage(ciphertext, 'binary'); + plaintextBuffer = await sessionCipher.decryptWhisperMessage(ciphertext, 'binary'); } return plaintextBuffer; diff --git a/app/widgets/ChatOmemo/chatomemo_storage.js b/app/widgets/ChatOmemo/chatomemo_storage.js index b734a1545..77d6ba79f 100644 --- a/app/widgets/ChatOmemo/chatomemo_storage.js +++ b/app/widgets/ChatOmemo/chatomemo_storage.js @@ -12,7 +12,7 @@ ChatOmemoStorage.prototype = { if (key === undefined || value === undefined || key === null || value === null) throw new Error("Tried to store undefined/null"); - localStorage.setObject(key, value); + return localStorage.setObject(key, value); }, get: function (key, defaultValue) { if (key === null || key === undefined) @@ -65,13 +65,13 @@ ChatOmemoStorage.prototype = { if (trusted === undefined) { return Promise.resolve(true); } - return Promise.resolve(true); - //return Promise.resolve(libsignal.util.toString(identityKey) === libsignal.util.toString(trusted)); + + return Promise.resolve(libsignal.util.toString(identityKey) === libsignal.util.toString(trusted)); }, loadIdentityKey: function (identifier) { if (identifier === null || identifier === undefined) throw new Error("Tried to get identity key for undefined/null key"); - return Promise.resolve(this.get(this.jid + '.identityKey' + identifier)); + return Promise.resolve(MovimUtils.base64ToArrayBuffer(this.get(this.jid + '.identityKey' + identifier))); }, saveIdentity: function (identifier, identityKey) { if (identifier === null || identifier === undefined) @@ -80,7 +80,7 @@ ChatOmemoStorage.prototype = { var address = new libsignal.SignalProtocolAddress.fromString(identifier); var existing = this.get(this.jid + '.identityKey' + address.getName()); - this.put(this.jid + '.identityKey' + address.getName(), identityKey) + this.put(this.jid + '.identityKey' + address.getName(), MovimUtils.arrayBufferToBase64(identityKey)) if (existing && toString(identityKey) !== toString(existing)) { return Promise.resolve(true); @@ -143,17 +143,19 @@ ChatOmemoStorage.prototype = { return Promise.resolve(this.remove(this.jid + '.session' + identifier)); }, removeAllSessions: function () { - for (key in Object.keys(localStorage) - .filter(key => key.startsWith(this.jid + '.session'))) { - this.remove(key); + let filtered = Object.keys(localStorage).filter(key => key.startsWith(this.jid + '.session')); + + for (id in filtered) { + this.remove(filtered[key]); } return Promise.resolve(); }, removeAllSessionsOfJid: function (identifier) { - for (key in Object.keys(localStorage) - .filter(key => key.startsWith(this.jid + '.session' + identifier))) { - this.remove(key); + let filtered = Object.keys(localStorage).filter(key => key.startsWith(this.jid + '.session' + identifier)); + + for (id in filtered) { + this.remove(filtered[id]); } return Promise.resolve(); diff --git a/app/widgets/ContactActions/_contactactions_drawer.tpl b/app/widgets/ContactActions/_contactactions_drawer.tpl index a986bb0aa..42abccc97 100644 --- a/app/widgets/ContactActions/_contactactions_drawer.tpl +++ b/app/widgets/ContactActions/_contactactions_drawer.tpl @@ -103,7 +103,7 @@
- + {$value->fingerprint}
diff --git a/database/migrations/20210426164828_create_bundles_table.php b/database/migrations/20210526164828_create_bundles_table.php similarity index 88% rename from database/migrations/20210426164828_create_bundles_table.php rename to database/migrations/20210526164828_create_bundles_table.php index 75ca5246c..af038e434 100644 --- a/database/migrations/20210426164828_create_bundles_table.php +++ b/database/migrations/20210526164828_create_bundles_table.php @@ -13,8 +13,10 @@ class CreateBundlesTable extends Migration $table->integer('bundle_id'); $table->string('jid', 128); - $table->text('prekeypublic'); - $table->text('prekeysignature'); + $table->integer('signedprekeyid'); + $table->text('signedprekeypublic'); + $table->text('signedprekeysignature'); + $table->text('identitykey'); $table->text('prekeys'); $table->timestamps();