|
@@ -74300,7 +74300,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
'tag': aes_data.tag
|
|
'tag': aes_data.tag
|
|
}));
|
|
}));
|
|
}).then(plaintext => {
|
|
}).then(plaintext => {
|
|
- // TODO remove newly used key before republishing
|
|
|
|
|
|
+ // TODO the prekey should now have been removed.
|
|
|
|
+ // Double-check that this is the case and then
|
|
|
|
+ // generate a new key to replace it, before
|
|
|
|
+ // republishing.
|
|
_converse.omemo_store.publishBundle();
|
|
_converse.omemo_store.publishBundle();
|
|
|
|
|
|
return _.extend(attrs, {
|
|
return _.extend(attrs, {
|
|
@@ -74647,54 +74650,81 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
|
|
- loadPreKey(keyId) {
|
|
|
|
- let res = this.get('25519KeypreKey' + keyId);
|
|
|
|
|
|
+ getPreKeys() {
|
|
|
|
+ return this.get('prekeys') || {};
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ loadPreKey(key_id) {
|
|
|
|
+ const res = this.getPreKeys()[key_id];
|
|
|
|
|
|
if (res) {
|
|
if (res) {
|
|
- res = {
|
|
|
|
|
|
+ return Promise.resolve({
|
|
'privKey': u.base64ToArrayBuffer(res.privKey),
|
|
'privKey': u.base64ToArrayBuffer(res.privKey),
|
|
'pubKey': u.base64ToArrayBuffer(res.pubKey)
|
|
'pubKey': u.base64ToArrayBuffer(res.pubKey)
|
|
- };
|
|
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
- return Promise.resolve(res);
|
|
|
|
|
|
+ return Promise.resolve();
|
|
},
|
|
},
|
|
|
|
|
|
- storePreKey(keyId, keyPair) {
|
|
|
|
- this.save('25519KeypreKey' + keyId, {
|
|
|
|
- 'privKey': u.arrayBufferToBase64(keyPair.privKey),
|
|
|
|
- 'pubKey': u.arrayBufferToBase64(keyPair.pubKey)
|
|
|
|
- });
|
|
|
|
|
|
+ storePreKey(key_id, key_pair) {
|
|
|
|
+ const prekey = {};
|
|
|
|
+ prekey[key_id] = {
|
|
|
|
+ 'pubKey': u.arrayBufferToBase64(key_pair.pubKey),
|
|
|
|
+ 'privKey': u.arrayBufferToBase64(key_pair.privKey)
|
|
|
|
+ };
|
|
|
|
+ this.save('prekeys', _.extend(this.getPreKeys(), prekey));
|
|
return Promise.resolve();
|
|
return Promise.resolve();
|
|
},
|
|
},
|
|
|
|
|
|
- removePreKey(keyId) {
|
|
|
|
- return Promise.resolve(this.unset('25519KeypreKey' + keyId));
|
|
|
|
|
|
+ removePreKey(key_id) {
|
|
|
|
+ this.save('prekeys', _.omit(this.getPreKeys(), key_id));
|
|
|
|
+ return Promise.resolve();
|
|
},
|
|
},
|
|
|
|
|
|
loadSignedPreKey(keyId) {
|
|
loadSignedPreKey(keyId) {
|
|
- let res = this.get('25519KeysignedKey' + keyId);
|
|
|
|
|
|
+ const res = this.get('signed_prekey');
|
|
|
|
|
|
if (res) {
|
|
if (res) {
|
|
- res = {
|
|
|
|
|
|
+ return Promise.resolve({
|
|
'privKey': u.base64ToArrayBuffer(res.privKey),
|
|
'privKey': u.base64ToArrayBuffer(res.privKey),
|
|
'pubKey': u.base64ToArrayBuffer(res.pubKey)
|
|
'pubKey': u.base64ToArrayBuffer(res.pubKey)
|
|
- };
|
|
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
- return Promise.resolve(res);
|
|
|
|
|
|
+ return Promise.resolve();
|
|
},
|
|
},
|
|
|
|
|
|
- storeSignedPreKey(keyId, keyPair) {
|
|
|
|
- this.save('25519KeysignedKey' + keyId, {
|
|
|
|
- 'privKey': u.arrayBufferToBase64(keyPair.privKey),
|
|
|
|
- 'pubKey': u.arrayBufferToBase64(keyPair.pubKey)
|
|
|
|
|
|
+ storeSignedPreKey(spk) {
|
|
|
|
+ if (typeof spk !== "object") {
|
|
|
|
+ // XXX: We've changed the signature of this method from the
|
|
|
|
+ // example given in InMemorySignalProtocolStore.
|
|
|
|
+ // Should be fine because the libsignal code doesn't
|
|
|
|
+ // actually call this method.
|
|
|
|
+ throw new Error("storeSignedPreKey: expected an object");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.save('signed_prekey', {
|
|
|
|
+ 'id': spk.keyId,
|
|
|
|
+ 'privKey': u.arrayBufferToBase64(spk.keyPair.privKey),
|
|
|
|
+ 'pubKey': u.arrayBufferToBase64(spk.keyPair.pubKey),
|
|
|
|
+ // XXX: The InMemorySignalProtocolStore does not pass
|
|
|
|
+ // in or store the signature, but we need it when we
|
|
|
|
+ // publish out bundle and this method isn't called from
|
|
|
|
+ // within libsignal code, so we modify it to also store
|
|
|
|
+ // the signature.
|
|
|
|
+ 'signature': u.arrayBufferToBase64(spk.signature)
|
|
});
|
|
});
|
|
return Promise.resolve();
|
|
return Promise.resolve();
|
|
},
|
|
},
|
|
|
|
|
|
- removeSignedPreKey(keyId) {
|
|
|
|
- return Promise.resolve(this.unset('25519KeysignedKey' + keyId));
|
|
|
|
|
|
+ removeSignedPreKey(key_id) {
|
|
|
|
+ if (this.get('signed_prekey')['id'] === key_id) {
|
|
|
|
+ this.unset('signed_prekey');
|
|
|
|
+ this.save();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return Promise.resolve();
|
|
},
|
|
},
|
|
|
|
|
|
loadSession(identifier) {
|
|
loadSession(identifier) {
|
|
@@ -74738,12 +74768,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
}).c('item').c('bundle', {
|
|
}).c('item').c('bundle', {
|
|
'xmlns': Strophe.NS.OMEMO
|
|
'xmlns': Strophe.NS.OMEMO
|
|
}).c('signedPreKeyPublic', {
|
|
}).c('signedPreKeyPublic', {
|
|
- 'signedPreKeyId': signed_prekey.keyId
|
|
|
|
- }).t(signed_prekey.keyPair.pubKey).up().c('signedPreKeySignature').t(signed_prekey.signature).up().c('identityKey').t(this.get('identity_keypair').pubKey).up().c('prekeys');
|
|
|
|
|
|
+ 'signedPreKeyId': signed_prekey.id
|
|
|
|
+ }).t(signed_prekey.pubKey).up().c('signedPreKeySignature').t(signed_prekey.signature).up().c('identityKey').t(this.get('identity_keypair').pubKey).up().c('prekeys');
|
|
|
|
|
|
- _.forEach(this.get('prekeys').slice(0, _converse.NUM_PREKEYS), prekey => stanza.c('preKeyPublic', {
|
|
|
|
- 'preKeyId': prekey.keyId
|
|
|
|
- }).t(prekey.keyPair.pubKey).up());
|
|
|
|
|
|
+ _.forEach(this.get('prekeys'), (prekey, id) => stanza.c('preKeyPublic', {
|
|
|
|
+ 'preKeyId': id
|
|
|
|
+ }).t(prekey.pubKey).up());
|
|
|
|
|
|
return _converse.api.sendIQ(stanza);
|
|
return _converse.api.sendIQ(stanza);
|
|
},
|
|
},
|
|
@@ -74755,52 +74785,45 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
|
|
* public/private Key pair. The Device ID is a randomly
|
|
* public/private Key pair. The Device ID is a randomly
|
|
* generated integer between 1 and 2^31 - 1.
|
|
* generated integer between 1 and 2^31 - 1.
|
|
*/
|
|
*/
|
|
- const data = {
|
|
|
|
- 'device_id': generateDeviceID()
|
|
|
|
- };
|
|
|
|
|
|
+ const bundle = {};
|
|
return libsignal.KeyHelper.generateIdentityKeyPair().then(identity_keypair => {
|
|
return libsignal.KeyHelper.generateIdentityKeyPair().then(identity_keypair => {
|
|
- const identity_key = u.arrayBufferToBase64(identity_keypair.pubKey);
|
|
|
|
- data['identity_keypair'] = {
|
|
|
|
- 'privKey': u.arrayBufferToBase64(identity_keypair.privKey),
|
|
|
|
- 'pubKey': identity_key
|
|
|
|
- };
|
|
|
|
- data['identity_key'] = identity_key;
|
|
|
|
- return libsignal.KeyHelper.generateSignedPreKey(identity_keypair, 1);
|
|
|
|
|
|
+ const identity_key = u.arrayBufferToBase64(identity_keypair.pubKey),
|
|
|
|
+ device_id = generateDeviceID();
|
|
|
|
+ bundle['identity_key'] = identity_key;
|
|
|
|
+ bundle['device_id'] = device_id;
|
|
|
|
+ this.save({
|
|
|
|
+ 'device_id': device_id,
|
|
|
|
+ 'identity_keypair': {
|
|
|
|
+ 'privKey': u.arrayBufferToBase64(identity_keypair.privKey),
|
|
|
|
+ 'pubKey': identity_key
|
|
|
|
+ },
|
|
|
|
+ 'identity_key': identity_key
|
|
|
|
+ });
|
|
|
|
+ return libsignal.KeyHelper.generateSignedPreKey(identity_keypair, 0);
|
|
}).then(signed_prekey => {
|
|
}).then(signed_prekey => {
|
|
- _converse.omemo_store.storeSignedPreKey(signed_prekey.keyId, signed_prekey.keyPair);
|
|
|
|
|
|
+ _converse.omemo_store.storeSignedPreKey(signed_prekey);
|
|
|
|
|
|
- data['signed_prekey'] = {
|
|
|
|
- 'keyId': signed_prekey.keyId,
|
|
|
|
- 'keyPair': {
|
|
|
|
- 'privKey': u.arrayBufferToBase64(signed_prekey.keyPair.privKey),
|
|
|
|
- 'pubKey': u.arrayBufferToBase64(signed_prekey.keyPair.pubKey)
|
|
|
|
- },
|
|
|
|
|
|
+ bundle['signed_prekey'] = {
|
|
|
|
+ 'id': signed_prekey.keyId,
|
|
|
|
+ 'public_key': u.arrayBufferToBase64(signed_prekey.keyPair.privKey),
|
|
'signature': u.arrayBufferToBase64(signed_prekey.signature)
|
|
'signature': u.arrayBufferToBase64(signed_prekey.signature)
|
|
};
|
|
};
|
|
return Promise.all(_.map(_.range(0, _converse.NUM_PREKEYS), id => libsignal.KeyHelper.generatePreKey(id)));
|
|
return Promise.all(_.map(_.range(0, _converse.NUM_PREKEYS), id => libsignal.KeyHelper.generatePreKey(id)));
|
|
}).then(keys => {
|
|
}).then(keys => {
|
|
_.forEach(keys, k => _converse.omemo_store.storePreKey(k.keyId, k.keyPair));
|
|
_.forEach(keys, k => _converse.omemo_store.storePreKey(k.keyId, k.keyPair));
|
|
|
|
|
|
- const marshalled_keys = _.map(keys, k => {
|
|
|
|
- return {
|
|
|
|
- 'keyId': k.keyId,
|
|
|
|
- 'keyPair': {
|
|
|
|
- 'pubKey': u.arrayBufferToBase64(k.keyPair.pubKey),
|
|
|
|
- 'privKey': u.arrayBufferToBase64(k.keyPair.privKey)
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- data['prekeys'] = marshalled_keys;
|
|
|
|
- this.save(data); // Save the bundle to the device
|
|
|
|
-
|
|
|
|
const devicelist = _converse.devicelists.get(_converse.bare_jid),
|
|
const devicelist = _converse.devicelists.get(_converse.bare_jid),
|
|
device = devicelist.devices.create({
|
|
device = devicelist.devices.create({
|
|
- 'id': data.device_id,
|
|
|
|
|
|
+ 'id': bundle.device_id,
|
|
'jid': _converse.bare_jid
|
|
'jid': _converse.bare_jid
|
|
- });
|
|
|
|
|
|
+ }),
|
|
|
|
+ marshalled_keys = _.map(keys, k => ({
|
|
|
|
+ 'id': k.keyId,
|
|
|
|
+ 'key': u.arrayBufferToBase64(k.keyPair.pubKey)
|
|
|
|
+ }));
|
|
|
|
|
|
- device.save('bundle', data);
|
|
|
|
|
|
+ bundle['prekeys'] = marshalled_keys;
|
|
|
|
+ device.save('bundle', bundle);
|
|
});
|
|
});
|
|
},
|
|
},
|
|
|
|
|