Commit c4da1073 authored by R.W.Majeed's avatar R.W.Majeed

fixed decryption errors in DecryptingInputStream

parent 42048ee9
......@@ -28,7 +28,6 @@ public class DecryptingInputStream extends InputStream {
// use buffer
endOfStream = false;
byte[] buf = new byte[1024*8];
outputBuffer = ByteBuffer.allocate(1024*8).compact();
int read = in.read(buf);
buffer = ByteBuffer.wrap(buf, 0, read);
int version = buffer.getInt();
......@@ -36,7 +35,6 @@ public class DecryptingInputStream extends InputStream {
if( version != EncryptingByteChannel.Version )throw new IOException("Unsupported MDAT stream version "+version);
byte[] wrapped = new byte[ks];
buffer.get(wrapped);
buffer.compact();
Cipher unwrap;
try {
......@@ -48,6 +46,13 @@ public class DecryptingInputStream extends InputStream {
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
throw new IOException("Unable to unwrap symmetric key",e);
}
// decrypt remaining buffer
outputBuffer = ByteBuffer.allocate(1024*8);
cipher.update(buffer, outputBuffer);
// prepare buffer for writing
buffer.compact();
// prepare decrypted buffer for reading
outputBuffer.flip();
this.in = in;
}
......@@ -62,14 +67,29 @@ public class DecryptingInputStream extends InputStream {
private int readAndDecrypt() throws IOException{
int bytesRead=0;
if( buffer.hasRemaining() ){
bytesRead = in.read(buffer.array(),buffer.position(),buffer.remaining());
// space available for reading data
int pos = buffer.position();
bytesRead = in.read(buffer.array(),buffer.arrayOffset()+pos,buffer.remaining());
// got some bytes?
if( bytesRead == -1 ){
// no more data
endOfStream = true;
}else{
// update position
buffer.position(pos+bytesRead);
}
}
outputBuffer.compact();
buffer.flip();
try {
if( bytesRead == -1 ){
endOfStream = true;
bytesRead = cipher.doFinal(buffer, outputBuffer);
if( endOfStream == true ){
if( buffer.hasRemaining() ){
bytesRead = cipher.doFinal(buffer, outputBuffer);
}else{
byte[] fin = cipher.doFinal();
outputBuffer.put(fin);
bytesRead = fin.length;
}
}else{
bytesRead = cipher.update(buffer, outputBuffer);
}
......@@ -107,7 +127,7 @@ public class DecryptingInputStream extends InputStream {
// if empty, fill output buffer
readAndDecrypt();
return read(b);
return read(b, off, len);
}
@Override
public int available() throws IOException {
......
package de.sekmi.histream.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Supplier;
......@@ -75,4 +81,38 @@ public class Streams {
return Spliterator.NONNULL | Spliterator.IMMUTABLE;
}
}
public static long channelCopy(final ReadableByteChannel src, final WritableByteChannel dest)
throws IOException {
long count = 0;
final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
while (src.read(buffer) != -1) {
// prepare the buffer to be drained
buffer.flip();
// write to the channel, may block
count += dest.write(buffer);
// If partial transfer, shift remainder down
// If buffer is empty, same as doing clear()
buffer.compact();
}
// EOF will leave buffer in fill state
buffer.flip();
// make sure the buffer is fully drained.
while (buffer.hasRemaining()) {
count += dest.write(buffer);
}
return count;
}
public static long streamCopy(InputStream in, OutputStream out) throws IOException{
byte[] buffer = new byte[1024]; // Adjust if you want
long total = 0;
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
total += bytesRead;
}
return total;
}
}
......@@ -20,6 +20,8 @@ import java.security.SecureRandom;
import org.junit.Before;
import org.junit.Test;
import de.sekmi.histream.io.Streams;
import org.junit.Assert;
public class TestEncryptDecrypt {
......@@ -96,13 +98,6 @@ public class TestEncryptDecrypt {
Files.delete(dec);
}
public static void transfer(InputStream in, OutputStream out) throws IOException{
byte[] buffer = new byte[1024]; // Adjust if you want
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
@Test
public void testEncryptDecryptStreams() throws GeneralSecurityException, IOException{
......@@ -115,7 +110,7 @@ public class TestEncryptDecrypt {
OutputStream enc = new EncryptingOutputStream(out, keyPair.getPublic());
InputStream in = Files.newInputStream(source);
transfer(in, enc);
Streams.streamCopy(in, enc);
in.close();
enc.close();
......@@ -125,7 +120,7 @@ public class TestEncryptDecrypt {
in = Files.newInputStream(temp, StandardOpenOption.READ);
InputStream decrypted = new DecryptingInputStream(in, keyPair.getPrivate());
out = Files.newOutputStream(dec, StandardOpenOption.WRITE);
transfer(decrypted, out);
Streams.streamCopy(decrypted, out);
in.close();
out.close();
decrypted.close();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment