Merge branch 'omemo-debug'
This commit is contained in:
commit
fc6982ce08
85
dist/converse.js
vendored
85
dist/converse.js
vendored
@ -71769,23 +71769,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getKeyAndTag(string) {
|
|
||||||
return {
|
|
||||||
'key': string.slice(0, 22),
|
|
||||||
'tag': string.slice(22)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
decryptMessage(obj) {
|
decryptMessage(obj) {
|
||||||
const _converse = this.__super__._converse,
|
return crypto.subtle.importKey('raw', obj.key, KEY_ALGO, true, ['encrypt', 'decrypt']).then(key_obj => {
|
||||||
key_obj = {
|
|
||||||
"alg": "A128GCM",
|
|
||||||
"ext": true,
|
|
||||||
"k": obj.key,
|
|
||||||
"key_ops": ["encrypt", "decrypt"],
|
|
||||||
"kty": "oct"
|
|
||||||
};
|
|
||||||
return crypto.subtle.importKey('jwk', key_obj, KEY_ALGO, true, ['encrypt', 'decrypt']).then(key_obj => {
|
|
||||||
const algo = {
|
const algo = {
|
||||||
'name': "AES-GCM",
|
'name': "AES-GCM",
|
||||||
'iv': u.base64ToArrayBuffer(obj.iv),
|
'iv': u.base64ToArrayBuffer(obj.iv),
|
||||||
@ -71808,17 +71793,17 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
|
|
||||||
decrypt(attrs) {
|
decrypt(attrs) {
|
||||||
const _converse = this.__super__._converse,
|
const _converse = this.__super__._converse,
|
||||||
address = new libsignal.SignalProtocolAddress(attrs.from, parseInt(attrs.encrypted.device_id, 10)),
|
session_cipher = this.getSessionCipher(attrs.from, parseInt(attrs.encrypted.device_id, 10)); // https://xmpp.org/extensions/xep-0384.html#usecases-receiving
|
||||||
session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address); // https://xmpp.org/extensions/xep-0384.html#usecases-receiving
|
|
||||||
|
|
||||||
if (attrs.encrypted.prekey === 'true') {
|
if (attrs.encrypted.prekey === 'true') {
|
||||||
let plaintext;
|
let plaintext;
|
||||||
return session_cipher.decryptPreKeyWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary').then(key_and_tag => {
|
return session_cipher.decryptPreKeyWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary').then(key_and_tag => {
|
||||||
if (attrs.encrypted.payload) {
|
if (attrs.encrypted.payload) {
|
||||||
const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
|
const key = key_and_tag.slice(0, 16),
|
||||||
|
tag = key_and_tag.slice(16);
|
||||||
return this.decryptMessage(_.extend(attrs.encrypted, {
|
return this.decryptMessage(_.extend(attrs.encrypted, {
|
||||||
'key': aes_data.key,
|
'key': key,
|
||||||
'tag': aes_data.tag
|
'tag': tag
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71842,10 +71827,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return session_cipher.decryptWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary').then(key_and_tag => {
|
return session_cipher.decryptWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary').then(key_and_tag => {
|
||||||
const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
|
const key = key_and_tag.slice(0, 16),
|
||||||
|
tag = key_and_tag.slice(16);
|
||||||
return this.decryptMessage(_.extend(attrs.encrypted, {
|
return this.decryptMessage(_.extend(attrs.encrypted, {
|
||||||
'key': aes_data.key,
|
'key': key,
|
||||||
'tag': aes_data.tag
|
'tag': tag
|
||||||
}));
|
}));
|
||||||
}).then(plaintext => _.extend(attrs, {
|
}).then(plaintext => _.extend(attrs, {
|
||||||
'plaintext': plaintext
|
'plaintext': plaintext
|
||||||
@ -71909,12 +71895,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
};
|
};
|
||||||
return window.crypto.subtle.encrypt(algo, key, new TextEncoder().encode(plaintext));
|
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 => {
|
return window.crypto.subtle.exportKey("raw", key).then(key => {
|
||||||
const tag = u.arrayBufferToBase64(ciphertext.slice(ciphertext.byteLength - (TAG_LENGTH + 7 >> 3)));
|
const tag = ciphertext.slice(ciphertext.byteLength - (TAG_LENGTH + 7 >> 3));
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
'key': key_obj.k,
|
'key': key,
|
||||||
'tag': tag,
|
'key_and_tag': u.appendArrayBuffer(key, tag),
|
||||||
'key_and_tag': key_obj.k + tag,
|
|
||||||
'payload': u.arrayBufferToBase64(ciphertext),
|
'payload': u.arrayBufferToBase64(ciphertext),
|
||||||
'iv': u.arrayBufferToBase64(iv)
|
'iv': u.arrayBufferToBase64(iv)
|
||||||
});
|
});
|
||||||
@ -71922,11 +71907,18 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSessionCipher(jid, id) {
|
||||||
|
if (!this.session_cipher) {
|
||||||
|
const _converse = this.__super__._converse,
|
||||||
|
address = new libsignal.SignalProtocolAddress(jid, id);
|
||||||
|
this.session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.session_cipher;
|
||||||
|
},
|
||||||
|
|
||||||
encryptKey(plaintext, device) {
|
encryptKey(plaintext, device) {
|
||||||
const _converse = this.__super__._converse,
|
return this.getSessionCipher(device.get('jid'), device.get('id')).encrypt(plaintext).then(payload => ({
|
||||||
address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id')),
|
|
||||||
session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address);
|
|
||||||
return session_cipher.encrypt(plaintext).then(payload => ({
|
|
||||||
'payload': payload,
|
'payload': payload,
|
||||||
'device': device
|
'device': device
|
||||||
}));
|
}));
|
||||||
@ -81290,26 +81282,37 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|||||||
return fp;
|
return fp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u.appendArrayBuffer = function (buffer1, buffer2) {
|
||||||
|
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
|
||||||
|
tmp.set(new Uint8Array(buffer1), 0);
|
||||||
|
tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
|
||||||
|
return tmp.buffer;
|
||||||
|
};
|
||||||
|
|
||||||
u.arrayBufferToHex = function (ab) {
|
u.arrayBufferToHex = function (ab) {
|
||||||
// https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex#40031979
|
// https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex#40031979
|
||||||
return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
|
return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
|
||||||
};
|
};
|
||||||
|
|
||||||
u.arrayBufferToString = function (ab) {
|
u.arrayBufferToString = function (ab) {
|
||||||
const enc = new TextDecoder("utf-8");
|
return new Uint8Array(ab).reduce((data, byte) => data + String.fromCharCode(byte), '');
|
||||||
return enc.decode(ab);
|
};
|
||||||
|
|
||||||
|
u.stringToArrayBuffer = function (string) {
|
||||||
|
const len = string.length,
|
||||||
|
bytes = new Uint8Array(len);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
bytes[i] = string.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
u.arrayBufferToBase64 = function (ab) {
|
u.arrayBufferToBase64 = function (ab) {
|
||||||
return btoa(new Uint8Array(ab).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
return btoa(new Uint8Array(ab).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||||
};
|
};
|
||||||
|
|
||||||
u.stringToArrayBuffer = function (string) {
|
|
||||||
const enc = new TextEncoder(); // always utf-8
|
|
||||||
|
|
||||||
return enc.encode(string);
|
|
||||||
};
|
|
||||||
|
|
||||||
u.base64ToArrayBuffer = function (b64) {
|
u.base64ToArrayBuffer = function (b64) {
|
||||||
const binary_string = window.atob(b64),
|
const binary_string = window.atob(b64),
|
||||||
len = binary_string.length,
|
len = binary_string.length,
|
||||||
|
@ -88,9 +88,9 @@
|
|||||||
.then((v) => {
|
.then((v) => {
|
||||||
view = v;
|
view = v;
|
||||||
return view.model.encryptMessage(message);
|
return view.model.encryptMessage(message);
|
||||||
}).then((payload) => {
|
}).then(payload => {
|
||||||
return view.model.decryptMessage(payload);
|
return view.model.decryptMessage(payload);
|
||||||
}).then((result) => {
|
}).then(result => {
|
||||||
expect(result).toBe(message);
|
expect(result).toBe(message);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@ -199,10 +199,13 @@
|
|||||||
|
|
||||||
// Test reception of an encrypted message
|
// Test reception of an encrypted message
|
||||||
return view.model.encryptMessage('This is an encrypted message from the contact')
|
return view.model.encryptMessage('This is an encrypted message from the contact')
|
||||||
}).then((obj) => {
|
}).then(obj => {
|
||||||
// XXX: Normally the key will be encrypted via libsignal.
|
// XXX: Normally the key will be encrypted via libsignal.
|
||||||
// However, we're mocking libsignal in the tests, so we include
|
// However, we're mocking libsignal in the tests, so we include
|
||||||
// it as plaintext in the message.
|
// it as plaintext in the message.
|
||||||
|
|
||||||
|
// u.stringToArrayBuffer(atob(u.arrayBufferToBase64(obj.key_and_tag)));
|
||||||
|
// u.stringToArrayBuffer(u.arrayBufferToString(obj.key_and_tag));
|
||||||
const stanza = $msg({
|
const stanza = $msg({
|
||||||
'from': contact_jid,
|
'from': contact_jid,
|
||||||
'to': _converse.connection.jid,
|
'to': _converse.connection.jid,
|
||||||
@ -211,7 +214,7 @@
|
|||||||
}).c('body').t('This is a fallback message').up()
|
}).c('body').t('This is a fallback message').up()
|
||||||
.c('encrypted', {'xmlns': Strophe.NS.OMEMO})
|
.c('encrypted', {'xmlns': Strophe.NS.OMEMO})
|
||||||
.c('header', {'sid': '555'})
|
.c('header', {'sid': '555'})
|
||||||
.c('key', {'rid': _converse.omemo_store.get('device_id')}).t(btoa(obj.key_and_tag)).up()
|
.c('key', {'rid': _converse.omemo_store.get('device_id')}).t(u.arrayBufferToBase64(obj.key_and_tag)).up()
|
||||||
.c('iv').t(obj.iv)
|
.c('iv').t(obj.iv)
|
||||||
.up().up()
|
.up().up()
|
||||||
.c('payload').t(obj.payload);
|
.c('payload').t(obj.payload);
|
||||||
@ -255,7 +258,7 @@
|
|||||||
.c('key', {
|
.c('key', {
|
||||||
'prekey': 'true',
|
'prekey': 'true',
|
||||||
'rid': _converse.omemo_store.get('device_id')
|
'rid': _converse.omemo_store.get('device_id')
|
||||||
}).t(btoa(obj.key_and_tag)).up()
|
}).t(u.arrayBufferToBase64(obj.key_and_tag)).up()
|
||||||
.c('iv').t(obj.iv)
|
.c('iv').t(obj.iv)
|
||||||
.up().up()
|
.up().up()
|
||||||
.c('payload').t(obj.payload);
|
.c('payload').t(obj.payload);
|
||||||
|
@ -201,24 +201,9 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getKeyAndTag (string) {
|
|
||||||
return {
|
|
||||||
'key': string.slice(0, 22),
|
|
||||||
'tag': string.slice(22)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
decryptMessage (obj) {
|
decryptMessage (obj) {
|
||||||
const { _converse } = this.__super__,
|
return crypto.subtle.importKey('raw', obj.key, KEY_ALGO, true, ['encrypt','decrypt'])
|
||||||
key_obj = {
|
.then(key_obj => {
|
||||||
"alg": "A128GCM",
|
|
||||||
"ext": true,
|
|
||||||
"k": obj.key,
|
|
||||||
"key_ops": ["encrypt","decrypt"],
|
|
||||||
"kty": "oct"
|
|
||||||
};
|
|
||||||
return crypto.subtle.importKey('jwk', key_obj, KEY_ALGO, true, ['encrypt','decrypt'])
|
|
||||||
.then((key_obj) => {
|
|
||||||
const algo = {
|
const algo = {
|
||||||
'name': "AES-GCM",
|
'name': "AES-GCM",
|
||||||
'iv': u.base64ToArrayBuffer(obj.iv),
|
'iv': u.base64ToArrayBuffer(obj.iv),
|
||||||
@ -240,8 +225,7 @@
|
|||||||
|
|
||||||
decrypt (attrs) {
|
decrypt (attrs) {
|
||||||
const { _converse } = this.__super__,
|
const { _converse } = this.__super__,
|
||||||
address = new libsignal.SignalProtocolAddress(attrs.from, parseInt(attrs.encrypted.device_id, 10)),
|
session_cipher = this.getSessionCipher(attrs.from, parseInt(attrs.encrypted.device_id, 10));
|
||||||
session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address);
|
|
||||||
|
|
||||||
// https://xmpp.org/extensions/xep-0384.html#usecases-receiving
|
// https://xmpp.org/extensions/xep-0384.html#usecases-receiving
|
||||||
if (attrs.encrypted.prekey === 'true') {
|
if (attrs.encrypted.prekey === 'true') {
|
||||||
@ -249,8 +233,9 @@
|
|||||||
return session_cipher.decryptPreKeyWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary')
|
return session_cipher.decryptPreKeyWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary')
|
||||||
.then(key_and_tag => {
|
.then(key_and_tag => {
|
||||||
if (attrs.encrypted.payload) {
|
if (attrs.encrypted.payload) {
|
||||||
const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
|
const key = key_and_tag.slice(0, 16),
|
||||||
return this.decryptMessage(_.extend(attrs.encrypted, {'key': aes_data.key, 'tag': aes_data.tag}));
|
tag = key_and_tag.slice(16);
|
||||||
|
return this.decryptMessage(_.extend(attrs.encrypted, {'key': key, 'tag': tag}));
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}).then(pt => {
|
}).then(pt => {
|
||||||
@ -270,8 +255,9 @@
|
|||||||
} else {
|
} else {
|
||||||
return session_cipher.decryptWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary')
|
return session_cipher.decryptWhisperMessage(u.base64ToArrayBuffer(attrs.encrypted.key), 'binary')
|
||||||
.then(key_and_tag => {
|
.then(key_and_tag => {
|
||||||
const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
|
const key = key_and_tag.slice(0, 16),
|
||||||
return this.decryptMessage(_.extend(attrs.encrypted, {'key': aes_data.key, 'tag': aes_data.tag}));
|
tag = key_and_tag.slice(16);
|
||||||
|
return this.decryptMessage(_.extend(attrs.encrypted, {'key': key, 'tag': tag}));
|
||||||
}).then(plaintext => _.extend(attrs, {'plaintext': plaintext}))
|
}).then(plaintext => _.extend(attrs, {'plaintext': plaintext}))
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
this.reportDecryptionError(e);
|
this.reportDecryptionError(e);
|
||||||
@ -332,13 +318,12 @@
|
|||||||
}
|
}
|
||||||
return window.crypto.subtle.encrypt(algo, key, new TextEncoder().encode(plaintext));
|
return window.crypto.subtle.encrypt(algo, key, new TextEncoder().encode(plaintext));
|
||||||
}).then(ciphertext => {
|
}).then(ciphertext => {
|
||||||
return window.crypto.subtle.exportKey("jwk", key)
|
return window.crypto.subtle.exportKey("raw", key)
|
||||||
.then(key_obj => {
|
.then(key => {
|
||||||
const tag = u.arrayBufferToBase64(ciphertext.slice(ciphertext.byteLength - ((TAG_LENGTH + 7) >> 3)));
|
const tag = ciphertext.slice(ciphertext.byteLength - ((TAG_LENGTH + 7) >> 3));
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
'key': key_obj.k,
|
'key': key,
|
||||||
'tag': tag,
|
'key_and_tag': u.appendArrayBuffer(key, tag),
|
||||||
'key_and_tag': key_obj.k + tag,
|
|
||||||
'payload': u.arrayBufferToBase64(ciphertext),
|
'payload': u.arrayBufferToBase64(ciphertext),
|
||||||
'iv': u.arrayBufferToBase64(iv)
|
'iv': u.arrayBufferToBase64(iv)
|
||||||
});
|
});
|
||||||
@ -346,12 +331,19 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
encryptKey (plaintext, device) {
|
getSessionCipher (jid, id) {
|
||||||
const { _converse } = this.__super__,
|
if (!this.session_cipher) {
|
||||||
address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id')),
|
const { _converse } = this.__super__,
|
||||||
session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address);
|
address = new libsignal.SignalProtocolAddress(jid, id);
|
||||||
|
this.session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address);
|
||||||
|
}
|
||||||
|
return this.session_cipher;
|
||||||
|
},
|
||||||
|
|
||||||
return session_cipher.encrypt(plaintext).then(payload => ({'payload': payload, 'device': device}));
|
encryptKey (plaintext, device) {
|
||||||
|
return this.getSessionCipher(device.get('jid'), device.get('id'))
|
||||||
|
.encrypt(plaintext)
|
||||||
|
.then(payload => ({'payload': payload, 'device': device}));
|
||||||
},
|
},
|
||||||
|
|
||||||
addKeysToMessageStanza (stanza, dicts, iv) {
|
addKeysToMessageStanza (stanza, dicts, iv) {
|
||||||
|
@ -916,25 +916,36 @@
|
|||||||
return fp;
|
return fp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u.appendArrayBuffer = function (buffer1, buffer2) {
|
||||||
|
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
|
||||||
|
tmp.set(new Uint8Array(buffer1), 0);
|
||||||
|
tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
|
||||||
|
return tmp.buffer;
|
||||||
|
};
|
||||||
|
|
||||||
u.arrayBufferToHex = function (ab) {
|
u.arrayBufferToHex = function (ab) {
|
||||||
// https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex#40031979
|
// https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex#40031979
|
||||||
return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
|
return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
|
||||||
};
|
};
|
||||||
|
|
||||||
u.arrayBufferToString = function (ab) {
|
u.arrayBufferToString = function (ab) {
|
||||||
const enc = new TextDecoder("utf-8");
|
return (new Uint8Array(ab)).reduce((data, byte) => data + String.fromCharCode(byte), '');
|
||||||
return enc.decode(ab);
|
};
|
||||||
|
|
||||||
|
u.stringToArrayBuffer = function (string) {
|
||||||
|
const len = string.length,
|
||||||
|
bytes = new Uint8Array(len);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
bytes[i] = string.charCodeAt(i)
|
||||||
|
}
|
||||||
|
return bytes.buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
u.arrayBufferToBase64 = function (ab) {
|
u.arrayBufferToBase64 = function (ab) {
|
||||||
return btoa((new Uint8Array(ab)).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
return btoa((new Uint8Array(ab)).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||||
};
|
};
|
||||||
|
|
||||||
u.stringToArrayBuffer = function (string) {
|
|
||||||
const enc = new TextEncoder(); // always utf-8
|
|
||||||
return enc.encode(string);
|
|
||||||
};
|
|
||||||
|
|
||||||
u.base64ToArrayBuffer = function (b64) {
|
u.base64ToArrayBuffer = function (b64) {
|
||||||
const binary_string = window.atob(b64),
|
const binary_string = window.atob(b64),
|
||||||
len = binary_string.length,
|
len = binary_string.length,
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
'registrationId': '1337'
|
'registrationId': '1337'
|
||||||
});
|
});
|
||||||
this.decryptPreKeyWhisperMessage = (key_and_tag) => {
|
this.decryptPreKeyWhisperMessage = (key_and_tag) => {
|
||||||
// TODO: remove the prekey
|
|
||||||
return Promise.resolve(u.stringToArrayBuffer(key_and_tag));
|
return Promise.resolve(u.stringToArrayBuffer(key_and_tag));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user