use empty message (not key transport) to finish sessions

This commit is contained in:
Daniel Gultsch 2023-03-01 08:48:23 +01:00
parent 5e79dd8b68
commit 86ef179c42
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
2 changed files with 52 additions and 6 deletions

View file

@ -35,6 +35,8 @@ public class EncryptionBuilder {
private byte[] payload;
private KeyTransport keyTransport;
public Encrypted build() throws AxolotlEncryptionException {
try {
return buildOrThrow();
@ -57,6 +59,8 @@ public class EncryptionBuilder {
final long sourceDeviceId =
Preconditions.checkNotNull(this.sourceDeviceId, "Specify a source device id");
final var payloadCleartext = Preconditions.checkNotNull(this.payload, "Specify a payload");
Preconditions.checkState(
this.keyTransport == null, "A payload message should not have a keyTransport");
Preconditions.checkState(sessions.size() > 0, "Add at least on session");
final var sessions = ImmutableList.copyOf(this.sessions);
final var key = generateKey();
@ -89,14 +93,37 @@ public class EncryptionBuilder {
Preconditions.checkNotNull(this.sourceDeviceId, "Specify a source device id");
Preconditions.checkState(
this.payload == null, "A key transport message should not have a payload");
final var keyTransport =
Preconditions.checkNotNull(this.keyTransport, "Specify a keyTransport");
// TODO key transport messages in twomemo (omemo:1) use 32 bytes of zeros instead of a key
// TODO if we are not using this using this for actual key transport we can do this in siacs
// omemo too (and get rid of the IV)
final var sessions = ImmutableList.copyOf(this.sessions);
final var key = generateKey();
final var iv = generateIv();
final var header = buildHeader(sessions, key);
header.addIv(iv);
final var header = buildHeader(sessions, keyTransport.key);
header.addIv(keyTransport.iv);
header.setSourceDevice(sourceDeviceId);
final var encrypted = new Encrypted();
encrypted.addExtension(header);
return encrypted;
}
public Encrypted buildEmpty() throws AxolotlEncryptionException {
try {
return buildEmptyOrThrow();
} catch (final UntrustedIdentityException e) {
throw new AxolotlEncryptionException(e);
}
}
private Encrypted buildEmptyOrThrow() throws UntrustedIdentityException {
final long sourceDeviceId =
Preconditions.checkNotNull(this.sourceDeviceId, "Specify a source device id");
Preconditions.checkState(
this.payload == null, "An empty message should not have a payload");
Preconditions.checkState(
this.keyTransport == null, "An empty message should not have a keyTransport");
final var sessions = ImmutableList.copyOf(this.sessions);
final var header = buildHeader(sessions, new byte[32]);
header.setSourceDevice(sourceDeviceId);
final var encrypted = new Encrypted();
encrypted.addExtension(header);
@ -108,6 +135,11 @@ public class EncryptionBuilder {
return this;
}
public EncryptionBuilder keyTransport(final KeyTransport keyTransport) {
this.keyTransport = keyTransport;
return this;
}
public EncryptionBuilder session(final AxolotlSession session) {
this.sessions.add(session);
return this;
@ -182,4 +214,18 @@ public class EncryptionBuilder {
Conversations.SECURE_RANDOM.nextBytes(iv);
return iv;
}
public static KeyTransport createKeyTransport() {
return new KeyTransport(generateKey(), generateIv());
}
public static class KeyTransport {
public final byte[] key;
public final byte[] iv;
private KeyTransport(byte[] key, byte[] iv) {
this.key = key;
this.iv = iv;
}
}
}

View file

@ -525,7 +525,7 @@ public class AxolotlManager extends AbstractManager implements AxolotlService.Po
new EncryptionBuilder()
.session(existingSession)
.sourceDeviceId(signalProtocolStore().getLocalRegistrationId())
.buildKeyTransport();
.buildEmpty();
} catch (final AxolotlEncryptionException e) {
LOGGER.error("Could not create key transport message to complete session", e);
return;
@ -534,7 +534,7 @@ public class AxolotlManager extends AbstractManager implements AxolotlService.Po
message.setTo(axolotlAddress.getJid());
message.addExtension(encrypted);
LOGGER.info(
"Sending KeyTransport Message to {}/{}",
"Sending empty axolotl message to {}/{}",
axolotlAddress.getJid(),
axolotlAddress.getDeviceId());
connection.sendMessagePacket(message);