-
Notifications
You must be signed in to change notification settings - Fork 292
Cryptography
Benny Neugebauer edited this page Oct 11, 2019
·
14 revisions
Code generation
(z.util.murmurhash3('Field too long',42)+'').substr(0,4); // 1738
Error Code | Type/Error | Reason |
---|---|---|
2 (1778) |
RangeError Offset is outside the bounds of the DataView |
Remote side failed to decrypt our message and sends 💣 |
200 |
DecryptError Unknown message type |
Remote side does not follow proteus specification |
201 (2237) |
DecryptError.InvalidMessage Can't initialise a session from a CipherMessage. |
Occurs when the remote party thinks we have an initialised session, but it does not/no longer exist locally. We must have confirmed the session with the remote party by sending them a message. Until then then they continue to send us PreKeyMessages instead of CipherMessages. We prematurely deleted the session before decrypting all events. |
202 |
DecryptError.InvalidMessage Unknown message format: The message is neither a "CipherMessage" nor a "PreKeyMessage". |
Remote side does not follow proteus specification |
203 |
DecryptError.PrekeyNotFound Could not delete PreKey |
|
204 (3690) |
DecryptError.RemoteIdentityChanged Remote identity changed |
Client of the user has changed without informing us (Man in the middle attack? or database conflicts on the remote side: sessions get mixed with new client) |
205 (1976) |
DecryptError.InvalidMessage No matching session tag. |
Usually happens when we receive a message intended for another client. |
206 |
DecryptError.InvalidSignature Decryption of a message in sync failed |
Envelope mac key verification failed |
207 (8550) |
DecryptError.InvalidSignature Decryption of a newer message failed |
Envelope mac key verification failed. Session broken or out of sync. Reset the session and decryption is likely to work again! |
208 (2521) |
DecryptError.OutdatedMessage Message is out of sync |
Opposite of "Too distant future" error |
209 (1701) |
DecryptError.DuplicateMessage Duplicate message |
Happens if an encrypted message is decrypted twice |
210 |
DecryptError.InvalidSignature Decryption of a previous (older) message failed |
Envelope mac key verification |
211 (1300) |
DecryptError.TooDistantFuture Message is from too distant in the future |
More than 1000 messages on the receive chain were skipped |
213 |
DecryptError.InvalidMessage Sender failed to encrypt a message. |
Error on receiver side when remote side sends a 💣
|
300 |
DecryptError.InvalidMessage The received message was too big. |
Destroy session states
// This will enforce 'No matching session state.'
var client_id = "494C60375CC490E4".toLowerCase();
var sessions = wire.app.repository.cryptography.cryptobox.store.sessions;
var cryptobox_session = sessions[Object.keys(sessions).filter((session_key) => session_key.endsWith(client_id))[0]];
cryptobox_session.session_states = {};
- conv is verified
- backend rejects message because of missing client id
- we check for that device.... if it is unknown to us and not verified we show "conv degraded"
Retrieve the identity key pair
wire.app.repository.encryption.cryptobox
Payload after successful registration
Permanent device:
{
"cookie": "Wire - 569cff83-a338-487f-8f06-7a7c250664eb",
"time": "2015-12-17T16:06:09.097Z",
"location": {
"lat": 51.5,
"lon": -0.13
},
"address": "62.96.148.44",
"model": "Chrome 47.0.2526.80",
"id": "5791adc5672bf043",
"type": "permanent",
"class": "desktop",
"label": "Windows NT 10.0"
}
Temporary device:
{
"cookie": "Wire - 2507b1a5-1cf0-4144-b284-c349e6e8029e",
"time": "2015-12-17T16:08:56.293Z",
"location": {
"lat": 51.5,
"lon": -0.13
},
"address": "62.96.148.44",
"model": "Chrome 47.0.2526.80",
"id": "585d8f6b2a118d6f",
"type": "temporary",
"class": "desktop",
"label": "Windows NT 10.0"
}
iOS behaviour
Sending a message
- req to
/conversation/xxxxxxx/otr
- BE returns
{ missed: deleted: redundant: }
- take the missed json object, and put in a request to:
/users/prekeys
- pass missed keys to:
public func sessionWithId(sessionId: String, fromStringPreKey base64StringKey: String) throws -> CBSession
to create a session - resent to same /conversation/xxxx/otr
- repeat until there are no more
"missed"
Note:
When I want to send, I need to get the session of each client recipient, with: CBSession *session = [box sessionById:client.remoteIdentifier error:&error]
and encrypt for that client with: NSData *encryptedData = [session encrypt:dataToEncrypt error:&error];
Receiving a message
When receiving an event, the event has the "sender"
JSON field. That's the client ID of the sender.
CBSession *session = [self sessionById:sessionId error:&error];
if (session != nil) { // I already have a session
decryptedMessageData = [session decrypt:data error:&error];
if (createdNewSession) {
*createdNewSession = NO;
}
}
else {
CBSessionMessage *sessionMessage = [self sessionMessageWithId:sessionId fromMessage:data error:&error];
decryptedMessageData = sessionMessage.data;
}
Useful:
- When fetching
/notifications
, pass your client ID (not mandatory) - When opening web socket, same
Composition
cryptobox.CryptoboxSession = client_id, Store, Proteus.session.Session
Proteus.session.Session(local Proteus.keys.IdentityKeyPair, remote Proteus.keys.PreKeyBundle)
Proteus.keys.PreKeyBundle = Proteus.keys.IdentityKey & Proteus.keys.PreKey
Proteus.keys.PreKey = key_id & Proteus.keys.KeyPair
Proteus.keys.KeyPair = secret_key & public_key
Creation
pre_key = Proteus.keys.PreKey.new prekey_id
pre_key_bundle = Proteus.keys.PreKeyBundle.new(@identity.public_key, pk).serialise()
Serialized format
serialized_format =
id: 456
payload: 'base64encodedstring'
type: 'Proteus.keys.PreKey'
version: 1