Below is the detailed observations during aTalk system testing:
a. When an omemo message is sent from swan@atalk.syste.net to swordfish@atalk.sytes.net
b swordfish complains not valid session found.
c. So it proceeds to perform OmemoService#buildFreshSessionWithDevice().
d. However this attempt failed during SignalOmemoService#processBundle(); the
Curve.verifySignature(preKey.getIdentityKey().getPublicKey(), preKey.getSignedPreKey().serialize(), preKey.getSignedPreKeySignature())) return false hence throws an InvalidKeyException.
e. This leads to aTalk get locked in this state unable to recover itself; it is now impossible to exchange omemo messages between swan and swordfish.
However It was found that exchange of omemo messages between leopard@atalk.sytes.net and swan has no problem.
Wonder if the swan bundle on server is ready corrupted, so aTalk forces smack OmemoService#buildFreshSessionWithDevice() to proceed even with InvalidKeyException; by changing the following source i.e. invert Curve.verifySignature check result:
public void process(PreKeyBundle preKey) throws InvalidKeyException, UntrustedIdentityException {
synchronized (SessionCipher.SESSION_LOCK) {
if (!identityKeyStore.isTrustedIdentity(remoteAddress, preKey.getIdentityKey(), IdentityKeyStore.Direction.SENDING)) {
throw new UntrustedIdentityException(remoteAddress.getName(), preKey.getIdentityKey());
}
if (preKey.getSignedPreKey() != null &&
Curve.verifySignature(preKey.getIdentityKey().getPublicKey(),
preKey.getSignedPreKey().serialize(),
preKey.getSignedPreKeySignature()))
{
throw new InvalidKeyException("Invalid signature on device key!");
}
if (preKey.getSignedPreKey() == null) {
throw new InvalidKeyException("No signed prekey!");
}
....
}
After the above changes to temporary allow aTalk to rebuild the session, It is found that aTalk is able to recover form the earlier locked state. The exchange of omemo messages between swan and swordfish is now full working.
No sure why Curve.verifySignature() return false. Any comment?