|
@@ -71570,7 +71570,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
// Copyright (c) 2013-2018, the Converse.js developers
|
|
// Copyright (c) 2013-2018, the Converse.js developers
|
|
// Licensed under the Mozilla Public License (MPLv2)
|
|
// Licensed under the Mozilla Public License (MPLv2)
|
|
|
|
|
|
-/* global libsignal, ArrayBuffer, parseInt */
|
|
|
|
|
|
+/* global libsignal, ArrayBuffer, parseInt, crypto */
|
|
(function (root, factory) {
|
|
(function (root, factory) {
|
|
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! converse-core */ "./src/converse-core.js"), __webpack_require__(/*! templates/toolbar_omemo.html */ "./src/templates/toolbar_omemo.html")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
|
|
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! converse-core */ "./src/converse-core.js"), __webpack_require__(/*! templates/toolbar_omemo.html */ "./src/templates/toolbar_omemo.html")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
|
|
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
|
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
|
@@ -71769,6 +71769,29 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
});
|
|
});
|
|
},
|
|
},
|
|
|
|
|
|
|
|
+ async encryptMessage(plaintext) {
|
|
|
|
+ // The client MUST use fresh, randomly generated key/IV pairs
|
|
|
|
+ // with AES-128 in Galois/Counter Mode (GCM).
|
|
|
|
+ const iv = crypto.getRandomValues(new window.Uint8Array(16));
|
|
|
|
+ const key = await crypto.subtle.generateKey(KEY_ALGO, true, ["encrypt", "decrypt"]);
|
|
|
|
+ const algo = {
|
|
|
|
+ 'name': 'AES-GCM',
|
|
|
|
+ 'iv': iv,
|
|
|
|
+ 'tagLength': TAG_LENGTH
|
|
|
|
+ };
|
|
|
|
+ const encrypted = await crypto.subtle.encrypt(algo, key, u.stringToArrayBuffer(plaintext));
|
|
|
|
+ const length = encrypted.byteLength - (128 + 7 >> 3),
|
|
|
|
+ ciphertext = encrypted.slice(0, length),
|
|
|
|
+ tag = encrypted.slice(length);
|
|
|
|
+ const exported_key = await crypto.subtle.exportKey("raw", key);
|
|
|
|
+ return Promise.resolve({
|
|
|
|
+ 'key': key,
|
|
|
|
+ 'key_and_tag': u.appendArrayBuffer(exported_key, tag),
|
|
|
|
+ 'payload': u.arrayBufferToBase64(ciphertext),
|
|
|
|
+ 'iv': u.arrayBufferToBase64(iv)
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
decryptMessage(obj) {
|
|
decryptMessage(obj) {
|
|
return crypto.subtle.importKey('raw', obj.key, KEY_ALGO, true, ['encrypt', 'decrypt']).then(key_obj => {
|
|
return crypto.subtle.importKey('raw', obj.key, KEY_ALGO, true, ['encrypt', 'decrypt']).then(key_obj => {
|
|
const algo = {
|
|
const algo = {
|
|
@@ -71776,15 +71799,16 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
'iv': u.base64ToArrayBuffer(obj.iv),
|
|
'iv': u.base64ToArrayBuffer(obj.iv),
|
|
'tagLength': TAG_LENGTH
|
|
'tagLength': TAG_LENGTH
|
|
};
|
|
};
|
|
- return window.crypto.subtle.decrypt(algo, key_obj, u.base64ToArrayBuffer(obj.payload));
|
|
|
|
- }).then(out => new TextDecoder().decode(out));
|
|
|
|
|
|
+ const cipher = u.appendArrayBuffer(u.base64ToArrayBuffer(obj.payload), obj.tag);
|
|
|
|
+ return crypto.subtle.decrypt(algo, key_obj, cipher);
|
|
|
|
+ }).then(out => u.arrayBufferToString(out));
|
|
},
|
|
},
|
|
|
|
|
|
reportDecryptionError(e) {
|
|
reportDecryptionError(e) {
|
|
const _converse = this.__super__._converse,
|
|
const _converse = this.__super__._converse,
|
|
__ = _converse.__;
|
|
__ = _converse.__;
|
|
this.messages.create({
|
|
this.messages.create({
|
|
- 'message': __("Sorry, could not decrypt a received OMEMO message due to an error.") + `${e.name} ${e.message}`,
|
|
|
|
|
|
+ 'message': __("Sorry, could not decrypt a received OMEMO message due to an error.") + ` ${e.name} ${e.message}`,
|
|
'type': 'error'
|
|
'type': 'error'
|
|
});
|
|
});
|
|
|
|
|
|
@@ -71879,34 +71903,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
return Promise.all(devices.map(device => this.getSession(device))).then(() => devices);
|
|
return Promise.all(devices.map(device => this.getSession(device))).then(() => devices);
|
|
},
|
|
},
|
|
|
|
|
|
- encryptMessage(plaintext) {
|
|
|
|
- // The client MUST use fresh, randomly generated key/IV pairs
|
|
|
|
- // with AES-128 in Galois/Counter Mode (GCM).
|
|
|
|
- const iv = window.crypto.getRandomValues(new window.Uint8Array(16));
|
|
|
|
- let key;
|
|
|
|
- return window.crypto.subtle.generateKey(KEY_ALGO, true, // extractable
|
|
|
|
- ["encrypt", "decrypt"] // key usages
|
|
|
|
- ).then(result => {
|
|
|
|
- key = result;
|
|
|
|
- const algo = {
|
|
|
|
- 'name': 'AES-GCM',
|
|
|
|
- 'iv': iv,
|
|
|
|
- 'tagLength': TAG_LENGTH
|
|
|
|
- };
|
|
|
|
- return window.crypto.subtle.encrypt(algo, key, new TextEncoder().encode(plaintext));
|
|
|
|
- }).then(ciphertext => {
|
|
|
|
- return window.crypto.subtle.exportKey("raw", key).then(key => {
|
|
|
|
- const tag = ciphertext.slice(ciphertext.byteLength - (TAG_LENGTH + 7 >> 3));
|
|
|
|
- return Promise.resolve({
|
|
|
|
- 'key': key,
|
|
|
|
- 'key_and_tag': u.appendArrayBuffer(key, tag),
|
|
|
|
- 'payload': u.arrayBufferToBase64(ciphertext),
|
|
|
|
- 'iv': u.arrayBufferToBase64(iv)
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
getSessionCipher(jid, id) {
|
|
getSessionCipher(jid, id) {
|
|
const _converse = this.__super__._converse,
|
|
const _converse = this.__super__._converse,
|
|
address = new libsignal.SignalProtocolAddress(jid, id);
|
|
address = new libsignal.SignalProtocolAddress(jid, id);
|