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

View File

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