Ratchet: Make DI optional in ACK request

Don't put ACK request in NS or NSR
This commit is contained in:
zzz
2020-03-20 19:01:56 +00:00
parent 6487fb0516
commit 5c1700c2ab
2 changed files with 33 additions and 12 deletions

View File

@ -583,7 +583,8 @@ public final class ECIESAEADEngine {
if (re == null) {
if (_log.shouldDebug())
_log.debug("Encrypting as NS to " + target);
return encryptNewSession(cloves, target, priv, keyManager, replyDI);
// no ack in NS
return encryptNewSession(cloves, target, priv, keyManager, null);
}
HandshakeState state = re.key.getHandshakeState();
@ -597,7 +598,8 @@ public final class ECIESAEADEngine {
}
if (_log.shouldDebug())
_log.debug("Encrypting as NSR to " + target + " with tag " + re.tag.toBase64());
return encryptNewSessionReply(cloves, target, state, re.tag, keyManager, replyDI);
// no ack in NSR
return encryptNewSessionReply(cloves, target, state, re.tag, keyManager, null);
}
if (_log.shouldDebug())
_log.debug("Encrypting as ES to " + target + " with key " + re.key + " and tag " + re.tag.toBase64());
@ -812,6 +814,7 @@ public final class ECIESAEADEngine {
public final List<GarlicClove> cloveSet = new ArrayList<GarlicClove>(3);
public long datetime;
public NextSessionKey nextKey;
public boolean ackRequested;
public void gotDateTime(long time) {
if (_log.shouldDebug())
@ -846,6 +849,7 @@ public final class ECIESAEADEngine {
public void gotAckRequest(int id, DeliveryInstructions di) {
if (_log.shouldDebug())
_log.debug("Got ACK REQUEST block: " + di);
ackRequested = true;
}
public void gotTermination(int reason, long count) {
@ -890,7 +894,8 @@ public final class ECIESAEADEngine {
}
if (replyDI != null) {
// put after the cloves so recipient has any LS garlic
Block block = new AckRequestBlock(0, replyDI);
// ignore actual DI
Block block = new AckRequestBlock(0, null);
blocks.add(block);
len += block.getTotalLength();
}

View File

@ -68,6 +68,7 @@ class RatchetPayload {
public void gotAck(int id, int n);
/**
* @param di may be null
* @since 0.9.46
*/
public void gotAckRequest(int id, DeliveryInstructions di);
@ -148,7 +149,7 @@ class RatchetPayload {
case BLOCK_ACKKEY:
{
if (len < 4 || (len % 4) != 0)
throw new IOException("Bad length for REPLYDI: " + len);
throw new IOException("Bad length for ACKKEY: " + len);
for (int j = i; j < i + len; j += 4) {
int id = (int) DataHelper.fromLong(payload, j, 2);
int n = (int) DataHelper.fromLong(payload, j + 2, 2);
@ -159,11 +160,16 @@ class RatchetPayload {
case BLOCK_REPLYDI:
{
if (len < 6)
if (len < 3)
throw new IOException("Bad length for REPLYDI: " + len);
int id = (int) DataHelper.fromLong(payload, i, 4);
DeliveryInstructions di = new DeliveryInstructions();
di.readBytes(payload, i + 5);
int id = (int) DataHelper.fromLong(payload, i, 2);
DeliveryInstructions di;
if ((payload[2] & 0x01) != 0) {
di = new DeliveryInstructions();
di.readBytes(payload, i + 3);
} else {
di = null;
}
cb.gotAckRequest(id, di);
}
break;
@ -383,12 +389,22 @@ class RatchetPayload {
public static class AckRequestBlock extends Block {
private final byte[] data;
/**
* @param sessionID 0 - 65535
* @param di may be null
*/
public AckRequestBlock(int sessionID, DeliveryInstructions di) {
super(BLOCK_REPLYDI);
data = new byte[5 + di.getSize()];
DataHelper.toLong(data, 0, 4, sessionID);
// flag is zero
di.writeBytes(data, 5);
int len = 3;
if (di != null)
len += di.getSize();
data = new byte[len];
DataHelper.toLong(data, 0, 2, sessionID);
if (di != null) {
data[2] = 0x01;
di.writeBytes(data, 3);
}
// else flag is zero
}
public int getDataLength() {