Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Error: Identity key changed" when sending a second OMEMO message #1242

Open
goors opened this issue Oct 10, 2018 · 28 comments
Open

"Error: Identity key changed" when sending a second OMEMO message #1242

goors opened this issue Oct 10, 2018 · 28 comments

Comments

@goors
Copy link

goors commented Oct 10, 2018

  1. You click on "lock" icon
  2. Send message to User 1
  3. Open other browser where you have loggedin User 1
  4. You click on "lock" icon.
  5. Send message to User 0
  6. Try to send another and you got: Sorry, could not send the message due to an error. Identity key changed
  7. You logout and try again, it is the same (all the time I have unchecked This is a trusted device )
    I am trying this all day and every time it is the same. I used latest libsignal-protocol.js.

So as far as i can see Omemo does not work on converse.js. Hwo to debug this to checkout why?


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@goors
Copy link
Author

goors commented Oct 10, 2018

In src/converse-omemo.js line 566:

const trusted = this.get('identity_key'+identifier);
console.log("-------------------------------------------------------------------------------------");
console.log(identifier); -->  jid of user that I am trying to send message
console.log(identity_key); -->  ArrayBuffer
console.log(trusted); -> this is empty
console.log(u.arrayBufferToBase64(identity_key)) this is correct with some value
console.log("-------------------------------------------------------------------------------------");

@goors
Copy link
Author

goors commented Oct 10, 2018

Further more:
Line 567:

if (trusted === undefined) {
    return Promise.resolve(true);
}

If i change to:

if (trusted === undefined || trusted === "") {
    return Promise.resolve(true);
}

messages are encrypted (i can see that i jabber log).

So I am not really sure if this is the right way to solve this?
I would really appreciate some comment @jcbrand .

@jcbrand
Copy link
Member

jcbrand commented Oct 11, 2018

So are you saying that checking for trusted === "" fixes the problem?

If so then the problem seems to be (in part at least) that an identify key with an empty string as value had been saved, which is why your change seems to fix it.

The question now is why it got that value in the first place and whether we should be concerned about it.

What browser are you using?

Also, could you please check what happens when saveIdentity is called and whether the values look correct there? Specifically important to know is whether a proper value (i.e. not "") gets saved and whether it gets saved under the same key (i.e. whether 'identity_key'+address.getName() in saveIdentity is the same as 'identity_key'+identifier in isTrustedIdentity).

@jcbrand jcbrand changed the title Only one omemo message can be sent? Error: Identity key changed when sending a second OMEMO message Oct 11, 2018
@jcbrand jcbrand changed the title Error: Identity key changed when sending a second OMEMO message "Error: Identity key changed" when sending a second OMEMO message Oct 11, 2018
@jcbrand jcbrand added the bug label Oct 11, 2018
@goors
Copy link
Author

goors commented Oct 11, 2018

console.log("-----------------------------------------------------------")
console.log(identifier) --> chrome@localhost.4513
console.log(address) --> libsignal.SignalProtocolAddress {getName: ƒ, getDeviceId: ƒ, toString: ƒ, equals: ƒ}
console.log('identity_key'+address.getName()) --> identity_keychrome@localhost
console.log(existing) --> ""
console.log(u.arrayBufferToBase64(identity_key)) --> ""
console.log("-----------------------------------------------------------")

if (existing && b64_idkey !== existing) is always false.

I am using Version 69.0.3497.100 (Official Build) (64-bit) on

Description:	Debian GNU/Linux 9.5 (stretch)
Release:	9.5
Codename:	stretch

@jcbrand
Copy link
Member

jcbrand commented Oct 18, 2018

You logout and try again, it is the same (all the time I have unchecked This is a trusted device )

I think this might be causing the issue here. At least in part.

It doesn't really make sense to try and use OMEMO when that box is unchecked.

An established OMEMO (libsignal) session is supposed to be permanent, which means that it needs to get stored somewhere when you log out. However when the "This is a trusted device" checkbox is unchecked, then your storage gets cleared when you log out.

This means you'll never be able to decrypt messages from before you logged in.

Additionally, OMEMO establishes dependencies between different stores in localStorage and sessionStorage. When first running as a trusted device, and then as an untrusted device, the stores get mixed up and I get invalid signature errors.

There are ways to fix this, for example by clearing all browser storage before logging in when "This is an untrusted device" is unchecked, or by giving all the stores different root keys.

However, simplest is just to disable OMEMO entirely when that checkbox is unchecked (done in c8dc7b6), which in any case makes sense given the first point raised.

@Bajchos
Copy link

Bajchos commented Aug 16, 2019

I'm not sure if I should create another issue or post here but I have the exact same problem as stated in this issue: only first message can be sent encrypted and afterwards input box gets grey and "Identity key changed." error occurs.
What I have to add is that I am using auto-login setup and "trusted" property is set to true all the time.
Here is the initialize call:

converse.initialize({
    allow_logout: false,
    keepalive: true,
    authentication: "login",
    auto_login: true,
    jid: jid,
    password: password,
    websocket_url: 'wss://example:5443/ws',
    show_controlbox_by_default: true,
    show_client_info: false,
    trusted: true
});

Could it maybe be wrong configuration of XMPP server (latest version of ejabberd) or maybe it's connected to the fact that this is being tested locally and self-signed certificates are being used or is it something entirely else?

@licaon-kter
Copy link
Contributor

@Bajchos you're on Converse 5.0.1 right?

@Bajchos
Copy link

Bajchos commented Aug 16, 2019

@licaon-kter
Yep, I am using Converse 5.0.1, although this issue was happening on 4.2.0 and 5.0.0 as well.

@jcbrand
Copy link
Member

jcbrand commented Aug 16, 2019

@Bajchos Are you using your browser in incognito mode?

@Bajchos
Copy link

Bajchos commented Aug 16, 2019

@jcbrand Actually I tried both normal and incognito mode (Chrome and Firefox), tried also with clearing session and local storage, nothing helped.
One more interesting thing: only first ever message gets encrypted, after this only deleting and re-creating users on ejabberd put me to state where this first message can be sent encrypted again (re-login, clearing browser data doesn't help).

@jcbrand
Copy link
Member

jcbrand commented Aug 16, 2019

@Bajchos: Can you please register an account conversejs.org (you can only do so on https://conversejs.org through Converse.js itself which runs there) and then check whether you can reproduce this issue on that XMPP server?

@Bajchos
Copy link

Bajchos commented Aug 16, 2019

@jcbrand
I couldn't really reproduce the issue on https://conversejs.org, only issue that seemed to look like the one I am having was when I switched 1 user from one browser to another and kept second user logged in and continued to send encrypted messages.
I was playing with configuration of XMPP and what seems (need more testing) to solve my problem is changing virtual host (jid of users as well) to match the domain of jabber server.
For example:

  • my jabber server is hosted on foo.bar.net
  • created virtual host named foo.bar.net -> now users' jid is user@foo.bar.net
  • previously virtual host was name foo -> users' jid was user@foo (this way omemo wasn't working)
    No other changes were done on server side except creating another virtual host and 2 new users under it. No idea if this was the issue but right now I can send encrypted messages between users. 😄

@goors
Copy link
Author

goors commented Sep 21, 2019

I gave up on conversejs and wrote my own client.

@JLueke
Copy link

JLueke commented May 4, 2020

I get Uncaught (in promise) Error: Identity key changed after sending one encrypted message.
I use the same browser (Chrome) for two users (just changing via logout and login).
After the login I can send one message, before the error is shown in the console and the input field is disabled.

Used scripts:
https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js
https://cdn.conversejs.org/dist/converse.min.js

@nikita-cerejo
Copy link

Any update on this issue @jcbrand

@licaon-kter
Copy link
Contributor

@nikita-cerejo you are seeing this issue with latest 8 release or git HEAD code?

@nikita-cerejo
Copy link

I faced this issue on v8.0.2dev
Whenever I click on lock icon and send message to a contact, it gives me error as identity key changed and also message box greys out like disabled. But if I again click on lock icon, and try sending unencrypted message, the message box enables and I am able to send message.

@jcbrand
Copy link
Member

jcbrand commented Nov 29, 2021

@nikita-cerejo: Where/how are you using Converse?

The latest version can be tested here: https://conversejs.org/trunk/fullscreen.html

Can you reproduce the issue there?

@nikita-cerejo
Copy link

I am using github conversejs master branch, downloading the zip and using it via docker on localhost.

@jcbrand
Copy link
Member

jcbrand commented Nov 29, 2021

@nikita-cerejo: So you're building Converse yourself with make dist?

Can you please update the HTML file you're using (I'm guessing fullscreen.html) to use converse.js and not converse.min.js.
That way we'll get usable line numbers in error tracebacks.

Then check your browser console for errors and post it here. Thanks.

@nikita-cerejo
Copy link

nikita-cerejo commented Nov 29, 2021

Yes I have replaced fullscreen.html 3 days ago. There were few fixes in conversejs master so you had suggested me before to replace it. And also changed converse.min.js to converse.js.
The libsignal-protocol.min.js cdn used is :
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>

Below is the screenshot of the error I am getting.

omemo error

@jcbrand
Copy link
Member

jcbrand commented Nov 29, 2021

Please use the unminified version of libsignal as well (libsignal-protocol.js).

https://conversejs.org/3rdparty/libsignal-protocol.js

Then, when you get the error, please click on the red triangle (just before Uncaught) to open it up, so that the whole traceback can be seen.

@nikita-cerejo
Copy link

Here is the screenshot of using unminified version and error traceback

omemo detail error

@nikita-cerejo
Copy link

@jcbrand I tried the same with v9.0.0 still getting the same error. Let me know if any more information needed.

@nikita-cerejo
Copy link

@jcbrand Were you able to regenerate this issue at your end? Any update on it?

@jcbrand
Copy link
Member

jcbrand commented Nov 30, 2021

No, I haven't reproduced it. I've mainly been looking at the code based on the traceback you've sent.

Have you read this comment? #1242 (comment)
Based on that comment, I wonder whether this has to do with you hosting your XMPP server locally (and how you're doing it).

Please set loglevel to 'debug' when calling converse.initialize and then set logging to "verbose" in your browser console. Then reproduce the bug, save the console log output to a file and either paste it here or email it to me.

Maybe there's something in there that shows what's going on.

If that doesn't work, we can try to schedule a video call some time.

@nikita-cerejo
Copy link

nikita-cerejo commented Dec 1, 2021

Thanks @jcbrand I am able to send encrypted messages when I changed my virtualhost domain from localhost to server.localhost. But I faced a scenario in this, which gives error that contact client doesn't support omemo encryption. As shown in below screenshot(A).

Scenario :
-> For the first time when contact is added, if user A (in my case Test 1 i.e test1@server.localhost) sent contact request to user B (in my case Test 4 i.e test4@server.localhost) and user B accepts it.
-> If user B tries to send encrypted message first, it gives error that omemo encryption is not supported by user A client.
-> But if user A sends encrypted message to user B first and then user B sends encrypted message then it works properly as shown in the screenshot(B).
(Note : Test1 was logged in from chrome and Test 4 was logged in from microsoft edge browser)

screenshot(A) :

omemo new error

screenshot(B) :

omemo success

@jcbrand
Copy link
Member

jcbrand commented Dec 1, 2021

@nikita-cerejo: Ok, that sounds like a different issue. Can you please create a new issue for this? You can just copy/paste the same data from this comment into it.

Sounds to me like Converse should be fetching the OMEMO bundle for user A, but isn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants