mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 04:39:54 +01:00
Distinguish between recoverable and unrecoverable errors.
This commit is contained in:
@@ -2,8 +2,8 @@ package net.sf.briar.api;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/** An exception that indicates an unrecoverable formatting error. */
|
||||||
public class FormatException extends IOException {
|
public class FormatException extends IOException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 2274966775687766337L;
|
private static final long serialVersionUID = 2274966775687766337L;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
|
|||||||
// No error correction
|
// No error correction
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
// Create the reader
|
// Create the reader - don't tolerate errors
|
||||||
Mac mac = crypto.getMac();
|
Mac mac = crypto.getMac();
|
||||||
return new ConnectionReaderImpl(correcter, mac, macKey);
|
return new ConnectionReaderImpl(correcter, mac, macKey, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectionReader createConnectionReader(SegmentSource in,
|
public ConnectionReader createConnectionReader(SegmentSource in,
|
||||||
@@ -80,8 +80,8 @@ class ConnectionReaderFactoryImpl implements ConnectionReaderFactory {
|
|||||||
// No error correction
|
// No error correction
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
// Create the reader
|
// Create the reader - don't tolerate errors
|
||||||
Mac mac = crypto.getMac();
|
Mac mac = crypto.getMac();
|
||||||
return new ConnectionReaderImpl(correcter, mac, macKey);
|
return new ConnectionReaderImpl(correcter, mac, macKey, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,15 +20,17 @@ class ConnectionReaderImpl extends InputStream implements ConnectionReader {
|
|||||||
|
|
||||||
private final IncomingErrorCorrectionLayer in;
|
private final IncomingErrorCorrectionLayer in;
|
||||||
private final Mac mac;
|
private final Mac mac;
|
||||||
|
private final boolean tolerateErrors;
|
||||||
private final Frame frame;
|
private final Frame frame;
|
||||||
|
|
||||||
private long frameNumber = 0L;
|
private long frameNumber = 0L;
|
||||||
private int offset = 0, length = 0;
|
private int offset = 0, length = 0;
|
||||||
|
|
||||||
ConnectionReaderImpl(IncomingErrorCorrectionLayer in, Mac mac,
|
ConnectionReaderImpl(IncomingErrorCorrectionLayer in, Mac mac,
|
||||||
ErasableKey macKey) {
|
ErasableKey macKey, boolean tolerateErrors) {
|
||||||
this.in = in;
|
this.in = in;
|
||||||
this.mac = mac;
|
this.mac = mac;
|
||||||
|
this.tolerateErrors = tolerateErrors;
|
||||||
// Initialise the MAC
|
// Initialise the MAC
|
||||||
try {
|
try {
|
||||||
mac.init(macKey);
|
mac.init(macKey);
|
||||||
@@ -47,7 +49,7 @@ class ConnectionReaderImpl extends InputStream implements ConnectionReader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
while(length == 0) if(!readFrame()) return -1;
|
while(length == 0) if(!readValidFrame()) return -1;
|
||||||
int b = frame.getBuffer()[offset] & 0xff;
|
int b = frame.getBuffer()[offset] & 0xff;
|
||||||
offset++;
|
offset++;
|
||||||
length--;
|
length--;
|
||||||
@@ -61,7 +63,7 @@ class ConnectionReaderImpl extends InputStream implements ConnectionReader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] b, int off, int len) throws IOException {
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
while(length == 0) if(!readFrame()) return -1;
|
while(length == 0) if(!readValidFrame()) return -1;
|
||||||
len = Math.min(len, length);
|
len = Math.min(len, length);
|
||||||
System.arraycopy(frame.getBuffer(), offset, b, off, len);
|
System.arraycopy(frame.getBuffer(), offset, b, off, len);
|
||||||
offset += len;
|
offset += len;
|
||||||
@@ -69,33 +71,46 @@ class ConnectionReaderImpl extends InputStream implements ConnectionReader {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean readFrame() throws IOException {
|
private boolean readValidFrame() throws IOException {
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
return readFrame();
|
||||||
|
} catch(InvalidDataException e) {
|
||||||
|
if(tolerateErrors) continue;
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean readFrame() throws IOException, InvalidDataException {
|
||||||
assert length == 0;
|
assert length == 0;
|
||||||
// Don't allow more than 2^32 frames to be read
|
// Don't allow more than 2^32 frames to be read
|
||||||
if(frameNumber > MAX_32_BIT_UNSIGNED) throw new IllegalStateException();
|
if(frameNumber > MAX_32_BIT_UNSIGNED)
|
||||||
|
throw new IllegalStateException();
|
||||||
// Read a frame
|
// Read a frame
|
||||||
Collection<Long> window = Collections.singleton(frameNumber);
|
Collection<Long> window = Collections.singleton(frameNumber);
|
||||||
if(!in.readFrame(frame, window)) return false;
|
if(!in.readFrame(frame, window)) return false;
|
||||||
// Check that the frame number is correct and the length is legal
|
// Check that the frame number is correct and the length is legal
|
||||||
byte[] buf = frame.getBuffer();
|
byte[] buf = frame.getBuffer();
|
||||||
if(!HeaderEncoder.validateHeader(buf, frameNumber))
|
if(!HeaderEncoder.validateHeader(buf, frameNumber))
|
||||||
throw new FormatException();
|
throw new InvalidDataException();
|
||||||
// Check that the payload and padding lengths are correct
|
// Check that the payload and padding lengths are correct
|
||||||
int payload = HeaderEncoder.getPayloadLength(buf);
|
int payload = HeaderEncoder.getPayloadLength(buf);
|
||||||
int padding = HeaderEncoder.getPaddingLength(buf);
|
int padding = HeaderEncoder.getPaddingLength(buf);
|
||||||
if(frame.getLength() != FRAME_HEADER_LENGTH + payload + padding
|
if(frame.getLength() != FRAME_HEADER_LENGTH + payload + padding
|
||||||
+ MAC_LENGTH) throw new FormatException();
|
+ MAC_LENGTH) throw new InvalidDataException();
|
||||||
// Check that the padding is all zeroes
|
// Check that the padding is all zeroes
|
||||||
int paddingStart = FRAME_HEADER_LENGTH + payload;
|
int paddingStart = FRAME_HEADER_LENGTH + payload;
|
||||||
for(int i = paddingStart; i < paddingStart + padding; i++) {
|
for(int i = paddingStart; i < paddingStart + padding; i++) {
|
||||||
if(buf[i] != 0) throw new FormatException();
|
if(buf[i] != 0) throw new InvalidDataException();
|
||||||
}
|
}
|
||||||
// Check the MAC
|
// Check the MAC
|
||||||
int macStart = FRAME_HEADER_LENGTH + payload + padding;
|
int macStart = FRAME_HEADER_LENGTH + payload + padding;
|
||||||
mac.update(buf, 0, macStart);
|
mac.update(buf, 0, macStart);
|
||||||
byte[] expectedMac = mac.doFinal();
|
byte[] expectedMac = mac.doFinal();
|
||||||
for(int i = 0; i < expectedMac.length; i++) {
|
for(int i = 0; i < expectedMac.length; i++) {
|
||||||
if(expectedMac[i] != buf[macStart + i]) throw new FormatException();
|
if(expectedMac[i] != buf[macStart + i])
|
||||||
|
throw new InvalidDataException();
|
||||||
}
|
}
|
||||||
offset = FRAME_HEADER_LENGTH;
|
offset = FRAME_HEADER_LENGTH;
|
||||||
length = payload;
|
length = payload;
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ interface IncomingEncryptionLayer {
|
|||||||
/**
|
/**
|
||||||
* Reads a segment, excluding its tag, into the given buffer. Returns false
|
* Reads a segment, excluding its tag, into the given buffer. Returns false
|
||||||
* if no more segments can be read from the connection.
|
* if no more segments can be read from the connection.
|
||||||
|
* @throws IOException if an unrecoverable error occurs and the connection
|
||||||
|
* must be closed.
|
||||||
|
* @throws InvalidDataException if a recoverable error occurs. The caller
|
||||||
|
* may choose whether to retry the read or close the connection.
|
||||||
*/
|
*/
|
||||||
boolean readSegment(Segment s) throws IOException;
|
boolean readSegment(Segment s) throws IOException, InvalidDataException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ interface IncomingErrorCorrectionLayer {
|
|||||||
* Reads a frame into the given buffer. The frame number must be contained
|
* Reads a frame into the given buffer. The frame number must be contained
|
||||||
* in the given window. Returns false if no more frames can be read from
|
* in the given window. Returns false if no more frames can be read from
|
||||||
* the connection.
|
* the connection.
|
||||||
|
* @throws IOException if an unrecoverable error occurs and the connection
|
||||||
|
* must be closed.
|
||||||
|
* @throws InvalidDataException if a recoverable error occurs. The caller
|
||||||
|
* may choose whether to retry the read or close the connection.
|
||||||
*/
|
*/
|
||||||
boolean readFrame(Frame f, Collection<Long> window) throws IOException;
|
boolean readFrame(Frame f, Collection<Long> window) throws IOException,
|
||||||
|
InvalidDataException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import java.security.GeneralSecurityException;
|
|||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
|
||||||
import net.sf.briar.api.FormatException;
|
|
||||||
import net.sf.briar.api.crypto.ErasableKey;
|
import net.sf.briar.api.crypto.ErasableKey;
|
||||||
import net.sf.briar.api.plugins.SegmentSource;
|
import net.sf.briar.api.plugins.SegmentSource;
|
||||||
import net.sf.briar.api.transport.Segment;
|
import net.sf.briar.api.transport.Segment;
|
||||||
@@ -32,22 +31,23 @@ class IncomingSegmentedEncryptionLayer implements IncomingEncryptionLayer {
|
|||||||
|
|
||||||
IncomingSegmentedEncryptionLayer(SegmentSource in, Cipher tagCipher,
|
IncomingSegmentedEncryptionLayer(SegmentSource in, Cipher tagCipher,
|
||||||
Cipher segCipher, ErasableKey tagKey, ErasableKey segKey,
|
Cipher segCipher, ErasableKey tagKey, ErasableKey segKey,
|
||||||
boolean tagEverySegment, Segment s) {
|
boolean tagEverySegment, Segment bufferedSegment) {
|
||||||
this.in = in;
|
this.in = in;
|
||||||
this.tagCipher = tagCipher;
|
this.tagCipher = tagCipher;
|
||||||
this.segCipher = segCipher;
|
this.segCipher = segCipher;
|
||||||
this.tagKey = tagKey;
|
this.tagKey = tagKey;
|
||||||
this.segKey = segKey;
|
this.segKey = segKey;
|
||||||
this.tagEverySegment = tagEverySegment;
|
this.tagEverySegment = tagEverySegment;
|
||||||
|
this.bufferedSegment = bufferedSegment;
|
||||||
blockSize = segCipher.getBlockSize();
|
blockSize = segCipher.getBlockSize();
|
||||||
if(blockSize < FRAME_HEADER_LENGTH)
|
if(blockSize < FRAME_HEADER_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
iv = IvEncoder.encodeIv(0L, blockSize);
|
iv = IvEncoder.encodeIv(0L, blockSize);
|
||||||
segment = new SegmentImpl();
|
segment = new SegmentImpl();
|
||||||
bufferedSegment = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean readSegment(Segment s) throws IOException {
|
public boolean readSegment(Segment s) throws IOException,
|
||||||
|
InvalidDataException {
|
||||||
boolean expectTag = tagEverySegment || firstSegment;
|
boolean expectTag = tagEverySegment || firstSegment;
|
||||||
firstSegment = false;
|
firstSegment = false;
|
||||||
try {
|
try {
|
||||||
@@ -62,14 +62,14 @@ class IncomingSegmentedEncryptionLayer implements IncomingEncryptionLayer {
|
|||||||
}
|
}
|
||||||
int offset = expectTag ? TAG_LENGTH : 0;
|
int offset = expectTag ? TAG_LENGTH : 0;
|
||||||
int length = segment.getLength();
|
int length = segment.getLength();
|
||||||
if(length > MAX_SEGMENT_LENGTH) throw new FormatException();
|
if(length > MAX_SEGMENT_LENGTH) throw new InvalidDataException();
|
||||||
if(length < offset + FRAME_HEADER_LENGTH + MAC_LENGTH)
|
if(length < offset + FRAME_HEADER_LENGTH + MAC_LENGTH)
|
||||||
throw new FormatException();
|
throw new InvalidDataException();
|
||||||
byte[] ciphertext = segment.getBuffer();
|
byte[] ciphertext = segment.getBuffer();
|
||||||
// If a tag is expected then decrypt and validate it
|
// If a tag is expected then decrypt and validate it
|
||||||
if(expectTag) {
|
if(expectTag) {
|
||||||
long seg = TagEncoder.decodeTag(ciphertext, tagCipher, tagKey);
|
long seg = TagEncoder.decodeTag(ciphertext, tagCipher, tagKey);
|
||||||
if(seg == -1) throw new FormatException();
|
if(seg == -1) throw new InvalidDataException();
|
||||||
segmentNumber = seg;
|
segmentNumber = seg;
|
||||||
}
|
}
|
||||||
// Decrypt the segment
|
// Decrypt the segment
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package net.sf.briar.transport;
|
||||||
|
|
||||||
|
/** An exception that indicates a recoverable formatting error. */
|
||||||
|
class InvalidDataException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4455775710413826953L;
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ class NullIncomingErrorCorrectionLayer implements IncomingErrorCorrectionLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean readFrame(Frame f, Collection<Long> window)
|
public boolean readFrame(Frame f, Collection<Long> window)
|
||||||
throws IOException {
|
throws IOException, InvalidDataException {
|
||||||
while(true) {
|
while(true) {
|
||||||
if(!in.readSegment(segment)) return false;
|
if(!in.readSegment(segment)) return false;
|
||||||
byte[] buf = segment.getBuffer();
|
byte[] buf = segment.getBuffer();
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
// There should be no bytes available before EOF
|
// There should be no bytes available before EOF
|
||||||
assertEquals(-1, r.getInputStream().read());
|
assertEquals(-1, r.getInputStream().read());
|
||||||
}
|
}
|
||||||
@@ -55,7 +56,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
// There should be one byte available before EOF
|
// There should be one byte available before EOF
|
||||||
assertEquals(0, r.getInputStream().read());
|
assertEquals(0, r.getInputStream().read());
|
||||||
assertEquals(-1, r.getInputStream().read());
|
assertEquals(-1, r.getInputStream().read());
|
||||||
@@ -83,7 +85,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
byte[] read = new byte[MAX_PAYLOAD_LENGTH];
|
byte[] read = new byte[MAX_PAYLOAD_LENGTH];
|
||||||
TestUtils.readFully(r.getInputStream(), read);
|
TestUtils.readFully(r.getInputStream(), read);
|
||||||
// Try to read the second frame
|
// Try to read the second frame
|
||||||
@@ -119,7 +122,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
byte[] read = new byte[MAX_PAYLOAD_LENGTH - paddingLength];
|
byte[] read = new byte[MAX_PAYLOAD_LENGTH - paddingLength];
|
||||||
TestUtils.readFully(r.getInputStream(), read);
|
TestUtils.readFully(r.getInputStream(), read);
|
||||||
// Try to read the second frame
|
// Try to read the second frame
|
||||||
@@ -147,7 +151,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
// The non-zero padding should be rejected
|
// The non-zero padding should be rejected
|
||||||
try {
|
try {
|
||||||
r.getInputStream().read();
|
r.getInputStream().read();
|
||||||
@@ -181,7 +186,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
byte[] read = new byte[payloadLength];
|
byte[] read = new byte[payloadLength];
|
||||||
TestUtils.readFully(r.getInputStream(), read);
|
TestUtils.readFully(r.getInputStream(), read);
|
||||||
assertArrayEquals(new byte[payloadLength], read);
|
assertArrayEquals(new byte[payloadLength], read);
|
||||||
@@ -207,7 +213,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
try {
|
try {
|
||||||
r.getInputStream().read();
|
r.getInputStream().read();
|
||||||
fail();
|
fail();
|
||||||
@@ -231,7 +238,8 @@ public class ConnectionReaderImplTest extends TransportTest {
|
|||||||
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
IncomingEncryptionLayer decrypter = new NullIncomingEncryptionLayer(in);
|
||||||
IncomingErrorCorrectionLayer correcter =
|
IncomingErrorCorrectionLayer correcter =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey);
|
ConnectionReader r = new ConnectionReaderImpl(correcter, mac, macKey,
|
||||||
|
false);
|
||||||
try {
|
try {
|
||||||
r.getInputStream().read();
|
r.getInputStream().read();
|
||||||
fail();
|
fail();
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class FrameReadWriteTest extends BriarTestCase {
|
|||||||
IncomingErrorCorrectionLayer correcter1 =
|
IncomingErrorCorrectionLayer correcter1 =
|
||||||
new NullIncomingErrorCorrectionLayer(decrypter);
|
new NullIncomingErrorCorrectionLayer(decrypter);
|
||||||
ConnectionReader reader = new ConnectionReaderImpl(correcter1, mac,
|
ConnectionReader reader = new ConnectionReaderImpl(correcter1, mac,
|
||||||
macKey);
|
macKey, false);
|
||||||
InputStream in1 = reader.getInputStream();
|
InputStream in1 = reader.getInputStream();
|
||||||
byte[] recovered = new byte[frame.length];
|
byte[] recovered = new byte[frame.length];
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class NullIncomingEncryptionLayer implements IncomingEncryptionLayer {
|
|||||||
int padding = HeaderEncoder.getPaddingLength(buf);
|
int padding = HeaderEncoder.getPaddingLength(buf);
|
||||||
length = FRAME_HEADER_LENGTH + payload + padding + MAC_LENGTH;
|
length = FRAME_HEADER_LENGTH + payload + padding + MAC_LENGTH;
|
||||||
if(length > MAX_FRAME_LENGTH) throw new FormatException();
|
if(length > MAX_FRAME_LENGTH) throw new FormatException();
|
||||||
// Read the remainder of the frame/segment
|
// Read the remainder of the frame
|
||||||
while(offset < length) {
|
while(offset < length) {
|
||||||
int read = in.read(buf, offset, length - offset);
|
int read = in.read(buf, offset, length - offset);
|
||||||
if(read == -1) throw new EOFException();
|
if(read == -1) throw new EOFException();
|
||||||
|
|||||||
Reference in New Issue
Block a user