-
qy
o/
-
qy
Is 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?
-
moparisthebest
Which version of 384 are you looking at? The current one no one implements or the previous one that everyone implements?
-
qy
Both, tbh
-
qy
Afaict so far the main difference is the namespaces
-
qy
Ive mainly focused on the axolotl version, since it's more accurate
-
qy
I 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
-
qy
Or does libsignal not store bundles themselves?
-
qy
Perhaps they remain ephemeral, requested on need, and only sessions are stored?
-
qy
My understanding was that bundles were stored too
-
melvo
qy: 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()`.✎ -
melvo
qy: 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()`. ✏
-
melvo
moparisthebestโ: UWPX already implemented the latest version and we are working on an implementation for QXmpp / Kaidan.
-
melvo
You 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.
-
qy
I follow :) are sessions created reciprocally? i.e. Must i create one in response to someone creating one with me, or is one direction enough?
-
melvo
libomemo-c stores pre keys with `store_pre_key()` of the struct `signal_protocol_pre_key_store`.
-
qy
I 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
-
qy
I've implemented all the stores
-
melvo
Signal 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.✎ -
melvo
Signal 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.
-
qy
Ahh.
-
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.
-
qy
Right, i think im clear on this now
-
melvo
๐
-
qy
Hmm, just realised the biggest issue is that i need to close the loop and fully implement callbacks
-
qy
Since it uses pubsub rather than persistence
-
melvo
qy: What client is it?
-
qy
melvo: https://github.com/bqv/weechat-xmpp
-
qy
Another question, also
-
qy
Since clients have multiple devices, does that imply a session should be created for each device? Or one with every device as a recipient?
-
qy
I don't quite follow that workflow yet
-
melvo
Your 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.
-
melvo
Unfortunately, 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...
-
qy
Yeah that makes sense, a device is a client. So is the group_session code used to make things work for all present clients?
-
qy
Or, is every stanza sent done n times for each client?
-
qy
I feel like if it was the latter i'd have noticed
-
qy
Yes, all in one, per the spec. I thought libsignal had something for multiple recipients but maybe i need to do that manually?
-
vanitasvitae
qy: just add all recipient devices to the message header
-
vanitasvitae
The message itself is only encrypted once.
-
vanitasvitae
And only one stanza is being sent
-
vanitasvitae
But 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 ๐✎ -
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 ๐ ✏
-
qy
Right, 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?✎ -
qy
Right, 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? ✏
-
qy
melvo: noted :p
-
melvo
The key material is retrieved by the store functions / PreKeyMessage.
-
qy
Im trying to interpret this from the dino code but it's nontrivial
-
qy
So libsignal's session_cipher creates the ciphertextmessage object, which is the message encrypted for that specific session/pair of endpoints
-
qy
Surely if that's done for every endpoint, the payloads will all be different?
-
qy
Modelling 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)); ```✎ -
qy
Modelling 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)); ``` ✏
-
qy
To [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?
-
qy
I really wish i understood this thoroughly, i feel like im reinventing things i dont need to
-
vanitasvitae
I'm not familiar with C code, so I can't help with the details
-
vanitasvitae
But 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
-
qy
Right, i think from that and scanning github for a while, i might be able to implement it
-
qy
vanitasvitae: Thanks :D
-
vanitasvitae
In libsignal-protocol-c, afaict what's called message is actually an AES message key
-
vanitasvitae
But I might be wrong
-
qy
Yeah, that confused me
-
vanitasvitae
So ciphertext_message is an encrypted message key
-
qy
Yeah, i think im clear on it all now :D thanks for bearing with me
-
vanitasvitae
you're welcome ๐