KeyExchange interoperability with axolotl-java
gardenia opened this issue · 5 comments
Hi,
I am having an interpoerability problem with the java library when doing p2p KeyExchange. Sometimes it works, sometimes it doesn't.
Are there any known issues in this area?
I have created a functional example here to illustrate the problem I am seeing:
https://github.com/gardenia/axolotl-sandbox
to reproduce the issue I am seeing you will need 2 console windows.
In Window #1:
- cd into the java directory and type "make run". if the build stuff is working you should output like the following:
ALICE keyexchange initiate >>> 2308c1c004122105c2923b830fcfc984d4f34e685720435b1bafb9bbfde71d32a62109019261ba4a1a21054bddc9e188f261aeecf04dcc08f011ac735be65786e9aa23c7be8a35c09ee3642221058825d0f050925cd3b671affeb11cde9f29dd7d64d9f4e5c9dc3f04e7b8c4ab10
- copy the blob of hex (from your window) after the ">>>" bit
- NOTE: the above will be followed by a prompt for a keyexchange response. we will fill this later but not yet
now switch to Window #2:
- do "make init" followed by "make run"
- paste in the blob of hex you obtained from Window #1
- on the second last line you should see something like this:
RESPONSE >>> b'3308c2dc63122105ed51973caa1e00da087d18c0cda3ca92597f45179e7053a5080a42d9693c99241a21051479eb7d325bc5da0efaec6eb9844c36290d9ec49cf3fff6feaee630cf85e46f222105c3d6f9aa7d0b2e87e82664e44cd7591d17f57c8c7136bdfd8ef2cc1ac1fc88242a40f885ebff355d93e1f5c6a5019d9705815eb1760f077c93a20019a814ec6d15fa92d39bac0139b7b34151a4510ca5b81b58405a079b5a69528c1e155b0731d807
- copy the hex bytes from the above (just the bit inside the quotes)
- NOTE: the above will be followed by a prompt for a keyexchange response. we will fill this later but not yet
now switch to Window #1:
- this window should still be prompting for "Enter BOB keyexchange response"
- paste in the bytes obtained from Window #2 into this prompt
- you should now see output like the following:
MESSAGE[HEX] >>> 330a210507df96417571fe22dd9f6c6b022f0a712f42adb1ad364e7f69b682743b4f3707100018002210ed04776fdee3747d5cc2117bca394a686836e1218f40ab90
- copy the hex bytes into your clipboard
now switch to Window #2:
- paste in the hex bytes you just copied from Window #1
when it works as expected it looks like this:
SessionCipher >>> <axolotl.sessioncipher.SessionCipher object at 0x2ab8c737ce80>
WhisperMessage >>> <axolotl.protocol.whispermessage.WhisperMessage object at 0x2ab8c737ccf8>
DECRYPTED >>> Hello world
however, about 50% of the time this fails as follows:
SessionCipher >>> <axolotl.sessioncipher.SessionCipher object at 0x2ba2831d2e80>
WhisperMessage >>> <axolotl.protocol.whispermessage.WhisperMessage object at 0x2ba2831d2cf8>
EXCEPTION >>> No valid sessionsBad Mac!
*** print_tb:
File "main.py", line 60, in handle_data_msg
data = sc.decryptMsg(wm)
I tried digging into the bad mac error but after a lot of speculative printf style debugging. it seems that the axolotl.ratchet.chainkey keys are mismatching in the bad case but I can't figure out why.
I could well be missing something obvious here but I'm sufficiently stuck on this that I could really do with some further eyes on it.
any help appreciated. I'm happy to dig into it further myself if you have any suggestions.
Thanks.
I believe I see the problem here.
in RatchetingSession.isAlice the java code does a comparison of 2 certificates by making a java.math.BigInteger object with the byte arrays of each cert.
the java mechanism using big-endian and returns a signed integer (https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#BigInteger(byte[])
the current python mechanism returns an unsigned integer:
int(binascii.hexlify(self.publicKey), 16)
this leads to the non-derterministic results between java and python.
for python3 I was able to get it to work consistently correctly using the attached patch (which leverages int.from_bytes). howver, unfortunately this is not portable to python2 and would need to be emulated somehow.
here is a patch which from my testing solves the problem on both python2 and python3
it reads the bytes into a tuple of signed ints and then uses tuple comparison