Skip to content

Commit

Permalink
Added mutable max buffer size for Encryptor and Decryptor
Browse files Browse the repository at this point in the history
  • Loading branch information
Álvaro Morillas committed Mar 8, 2018
1 parent 078d521 commit dd63974
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 28 deletions.
18 changes: 8 additions & 10 deletions src/main/java/org/c02e/jpgpj/Decryptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.bouncycastle.bcpg.ArmoredOutputStream;

import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPDataValidationException;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
Expand Down Expand Up @@ -71,7 +70,7 @@
public class Decryptor {
protected boolean verificationRequired;
protected String symmetricPassphrase;
protected int maxBufferSize = 0x100000; //1MB
protected int maxFileBufferSize = 0x100000; //1MB
protected Ring ring;
protected Logger log = LoggerFactory.getLogger(Decryptor.class.getName());

Expand Down Expand Up @@ -119,17 +118,16 @@ public void setSymmetricPassphrase(String x) {
symmetricPassphrase = x != null ? x : "";
}

public int getMaxBufferSize() {
return maxBufferSize;
public int getMaxFileBufferSize() {
return maxFileBufferSize;
}

/**
* Decryptor will choose the most appropriate read/write buffer size
* for each file. You can set the maximum value here and it must be
* power of 2. Defaults to 1MB.
* for each file. You can set the maximum value here. Defaults to 1MB.
*/
public void setMaxBufferSize(int maxBufferSize) {
this.maxBufferSize = maxBufferSize;
public void setMaxFileBufferSize(int maxFileBufferSize) {
this.maxFileBufferSize = maxFileBufferSize;
}

/** Keys to use for decryption and verification. */
Expand Down Expand Up @@ -178,7 +176,7 @@ public FileMetadata decrypt(File ciphertext, File plaintext)
OutputStream output = null;
try {
int bestBufferSize =
Util.bestBufferSize(plaintext.length(), maxBufferSize);
Util.bestFileBufferSize(ciphertext.length(), maxFileBufferSize);
input = new BufferedInputStream(
new FileInputStream(ciphertext), bestBufferSize);
output = new BufferedOutputStream(
Expand Down
38 changes: 27 additions & 11 deletions src/main/java/org/c02e/jpgpj/Encryptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.util.Date;
import java.util.List;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.BCPGOutputStream;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
Expand All @@ -23,13 +22,13 @@
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator;
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.util.Strings;
import org.c02e.jpgpj.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -79,7 +78,7 @@ public class Encryptor {
protected HashingAlgorithm keyDerivationAlgorithm;
protected int keyDerivationWorkFactor;

protected int maxBufferSize = 0x100000; //1MB
protected int maxFileBufferSize = 0x100000; //1MB

protected Ring ring;
protected Logger log = LoggerFactory.getLogger(Encryptor.class.getName());
Expand Down Expand Up @@ -227,17 +226,17 @@ public void setKeyDeriviationWorkFactor(int x) {
keyDerivationWorkFactor = x;
}

public int getMaxBufferSize() {
return maxBufferSize;
public int getMaxFileBufferSize() {
return maxFileBufferSize;
}

/**
* Encryptor will choose the most appropriate read/write buffer size
* for each file. You can set the maximum value here and it must be
* power of 2. Defaults to 1MB.
*/
public void setMaxBufferSize(int maxBufferSize) {
this.maxBufferSize = maxBufferSize;
public void setMaxFileBufferSize(int maxFileBufferSize) {
this.maxFileBufferSize = maxFileBufferSize;
}

/** Keys to use for encryption and signing. */
Expand Down Expand Up @@ -281,12 +280,13 @@ public void encrypt(File plaintext, File ciphertext)
InputStream input = null;
OutputStream output = null;
try {
int bestBufferSize =
Util.bestBufferSize(plaintext.length(), maxBufferSize);
int bestFileBufferSize =
Util.bestFileBufferSize(plaintext.length(), maxFileBufferSize);
input = new BufferedInputStream(
new FileInputStream(plaintext), bestBufferSize);
new FileInputStream(plaintext), bestFileBufferSize);
output = new BufferedOutputStream(
new FileOutputStream(ciphertext), bestBufferSize);
new FileOutputStream(ciphertext),
estimateOutFileSize(plaintext.length()));
encrypt(input, output, new FileMetadata(plaintext));
} catch (Exception e) {
// delete output file if anything went wrong
Expand Down Expand Up @@ -601,6 +601,22 @@ protected int bestPacketSize(FileMetadata meta) {
return len;
}

private int estimateOutFileSize(long inFileSize) {
if (inFileSize > Integer.MAX_VALUE) return maxFileBufferSize;
else {
long outFileSize = inFileSize;
outFileSize += (1 + getRing().getEncryptionKeys().size() +
getRing().getSigningKeys().size()) * 512;
if (isAsciiArmored()) {
outFileSize *= (4 / 3) *
((64 + Strings.lineSeparator().length()) / 64);
outFileSize += 80;
}
return (outFileSize >= maxFileBufferSize) ?
maxFileBufferSize : Math.toIntExact(outFileSize);
}
}

protected class SigningOutputStream extends FilterOutputStream {
protected FileMetadata meta;
protected List<PGPSignatureGenerator> sigs;
Expand Down
12 changes: 5 additions & 7 deletions src/main/java/org/c02e/jpgpj/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,12 @@ public static String formatAsHex(byte[] bytes) {
}

/**
* Returns the fileSize rounded up to exact power of 2 with a maximum
* of maxBufferSize (which should be power of 2).
* Returns the exact fileSize with a maximum of maxFileBufferSize.
*/
public static int bestBufferSize(long fileSize, int maxBufferSize) {
if (fileSize>=maxBufferSize) return maxBufferSize;
else {
return 1 << (32 - Long.numberOfLeadingZeros(fileSize));
}
public static int bestFileBufferSize(long fileSize, int maxFileBufferSize) {
return (fileSize>=maxFileBufferSize) ?
maxFileBufferSize :
Math.toIntExact(fileSize);
}

}

0 comments on commit dd63974

Please sign in to comment.