qyIs anyone aware of why session_pre_key_bundle in libomemo-c/libsignal-protocol-c indicates only one prekey, whereas both prekeymessages and bundles in xep-0384 indicate specifically more than one?
Chuckhas left
moparisthebestWhich version of 384 are you looking at? The current one no one implements or the previous one that everyone implements?
qyBoth, tbh
qyAfaict so far the main difference is the namespaces
qyIve mainly focused on the axolotl version, since it's more accurate
qyI think i see now that only one prekey is used in a signal session, but i still have no clue how to feed an xmpp bundle into libsignal based on that
qyOr does libsignal not store bundles themselves?
qyPerhaps they remain ephemeral, requested on need, and only sessions are stored?
qyMy understanding was that bundles were stored too
melvoqy: You upload multiple pre keys. A device building a session with your device, takes one of them and calls `session_pre_key_bundle()`. That pre key is passed to `session_pre_key_bundle()`.✎
melvoqy: You upload multiple pre keys. A device building a session with your device takes one of them and calls `session_pre_key_bundle()`. That pre key is passed to `session_pre_key_bundle()`. ✏
melvomoparisthebest: UWPX already implemented the latest version and we are working on an implementation for QXmpp / Kaidan.
melvoYou have to remove that pre key from your published bundle and publish a new one in order to you ensure that other devices do not take an already used pre key.
qyI follow :) are sessions created reciprocally? i.e. Must i create one in response to someone creating one with me, or is one direction enough?
melvolibomemo-c stores pre keys with `store_pre_key()` of the struct `signal_protocol_pre_key_store`.
qyI think i was mainly thrown because libsignal makes no reference to randomly choosing from a prekey list
qy> melvo wrote:
> libomemo-c stores pre keys with `store_pre_key()` of the struct `signal_protocol_pre_key_store`.
For local prekeys, right?
qy`store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len, void *user_data)` has no discriminator for foreign keys
qyI've implemented all the stores
melvoSignal has a better approach for distributing pre keys. A device request one pre key, the server returns only one and removes it automatically. In OMEMO, we use PubSub and it has no such logic. So, we have to retrieve all pre keys and take care of them by ourselves.✎
melvoSignal has a better approach for distributing pre keys. A device requests one pre key, the server returns only one and removes it automatically. In OMEMO, we use PubSub and it has no such logic. So, we have to retrieve all pre keys and take care of them by ourselves. ✏
melvo>For local prekeys, right?
Yes.
qyAhh.
melvo> `store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len, void *user_data)` has no discriminator for foreign keys
You only have to store your own pre keys.
qyRight, i think im clear on this now
tritiumhas left
tritiumhas joined
Jeroenhas joined
Jeroenhas left
Jeroenhas joined
melvo🙂
Jeroenhas left
*IM*has joined
hellohas joined
hellohas left
Jeroenhas joined
Jeroenhas left
Jeroenhas joined
Jeroenhas left
Jeroenhas joined
Jeroenhas left
Jeroenhas joined
Jeroenhas left
Thilo Molitorhas left
Jeroenhas joined
Jeroenhas left
qyHmm, just realised the biggest issue is that i need to close the loop and fully implement callbacks
qySince it uses pubsub rather than persistence
tritiumhas left
Thilo Molitorhas joined
Jeroenhas joined
Jeroenhas left
sequalshas left
sequalshas joined
hellohas joined
Jeroenhas joined
Jeroenhas left
msavoritiashas left
Jeroenhas joined
melvoqy: What client is it?
qymelvo: https://github.com/bqv/weechat-xmpp
qyAnother question, also
qySince clients have multiple devices, does that imply a session should be created for each device? Or one with every device as a recipient?
qyI don't quite follow that workflow yet
meeson_has left
hellohas left
melvoYour client builds a session for each device (in practice, a client instance) in your contact's device list and for each device in your own device list but not to your own device.
hellohas joined
Jeroenhas left
Jeroenhas joined
melvoUnfortunately, the term *device* is not precise because multiple client instances may run on one physical device. But in the world of Signal there is only one client instance per device...
Jeroenhas left
Jeroenhas joined
melvohas left
melvohas joined
qyYeah that makes sense, a device is a client. So is the group_session code used to make things work for all present clients?
qyOr, is every stanza sent done n times for each client?
qyI feel like if it was the latter i'd have noticed
sequalshas left
Jeroenhas left
meeson_has joined
qyYes, all in one, per the spec. I thought libsignal had something for multiple recipients but maybe i need to do that manually?
Jeroenhas joined
vanitasvitaeqy: just add all recipient devices to the message header
vanitasvitaeThe message itself is only encrypted once.
vanitasvitaeAnd only one stanza is being sent
vanitasvitaeBut each recipient can encrypt it (hopefully)
melvo> Yeah that makes sense, a device is a client.
And each client instance could even use multiple sessions for communicating with same end. Thus, I prefer the term endpoint. Enough meta discussion 😁✎
atomicwatchhas left
atomicwatchhas joined
meeson_has left
melvo> Yeah that makes sense, a device is a client.
And each client instance could even use multiple sessions for communicating with same end. Thus, I prefer the term *endpoint*. Enough meta discussion 😁 ✏
qyRight, so the message is the payload, and each device gets a the key encrypted to their prekey in the header. But how does that translate to libsignal calls, if you excuse my ignorance 😅
`session_cipher_encrypt(cipher, message, message_len, &encrypted_message)` drops out the payload, so where do the keys come from?✎
qyRight, so the message is the payload, and each endpoint gets a the key encrypted to their prekey in the header. But how does that translate to libsignal calls, if you excuse my ignorance 😅
`session_cipher_encrypt(cipher, message, message_len, &encrypted_message)` drops out the payload, so where do the keys come from? ✏
qymelvo: noted :p
melvoThe key material is retrieved by the store functions / PreKeyMessage.
Jeroenhas left
meeson_has joined
Jeroenhas joined
Jeroenhas left
Titihas joined
qyIm trying to interpret this from the dino code but it's nontrivial
qySo libsignal's session_cipher creates the ciphertextmessage object, which is the message encrypted for that specific session/pair of endpoints
qySurely if that's done for every endpoint, the payloads will all be different?
meeson_has left
qyModelling this on the libsignal readme code:
```
/* Create the session cipher and encrypt the message */
session_cipher *cipher;
session_cipher_create(&cipher, store_context, &address, global_context);
session_builder_set_version(cipher, 4);
ciphertext_message *encrypted_message;
session_cipher_encrypt(cipher, message, message_len, &encrypted_message);
/* Get the serialized content and deliver it */
signal_buffer *serialized = ciphertext_message_get_serialized(encrypted_message);
deliver(signal_buffer_data(serialized), signal_buffer_len(serialized));
```✎
qyModelling this on the libsignal readme code:
```
/* Create the session cipher and encrypt the message */
session_cipher *cipher;
session_cipher_create(&cipher, store_context, &address, global_context);
ciphertext_message *encrypted_message;
session_cipher_encrypt(cipher, message, message_len, &encrypted_message);
/* Get the serialized content and deliver it */
signal_buffer *serialized = ciphertext_message_get_serialized(encrypted_message);
deliver(signal_buffer_data(serialized), signal_buffer_len(serialized));
``` ✏
meeson_has joined
qyTo [encrypt the message] as vanitasvitae was saying above, i'd need to do it with no recipient and then fetch the symmetric key used for the returned ciphertext, or something? Then encrypt _that_ for each endpoint, into the header
qy> melvo wrote:
> The key material is retrieved by the store functions / PreKeyMessage.
Dino seems to create prekeymessage from the ciphertext_message in a test at least, am i missing a trick?
Jeroenhas joined
meeson_has left
Jeroenhas left
meeson_has joined
qyI really wish i understood this thoroughly, i feel like im reinventing things i dont need to
Sevehas left
Jeroenhas joined
vanitasvitaeI'm not familiar with C code, so I can't help with the details
Jeroenhas left
vanitasvitaeBut the flow is: fetch the device list(s), check if you have a session with each device, if not then fetch missing bundles and select a random prekey to build missing sessions (session_builder_process_prekey_bundle), then encrypt the message using a message key and encrypt the message key for each recipient
Jeroenhas joined
Jeroenhas left
qyRight, i think from that and scanning github for a while, i might be able to implement it
qyvanitasvitae: Thanks :D
vanitasvitaeIn libsignal-protocol-c, afaict what's called message is actually an AES message key
vanitasvitaeBut I might be wrong
qyYeah, that confused me
vanitasvitaeSo ciphertext_message is an encrypted message key
hellohas left
qyYeah, i think im clear on it all now :D thanks for bearing with me