SSU2: Validate DateTime block in handshake messages

This commit is contained in:
zzz
2022-02-28 16:50:41 -05:00
parent 46ef49f2cf
commit 21c1f89249
4 changed files with 32 additions and 4 deletions

View File

@@ -54,7 +54,7 @@ class InboundEstablishState {
// identical to uncomfirmed, but sig now verified
protected RouterIdentity _receivedConfirmedIdentity;
// general status
private final long _establishBegin;
protected final long _establishBegin;
//private long _lastReceive;
protected long _lastSend;
protected long _nextSend;

View File

@@ -49,9 +49,11 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
private byte[] _sendHeaderEncryptKey2;
private byte[] _rcvHeaderEncryptKey2;
private byte[] _sessCrForReTX;
private long _timeReceived;
// testing
private static final boolean ENFORCE_TOKEN = false;
private static final long MAX_SKEW = 2*60*1000L;
/**
@@ -139,6 +141,11 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
_sendHeaderEncryptKey2 = SSU2Util.hkdf(_context, _handshakeState.getChainingKey(), "SessCreateHeader");
_currentState = InboundState.IB_STATE_REQUEST_RECEIVED;
}
if (_timeReceived == 0)
throw new GeneralSecurityException("No DateTime block in Session/Token Request");
long skew = _establishBegin - _timeReceived;
if (skew > MAX_SKEW || skew < 0 - MAX_SKEW)
throw new GeneralSecurityException("Skew exceeded in Session/Token Request: " + skew);
packetReceived();
}
@@ -160,7 +167,7 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
/////////////////////////////////////////////////////////
public void gotDateTime(long time) {
System.out.println("Got DATE block: " + DataHelper.formatTime(time));
_timeReceived = time;
}
public void gotOptions(byte[] options, boolean isHandshake) {
@@ -383,7 +390,13 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
}
if (_log.shouldDebug())
_log.debug("State after sess req: " + _handshakeState);
_timeReceived = 0;
processPayload(data, off + LONG_HEADER_SIZE, len - (SHORT_HEADER_SIZE + KEY_LEN + MAC_LEN + MAC_LEN), true);
if (_timeReceived == 0)
throw new GeneralSecurityException("No DateTime block in Session Request");
long skew = _establishBegin - _timeReceived;
if (skew > MAX_SKEW || skew < 0 - MAX_SKEW)
throw new GeneralSecurityException("Skew exceeded in Session Request: " + skew);
_sendHeaderEncryptKey2 = SSU2Util.hkdf(_context, _handshakeState.getChainingKey(), "SessCreateHeader");
_currentState = InboundState.IB_STATE_REQUEST_RECEIVED;

View File

@@ -49,7 +49,7 @@ class OutboundEstablishState {
private long _sentSignedOnTime;
private Signature _sentSignature;
// general status
private final long _establishBegin;
protected final long _establishBegin;
//private long _lastReceive;
private long _lastSend;
private long _nextSend;

View File

@@ -50,7 +50,10 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
private int _mtu;
private byte[] _sessReqForReTX;
private byte[] _sessConfForReTX;
private long _timeReceived;
private static final boolean SET_TOKEN = false;
private static final long MAX_SKEW = 2*60*1000L;
/**
* @param claimedAddress an IP/port based RemoteHostId, or null if unknown
@@ -172,7 +175,7 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
/////////////////////////////////////////////////////////
public void gotDateTime(long time) {
System.out.println("Got DATE block: " + DataHelper.formatTime(time));
_timeReceived = time;
}
public void gotOptions(byte[] options, boolean isHandshake) {
@@ -270,6 +273,7 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
int off = pkt.getOffset();
int len = pkt.getLength();
byte data[] = pkt.getData();
_timeReceived = 0;
try {
// decrypt in-place
ChaChaPolyCipherState chacha = new ChaChaPolyCipherState();
@@ -284,6 +288,11 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
_log.debug("Retry error", gse);
throw gse;
}
if (_timeReceived == 0)
throw new GeneralSecurityException("No DateTime block in Session/Token Request");
long skew = _establishBegin - _timeReceived;
if (skew > MAX_SKEW || skew < 0 - MAX_SKEW)
throw new GeneralSecurityException("Skew exceeded in Session/Token Request: " + skew);
createNewState(_routerAddress);
////// TODO state change
}
@@ -317,7 +326,13 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl
}
if (_log.shouldDebug())
_log.debug("State after sess cr: " + _handshakeState);
_timeReceived = 0;
processPayload(data, off + LONG_HEADER_SIZE, len - (LONG_HEADER_SIZE + KEY_LEN + MAC_LEN), true);
if (_timeReceived == 0)
throw new GeneralSecurityException("No DateTime block in Session/Token Request");
long skew = _establishBegin - _timeReceived;
if (skew > MAX_SKEW || skew < 0 - MAX_SKEW)
throw new GeneralSecurityException("Skew exceeded in Session/Token Request: " + skew);
_sessReqForReTX = null;
_sendHeaderEncryptKey2 = SSU2Util.hkdf(_context, _handshakeState.getChainingKey(), "SessionConfirmed");