use of java.nio.channels.ReadableByteChannel in project tink by google.
the class StreamingTestUtil method testEncryptDecryptWithChannel.
/**
* Encrypts and decrypts some plaintext in a stream and checks that the expected plaintext is
* returned.
*/
private static void testEncryptDecryptWithChannel(StreamingAead ags, int firstSegmentOffset, int plaintextSize, int chunkSize) throws Exception {
byte[] aad = TestUtil.hexDecode("aabbccddeeff");
byte[] plaintext = generatePlaintext(plaintextSize);
byte[] ciphertext = encryptWithChannel(ags, plaintext, aad, firstSegmentOffset);
// Construct an InputStream from the ciphertext where the first
// firstSegmentOffset bytes have already been read.
ReadableByteChannel ctChannel = new SeekableByteBufferChannel(ciphertext).position(firstSegmentOffset);
// Construct an InputStream that returns the plaintext.
ReadableByteChannel ptChannel = ags.newDecryptingChannel(ctChannel, aad);
int decryptedSize = 0;
while (true) {
ByteBuffer chunk = ByteBuffer.allocate(chunkSize);
int read = ptChannel.read(chunk);
if (read == -1) {
break;
}
assertEquals(read, chunk.position());
byte[] expectedPlaintext = Arrays.copyOfRange(plaintext, decryptedSize, decryptedSize + read);
TestUtil.assertByteArrayEquals(expectedPlaintext, Arrays.copyOf(chunk.array(), read));
decryptedSize += read;
// ptChannel should fill chunk, unless the end of the plaintext has been reached.
if (decryptedSize < plaintextSize) {
assertEquals("Decrypted chunk is shorter than expected\n" + ptChannel.toString(), chunk.limit(), chunk.position());
}
}
assertEquals(plaintext.length, decryptedSize);
}
use of java.nio.channels.ReadableByteChannel in project tink by google.
the class StreamingTestUtil method testEncryptDecryptLong.
/**
* Encrypt and decrypt a long ciphertext.
*/
public static void testEncryptDecryptLong(StreamingAead ags, long plaintextSize) throws Exception {
byte[] aad = TestUtil.hexDecode("aabbccddeeff");
ReadableByteChannel plaintext = new PseudorandomReadableByteChannel(plaintextSize);
ReadableByteChannel copy = new PseudorandomReadableByteChannel(plaintextSize);
ReadableByteChannel ciphertext = createCiphertextChannel(ags, plaintext, aad, 1 << 20);
ReadableByteChannel decrypted = ags.newDecryptingChannel(ciphertext, aad);
byte[] chunk = new byte[1 << 15];
int read;
long decryptedBytes = 0;
do {
read = decrypted.read(ByteBuffer.wrap(chunk));
if (read > 0) {
ByteBuffer expected = ByteBuffer.allocate(read);
int unused = copy.read(expected);
decryptedBytes += read;
TestUtil.assertByteArrayEquals(expected.array(), Arrays.copyOf(chunk, read));
}
} while (read != -1);
assertEquals(plaintextSize, decryptedBytes);
}
use of java.nio.channels.ReadableByteChannel in project tink by google.
the class StreamingAeadThreadSafetyTest method testEncryption.
/**
* Test for thread safety. This test is an incorrect use case for StreamingAead implementations.
* Streams have state and hence their behaviour is not well defined. Nevertheless if an encrypting
* channel is used concurrently we expect the following behaviour: (1) The resulting ciphertext
* has valid format. (2) All plaintext is encrypted. (3) The thread sanitizer does not find
* anything.
*/
public void testEncryption(StreamingAead stream, byte[] aad, int chunkSize, int numberOfChunks) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
WritableByteChannel encChannel = stream.newEncryptingChannel(Channels.newChannel(bos), aad);
int numberOfThreads = 10;
Thread[] thread = new Thread[numberOfThreads];
ExceptionHandler exceptionHandler = new ExceptionHandler();
for (int i = 0; i < numberOfThreads; i++) {
thread[i] = new EncryptingThread(encChannel, chunkSize, numberOfChunks, (byte) i);
thread[i].setUncaughtExceptionHandler(exceptionHandler);
}
for (int i = 0; i < numberOfThreads; i++) {
thread[i].start();
}
for (int i = 0; i < numberOfThreads; i++) {
thread[i].join();
}
exceptionHandler.check();
encChannel.close();
byte[] ciphertext = bos.toByteArray();
ReadableByteChannel ctChannel = new ByteBufferChannel(ciphertext);
ReadableByteChannel ptChannel = stream.newDecryptingChannel(ctChannel, aad);
ByteBuffer decrypted = ByteBuffer.allocate(numberOfThreads * chunkSize * numberOfChunks + 1);
ptChannel.read(decrypted);
// Test whether the writing the chunks was done in an atomic manner.
byte[] plaintext = decrypted.array();
for (int i = 0; i < numberOfThreads * numberOfChunks; i++) {
for (int j = 0; j < chunkSize - 1; j++) {
int idx = i * chunkSize + j;
if (plaintext[idx] != plaintext[idx + 1]) {
int thread1 = plaintext[idx] & 0xff;
int thread2 = plaintext[idx + 1] & 0xff;
fail("Chunk " + i + " contains bytes from thread " + thread1 + " and " + thread2 + ".");
}
}
}
}
use of java.nio.channels.ReadableByteChannel in project tink by google.
the class RewindableReadableByteChannelTest method testDisableRewind.
@Test
public void testDisableRewind() throws Exception {
int blockSize = PseudorandomReadableByteChannel.BLOCK_SIZE;
int extraSize = 123;
int blockCount = 5;
int inputSize = blockSize * blockCount + extraSize;
ReadableByteChannel baseChannel = new PseudorandomReadableByteChannel(inputSize);
assertTrue(baseChannel.isOpen());
RewindableReadableByteChannel rewindableChannel = new RewindableReadableByteChannel(baseChannel);
assertTrue(rewindableChannel.isOpen());
// Read two blocks.
ByteBuffer twoBlocksBuffer = ByteBuffer.allocate(2 * blockSize);
assertEquals(2 * blockSize, rewindableChannel.read(twoBlocksBuffer));
// Verify that the read bytes are not all the same.
assertFalse(Arrays.equals(Arrays.copyOfRange(twoBlocksBuffer.array(), 0, 42), Arrays.copyOfRange(twoBlocksBuffer.array(), 42, 2 * 42)));
// Rewind and read 1 block + extraSize;
rewindableChannel.rewind();
ByteBuffer blockAndExtraBuffer = ByteBuffer.allocate(blockSize + extraSize);
assertEquals(blockSize + extraSize, rewindableChannel.read(blockAndExtraBuffer));
assertArrayEquals(blockAndExtraBuffer.array(), Arrays.copyOfRange(twoBlocksBuffer.array(), 0, blockSize + extraSize));
// Disable the rewinding feature, and continue reading.
rewindableChannel.disableRewinding();
try {
rewindableChannel.rewind();
fail("Should have thrown exception, as rewinding has been dropped");
} catch (IOException expected) {
assertExceptionContains(expected, "Cannot rewind");
}
ByteBuffer oneBlockBuffer = ByteBuffer.allocate(blockSize);
assertEquals(blockSize, rewindableChannel.read(oneBlockBuffer));
assertArrayEquals(oneBlockBuffer.array(), Arrays.copyOfRange(twoBlocksBuffer.array(), extraSize, blockSize + extraSize));
int remainingSize = (blockCount - 2) * blockSize;
ByteBuffer remainingBuffer = ByteBuffer.allocate(remainingSize);
assertEquals(remainingSize, rewindableChannel.read(remainingBuffer));
assertArrayEquals(blockAndExtraBuffer.array(), Arrays.copyOfRange(remainingBuffer.array(), remainingSize - blockSize - extraSize, remainingSize));
// Check EOF.
ByteBuffer buffer = ByteBuffer.allocate(42);
assertEquals(-1, rewindableChannel.read(buffer));
// Close the channel.
rewindableChannel.close();
assertFalse(rewindableChannel.isOpen());
assertFalse(baseChannel.isOpen());
}
use of java.nio.channels.ReadableByteChannel in project rubix by qubole.
the class NonLocalReadRequestChain method call.
@Override
public Integer call() throws Exception {
Thread.currentThread().setName(threadName);
if (readRequests.size() == 0) {
return 0;
}
checkState(isLocked, "Trying to execute Chain without locking");
for (ReadRequest readRequest : readRequests) {
if (cancelled) {
propagateCancel(this.getClass().getName());
}
SocketChannel dataTransferClient;
try {
dataTransferClient = DataTransferClientHelper.createDataTransferClient(remoteNodeName, conf);
} catch (Exception e) {
log.warn("Could not create Data Transfer Client ", e);
if (strictMode) {
throw Throwables.propagate(e);
} else {
return directReadRequest(readRequests.indexOf(readRequest));
}
}
try {
int nread = 0;
/*
SocketChannels does not support timeouts when used directly, because timeout is used only by streams.
We get this working by wrapping it in ReadableByteChannel.
Ref - https://technfun.wordpress.com/2009/01/29/networking-in-java-non-blocking-nio-blocking-nio-and-io/
*/
InputStream inStream = dataTransferClient.socket().getInputStream();
ReadableByteChannel wrappedChannel = Channels.newChannel(inStream);
ByteBuffer buf = DataTransferClientHelper.writeHeaders(conf, new DataTransferHeader(readRequest.getActualReadStart(), readRequest.getActualReadLength(), fileSize, lastModified, clusterType, filePath));
dataTransferClient.write(buf);
int bytesread = 0;
ByteBuffer dst = ByteBuffer.wrap(readRequest.destBuffer, readRequest.getDestBufferOffset(), readRequest.destBuffer.length - readRequest.getDestBufferOffset());
while (bytesread != readRequest.getActualReadLength()) {
nread = wrappedChannel.read(dst);
bytesread += nread;
totalRead += nread;
if (nread == -1) {
totalRead -= bytesread;
throw new Exception("Error reading from Local Transfer Server");
}
dst.position(bytesread + readRequest.getDestBufferOffset());
}
} catch (SocketTimeoutException e) {
if (strictMode) {
log.error(remoteNodeName + ": socket read timed out.");
throw Throwables.propagate(e);
} else {
log.info(remoteNodeName + ": socket read timed out. Using direct reads");
return directReadRequest(readRequests.indexOf(readRequest));
}
} catch (Exception e) {
log.info("Error reading data from node : " + remoteNodeName, e);
if (strictMode) {
throw Throwables.propagate(e);
} else {
return directReadRequest(readRequests.indexOf(readRequest));
}
} finally {
if (statistics != null) {
statistics.incrementBytesRead(totalRead);
}
try {
log.info(String.format("Read %d bytes internally from node %s", totalRead, remoteNodeName));
dataTransferClient.close();
} catch (IOException e) {
log.info("Error closing Data Transfer client : " + remoteNodeName, e);
}
}
}
return totalRead;
}
Aggregations