Create generatePreKeys function

This commit is contained in:
JC Brand 2022-05-08 22:50:51 +02:00
parent bd579d8613
commit b5bcc05947
2 changed files with 45 additions and 21 deletions

View File

@ -121,7 +121,7 @@ const OMEMOStore = Model.extend({
'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
// publish our 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)
@ -206,22 +206,50 @@ const OMEMOStore = Model.extend({
},
/**
* Generate the data used by the X3DH key agreement protocol
* that can be used to build a session with a device.
* Generates, stores and then returns pre-keys.
*
* Pre-keys are one half of a X3DH key exchange and are published as part
* of the device bundle.
*
* For a new contact or device to establish an encrypted session, it needs
* to use a pre-key, which it chooses randomly from the list of available
* ones.
*/
async generatePreKeys () {
const amount = _converse.NUM_PREKEYS;
const { KeyHelper } = libsignal;
const keys = await Promise.all(
range(0, amount).map(id => KeyHelper.generatePreKey(id))
);
keys.forEach(k => this.storePreKey(k.keyId, k.keyPair));
return keys.map(k => ({
'id': k.keyId,
'key': u.arrayBufferToBase64(k.keyPair.pubKey)
}));
},
/**
* Generate the cryptographic data used by the X3DH key agreement protocol
* in order to build a session with other devices.
*
* By generating a bundle, and publishing it via PubSub, we allow other
* clients to download it and start asynchronous encrypted sessions with us,
* even if we're offline at that time.
*/
async generateBundle () {
// The first thing that needs to happen if a client wants to
// start using OMEMO is they need to generate an IdentityKey
// and a Device ID. The IdentityKey is a Curve25519 [6]
// public/private Key pair. The Device ID is a randomly
// generated integer between 1 and 2^31 - 1.
// and a Device ID.
// The IdentityKey is a Curve25519 public/private Key pair.
const identity_keypair = await libsignal.KeyHelper.generateIdentityKeyPair();
const bundle = {};
const identity_key = u.arrayBufferToBase64(identity_keypair.pubKey);
// The Device ID is a randomly generated integer between 1 and 2^31 - 1.
const device_id = await generateDeviceID();
bundle['identity_key'] = identity_key;
bundle['device_id'] = device_id;
this.save({
'device_id': device_id,
'identity_keypair': {
@ -230,28 +258,24 @@ const OMEMOStore = Model.extend({
},
'identity_key': identity_key
});
const signed_prekey = await libsignal.KeyHelper.generateSignedPreKey(identity_keypair, 0);
const signed_prekey = await libsignal.KeyHelper.generateSignedPreKey(identity_keypair, 0);
this.storeSignedPreKey(signed_prekey);
const prekeys = await this.generatePreKeys();
const bundle = { identity_key, device_id, prekeys };
bundle['signed_prekey'] = {
'id': signed_prekey.keyId,
'public_key': u.arrayBufferToBase64(signed_prekey.keyPair.pubKey),
'signature': u.arrayBufferToBase64(signed_prekey.signature)
};
const keys = await Promise.all(
range(0, _converse.NUM_PREKEYS).map(id => libsignal.KeyHelper.generatePreKey(id))
);
keys.forEach(k => this.storePreKey(k.keyId, k.keyPair));
const devicelist = await api.omemo.devicelists.get(_converse.bare_jid);
const device = await devicelist.devices.create(
{ 'id': bundle.device_id, 'jid': _converse.bare_jid },
{ 'promise': true }
);
const marshalled_keys = keys.map(k => ({
'id': k.keyId,
'key': u.arrayBufferToBase64(k.keyPair.pubKey)
}));
bundle['prekeys'] = marshalled_keys;
device.save('bundle', bundle);
},

View File

@ -1,18 +1,18 @@
/* global libsignal */
import concat from 'lodash-es/concat';
import difference from 'lodash-es/difference';
import log from '@converse/headless/log';
import tpl_audio from 'templates/audio.js';
import tpl_file from 'templates/file.js';
import tpl_image from 'templates/image.js';
import tpl_video from 'templates/video.js';
import { MIMETYPES_MAP } from 'utils/file.js';
import { KEY_ALGO, UNTRUSTED, TAG_LENGTH } from './consts.js';
import { MIMETYPES_MAP } from 'utils/file.js';
import { __ } from 'i18n';
import { _converse, converse, api } from '@converse/headless/core';
import { html } from 'lit';
import { initStorage } from '@converse/headless/utils/storage.js';
import { isAudioURL, isImageURL, isVideoURL, getURI } from '@converse/headless/utils/url.js';
import concat from 'lodash-es/concat';
import { until } from 'lit/directives/until.js';
import {
appendArrayBuffer,