mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
Merge pull request #7 from sachaaaaa/fallback_decrypt
Decrypt "friend request" messages using fallback encryption. Move logic into libloki.js
This commit is contained in:
commit
b52dac98b7
10 changed files with 78 additions and 31 deletions
|
@ -12,6 +12,7 @@ test/views/*.js
|
|||
# Generated files
|
||||
js/components.js
|
||||
js/libtextsecure.js
|
||||
js/libloki.js
|
||||
js/util_worker.js
|
||||
js/libsignal-protocol-worker.js
|
||||
libtextsecure/components.js
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,6 +19,7 @@ sql/
|
|||
js/components.js
|
||||
js/util_worker.js
|
||||
js/libtextsecure.js
|
||||
js/libloki.js
|
||||
libtextsecure/components.js
|
||||
libtextsecure/test/test.js
|
||||
stylesheets/*.css
|
||||
|
|
|
@ -8,6 +8,7 @@ dist/**
|
|||
js/components.js
|
||||
js/util_worker.js
|
||||
js/libtextsecure.js
|
||||
js/libloki.js
|
||||
libtextsecure/components.js
|
||||
libtextsecure/test/test.js
|
||||
stylesheets/*.css
|
||||
|
|
10
Gruntfile.js
10
Gruntfile.js
|
@ -86,6 +86,12 @@ module.exports = grunt => {
|
|||
],
|
||||
dest: 'js/libtextsecure.js',
|
||||
},
|
||||
libloki: {
|
||||
src: [
|
||||
'libloki/libloki-protocol.js',
|
||||
],
|
||||
dest: 'js/libloki.js',
|
||||
},
|
||||
libtextsecuretest: {
|
||||
src: [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
|
@ -128,6 +134,10 @@ module.exports = grunt => {
|
|||
files: ['./libtextsecure/*.js', './libtextsecure/storage/*.js'],
|
||||
tasks: ['concat:libtextsecure'],
|
||||
},
|
||||
libloki: {
|
||||
files: ['./libloki/*.js'],
|
||||
tasks: ['concat:libloki'],
|
||||
},
|
||||
protobuf: {
|
||||
files: ['./protos/SignalService.proto'],
|
||||
tasks: ['exec:build-protobuf'],
|
||||
|
|
|
@ -584,6 +584,7 @@
|
|||
<script type='text/javascript' src='js/storage.js'></script>
|
||||
<script type='text/javascript' src='js/signal_protocol_store.js'></script>
|
||||
<script type='text/javascript' src='js/libtextsecure.js'></script>
|
||||
<script type='text/javascript' src='js/libloki.js'></script>
|
||||
|
||||
<script type='text/javascript' src='js/focus_listener.js'></script>
|
||||
<script type='text/javascript' src='js/notifications.js'></script>
|
||||
|
|
47
libloki/libloki-protocol.js
Normal file
47
libloki/libloki-protocol.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* global window, libsignal, textsecure */
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
(function() {
|
||||
window.libloki = window.libloki || {};
|
||||
|
||||
const IV_LENGTH = 16;
|
||||
|
||||
FallBackSessionCipher = function (address) {
|
||||
this.pubKey = StringView.hexToArrayBuffer(address.getName());
|
||||
|
||||
this.encrypt = async (plaintext) => {
|
||||
const myKeyPair = await textsecure.storage.protocol.getIdentityKeyPair();
|
||||
const myPrivateKey = myKeyPair.privKey;
|
||||
const symmetricKey = libsignal.Curve.calculateAgreement(this.pubKey, myPrivateKey);
|
||||
const iv = libsignal.crypto.getRandomBytes(IV_LENGTH);
|
||||
const ciphertext = await libsignal.crypto.encrypt(symmetricKey, plaintext, iv);
|
||||
const ivAndCiphertext = new Uint8Array(
|
||||
iv.byteLength + ciphertext.byteLength
|
||||
);
|
||||
ivAndCiphertext.set(new Uint8Array(iv));
|
||||
ivAndCiphertext.set(
|
||||
new Uint8Array(ciphertext),
|
||||
iv.byteLength
|
||||
);
|
||||
|
||||
return {
|
||||
type : 6, //friend request
|
||||
body : new dcodeIO.ByteBuffer.wrap(ivAndCiphertext).toString('binary'),
|
||||
registrationId : null
|
||||
};
|
||||
},
|
||||
|
||||
this.decrypt = async (ivAndCiphertext) => {
|
||||
const iv = ivAndCiphertext.slice(0, IV_LENGTH);
|
||||
const cipherText = ivAndCiphertext.slice(IV_LENGTH);
|
||||
const myKeyPair = await textsecure.storage.protocol.getIdentityKeyPair();
|
||||
const myPrivateKey = myKeyPair.privKey;
|
||||
const symmetricKey = libsignal.Curve.calculateAgreement(this.pubKey, myPrivateKey);
|
||||
const plaintext = await libsignal.crypto.decrypt(symmetricKey, cipherText, iv);
|
||||
return plaintext;
|
||||
}
|
||||
}
|
||||
|
||||
window.libloki.FallBackSessionCipher = FallBackSessionCipher;
|
||||
|
||||
})();
|
|
@ -646,10 +646,17 @@ MessageReceiver.prototype.extend({
|
|||
case textsecure.protobuf.Envelope.Type.CIPHERTEXT:
|
||||
window.log.info('message from', this.getEnvelopeId(envelope));
|
||||
promise = Promise.resolve(ciphertext.toArrayBuffer())//;sessionCipher
|
||||
// TODO: restore decryption & unpadding
|
||||
// TODO: restore decryption & unpadding (?)
|
||||
//.decryptWhisperMessage(ciphertext)
|
||||
//.then(this.unpad);
|
||||
break;
|
||||
case textsecure.protobuf.Envelope.Type.FRIEND_REQUEST:
|
||||
window.log.info('friend-request message from ', envelope.source)
|
||||
const fallBackSessionCipher = new libloki.FallBackSessionCipher(
|
||||
address
|
||||
);
|
||||
promise = fallBackSessionCipher.decrypt(ciphertext.toArrayBuffer());
|
||||
break;
|
||||
case textsecure.protobuf.Envelope.Type.PREKEY_BUNDLE:
|
||||
window.log.info('prekey message from', this.getEnvelopeId(envelope));
|
||||
promise = this.decryptPreKeyWhisperMessage(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* global textsecure, libsignal, window, btoa */
|
||||
/* global textsecure, libsignal, window, btoa, libloki */
|
||||
|
||||
/* eslint-disable more/no-then */
|
||||
|
||||
|
@ -209,7 +209,7 @@ OutgoingMessage.prototype = {
|
|||
content: outgoingObject.content,
|
||||
});
|
||||
const requestMessage = new textsecure.protobuf.WebSocketRequestMessage({
|
||||
id: new Uint8Array(libsignal.crypto.getRandomBytes(1))[0],
|
||||
id: new Uint8Array(libsignal.crypto.getRandomBytes(1))[0], // random ID for now
|
||||
verb: 'PUT',
|
||||
path: '/api/v1/message',
|
||||
body: messageEnvelope.encode().toArrayBuffer()
|
||||
|
@ -219,6 +219,7 @@ OutgoingMessage.prototype = {
|
|||
request: requestMessage
|
||||
});
|
||||
const bytes = new Uint8Array(websocketMessage.encode().toArrayBuffer())
|
||||
bytes.toString(); // print bytes for debugging purposes: can be injected in mock socket server
|
||||
return bytes;
|
||||
},
|
||||
doSendMessage(number, deviceIds, recurse) {
|
||||
|
@ -239,32 +240,7 @@ OutgoingMessage.prototype = {
|
|||
|
||||
let sessionCipher;
|
||||
if (this.fallBackEncryption) {
|
||||
// TODO: move to own file?
|
||||
FallBackSessionCipher = function (address) {
|
||||
this.recipientPubKey = StringView.hexToArrayBuffer(address.getName());
|
||||
this.encrypt = async (plaintext) => {
|
||||
const myKeyPair = await textsecure.storage.protocol.getIdentityKeyPair();
|
||||
const myPrivateKey = myKeyPair.privKey;
|
||||
const symmetricKey = libsignal.Curve.calculateAgreement(this.recipientPubKey, myPrivateKey);
|
||||
const iv = libsignal.crypto.getRandomBytes(16);
|
||||
const ciphertext = await libsignal.crypto.encrypt(symmetricKey, plaintext, iv);
|
||||
const ivAndCiphertext = new Uint8Array(
|
||||
iv.byteLength + ciphertext.byteLength
|
||||
);
|
||||
ivAndCiphertext.set(new Uint8Array(iv));
|
||||
ivAndCiphertext.set(
|
||||
new Uint8Array(ciphertext),
|
||||
iv.byteLength
|
||||
);
|
||||
|
||||
return {
|
||||
type : 6, //friend request
|
||||
body : new dcodeIO.ByteBuffer.wrap(ivAndCiphertext).toString('binary'),
|
||||
registrationId : null
|
||||
};
|
||||
}
|
||||
}
|
||||
sessionCipher = new FallBackSessionCipher(
|
||||
sessionCipher = new libloki.FallBackSessionCipher(
|
||||
address
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -13,9 +13,11 @@ async def hello(websocket, path):
|
|||
# protomessage = new textsecure.protobuf.WebSocketMessage({type: textsecure.protobuf.WebSocketMessage.Type.REQUEST, request: {id:99, verb:'PUT', path:'/api/v1/queue/empty', body:null }})
|
||||
# new Uint8Array(protomessage.encode().toArrayBuffer())
|
||||
message = bytes(
|
||||
#[8, 1, 18, 70, 10, 3, 80, 85, 84, 18, 15, 47, 97, 112, 105, 47, 118, 49, 47, 109, 101, 115, 115, 97, 103, 101, 26, 44, 8, 1, 18, 15, 109, 121, 115, 111, 117, 114, 99, 101, 97, 100, 100, 114, 101, 115, 115, 56, 1, 40, 184, 151, 213, 221, 5, 66, 15, 10, 13, 10, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 32, 99]
|
||||
[
|
||||
8,1,18,117,10,3,80,85,84,18,15,47,97,112,105,47,118,49,47,109,101,115,115,97,103,101,26,91,8,1,18,66,48,53,55,51,57,102,51,54,55,50,100,55,57,52,51,56,101,57,53,53,97,55,99,99,55,55,56,52,100,98,97,53,101,97,52,98,102,56,50,55,52,54,54,53,55,55,51,99,97,102,51,101,97,98,55,48,97,50,98,57,100,98,102,101,50,99,56,1,40,0,66,15,10,13,10,11,104,101,108,108,111,32,119,111,114,108,100,32,99
|
||||
# "hello world" - unencrypted
|
||||
#8,1,18,117,10,3,80,85,84,18,15,47,97,112,105,47,118,49,47,109,101,115,115,97,103,101,26,91,8,1,18,66,48,53,55,51,57,102,51,54,55,50,100,55,57,52,51,56,101,57,53,53,97,55,99,99,55,55,56,52,100,98,97,53,101,97,52,98,102,56,50,55,52,54,54,53,55,55,51,99,97,102,51,101,97,98,55,48,97,50,98,57,100,98,102,101,50,99,56,1,40,0,66,15,10,13,10,11,104,101,108,108,111,32,119,111,114,108,100,32,99
|
||||
# "test" - fall back encrypted
|
||||
8,1,18,140,1,10,3,80,85,84,18,15,47,97,112,105,47,118,49,47,109,101,115,115,97,103,101,26,113,8,6,18,66,48,53,51,102,48,101,57,56,54,53,97,100,101,54,97,100,57,48,48,97,54,99,101,51,98,98,54,101,102,97,99,102,102,102,97,98,99,50,56,49,101,53,97,50,102,100,102,54,101,97,49,51,57,98,51,48,51,50,49,55,57,57,97,97,50,99,56,1,40,181,202,171,141,229,44,66,32,147,127,63,203,38,142,133,120,28,115,7,150,230,26,166,28,182,199,199,182,11,101,80,48,252,232,108,164,8,236,98,50,32,150,1
|
||||
])
|
||||
# created by executing in js:
|
||||
# dataMessage = new textsecure.protobuf.DataMessage({body: "hello world", attachments:[], contact:[]})
|
||||
|
|
|
@ -52,6 +52,7 @@ const excludedFiles = [
|
|||
// Generated files
|
||||
'^js/components.js',
|
||||
'^js/libtextsecure.js',
|
||||
'^js/libloki.js',
|
||||
'^js/util_worker.js',
|
||||
'^libtextsecure/components.js',
|
||||
'^libtextsecure/test/test.js',
|
||||
|
|
Loading…
Reference in a new issue