Search in sources :

Example 66 with ReadableByteChannel

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);
}
Also used : ReadableByteChannel(java.nio.channels.ReadableByteChannel) ByteBuffer(java.nio.ByteBuffer)

Example 67 with ReadableByteChannel

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);
}
Also used : ReadableByteChannel(java.nio.channels.ReadableByteChannel) ByteBuffer(java.nio.ByteBuffer)

Example 68 with ReadableByteChannel

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 + ".");
            }
        }
    }
}
Also used : ReadableByteChannel(java.nio.channels.ReadableByteChannel) ByteBufferChannel(com.google.crypto.tink.StreamingTestUtil.ByteBufferChannel) SeekableByteBufferChannel(com.google.crypto.tink.StreamingTestUtil.SeekableByteBufferChannel) WritableByteChannel(java.nio.channels.WritableByteChannel) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ByteBuffer(java.nio.ByteBuffer)

Example 69 with ReadableByteChannel

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());
}
Also used : ReadableByteChannel(java.nio.channels.ReadableByteChannel) PseudorandomReadableByteChannel(com.google.crypto.tink.StreamingTestUtil.PseudorandomReadableByteChannel) PseudorandomReadableByteChannel(com.google.crypto.tink.StreamingTestUtil.PseudorandomReadableByteChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 70 with ReadableByteChannel

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;
}
Also used : SocketChannel(java.nio.channels.SocketChannel) ReadableByteChannel(java.nio.channels.ReadableByteChannel) SocketTimeoutException(java.net.SocketTimeoutException) FSDataInputStream(org.apache.hadoop.fs.FSDataInputStream) InputStream(java.io.InputStream) DataTransferHeader(com.qubole.rubix.spi.DataTransferHeader) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) IOException(java.io.IOException) SocketTimeoutException(java.net.SocketTimeoutException)

Aggregations

ReadableByteChannel (java.nio.channels.ReadableByteChannel)307 ByteBuffer (java.nio.ByteBuffer)111 IOException (java.io.IOException)84 FileOutputStream (java.io.FileOutputStream)62 WritableByteChannel (java.nio.channels.WritableByteChannel)62 Test (org.junit.Test)52 File (java.io.File)50 FileChannel (java.nio.channels.FileChannel)49 FileInputStream (java.io.FileInputStream)43 ByteArrayInputStream (java.io.ByteArrayInputStream)38 InputStream (java.io.InputStream)36 URL (java.net.URL)35 ByteArrayOutputStream (java.io.ByteArrayOutputStream)21 Path (java.nio.file.Path)18 Test (org.testng.annotations.Test)14 FileNotFoundException (java.io.FileNotFoundException)13 ArrayList (java.util.ArrayList)12 DbusEventGenerator (com.linkedin.databus.core.test.DbusEventGenerator)11 MalformedURLException (java.net.MalformedURLException)11 Vector (java.util.Vector)11