mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
use buffers for encryption, so large files work as well... also showing encryption progress with better accuracy, which is especially useful for large encryptions
Fixes issue 18.
This commit is contained in:
parent
778f51dbaa
commit
e542c37eb3
@ -1198,6 +1198,7 @@ public class Apg {
|
||||
}
|
||||
|
||||
public static void encrypt(InputStream inStream, OutputStream outStream,
|
||||
long dataLength,
|
||||
boolean armored,
|
||||
long encryptionKeyIds[], long signatureKeyId,
|
||||
String signaturePassPhrase,
|
||||
@ -1240,23 +1241,13 @@ public class Apg {
|
||||
if (signaturePassPhrase == null) {
|
||||
throw new GeneralException("no pass phrase given");
|
||||
}
|
||||
progress.setProgress("extracting signature key...", 0, 100);
|
||||
signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(),
|
||||
new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
PGPSignatureGenerator signatureGenerator = null;
|
||||
progress.setProgress("preparing data...", 0, 100);
|
||||
|
||||
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
||||
int n = 0;
|
||||
byte[] buffer = new byte[1 << 16];
|
||||
while ((n = inStream.read(buffer)) > 0) {
|
||||
byteOut.write(buffer, 0, n);
|
||||
}
|
||||
byteOut.close();
|
||||
byte messageData[] = byteOut.toByteArray();
|
||||
|
||||
progress.setProgress("preparing streams...", 20, 100);
|
||||
progress.setProgress("preparing streams...", 5, 100);
|
||||
// encryptFile and compress input file content
|
||||
PGPEncryptedDataGenerator cPk =
|
||||
new PGPEncryptedDataGenerator(symmetricAlgorithm, true, new SecureRandom(),
|
||||
@ -1275,7 +1266,7 @@ public class Apg {
|
||||
encryptOut = cPk.open(out, new byte[1 << 16]);
|
||||
|
||||
if (signatureKeyId != 0) {
|
||||
progress.setProgress("preparing signature...", 30, 100);
|
||||
progress.setProgress("preparing signature...", 10, 100);
|
||||
signatureGenerator =
|
||||
new PGPSignatureGenerator(signingKey.getPublicKey().getAlgorithm(),
|
||||
hashAlgorithm,
|
||||
@ -1298,19 +1289,27 @@ public class Apg {
|
||||
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
|
||||
// file name not needed, so empty string
|
||||
OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "",
|
||||
messageData.length, new Date());
|
||||
new Date(), new byte[1 << 16]);
|
||||
|
||||
progress.setProgress("encrypting...", 40, 100);
|
||||
pOut.write(messageData);
|
||||
|
||||
if (signatureKeyId != 0) {
|
||||
progress.setProgress("finishing signature...", 70, 100);
|
||||
signatureGenerator.update(messageData);
|
||||
progress.setProgress("encrypting...", 20, 100);
|
||||
long done = 0;
|
||||
int n = 0;
|
||||
byte[] buffer = new byte[1 << 16];
|
||||
while ((n = inStream.read(buffer)) > 0) {
|
||||
pOut.write(buffer, 0, n);
|
||||
if (signatureKeyId != 0) {
|
||||
signatureGenerator.update(buffer, 0, n);
|
||||
}
|
||||
done += n;
|
||||
if (dataLength != 0) {
|
||||
progress.setProgress((int) (20 + (95 - 20) * done / dataLength), 100);
|
||||
}
|
||||
}
|
||||
|
||||
literalGen.close();
|
||||
|
||||
if (signatureKeyId != 0) {
|
||||
progress.setProgress("generating signature...", 95, 100);
|
||||
signatureGenerator.generate().encode(pOut);
|
||||
}
|
||||
compressGen.close();
|
||||
@ -1516,7 +1515,7 @@ public class Apg {
|
||||
throw new GeneralException("couldn't find a packet with symmetric encryption");
|
||||
}
|
||||
|
||||
progress.setProgress("decrypting data...", 20, 100);
|
||||
progress.setProgress("preparing streams...", 20, 100);
|
||||
clear = pbe.getDataStream(passPhrase.toCharArray(), new BouncyCastleProvider());
|
||||
encryptedData = pbe;
|
||||
} else {
|
||||
@ -1550,7 +1549,7 @@ public class Apg {
|
||||
throw new PGPException("wrong pass phrase");
|
||||
}
|
||||
|
||||
progress.setProgress("decrypting data...", 30, 100);
|
||||
progress.setProgress("preparing streams...", 30, 100);
|
||||
clear = pbe.getDataStream(privateKey, new BouncyCastleProvider());
|
||||
encryptedData = pbe;
|
||||
}
|
||||
@ -1606,9 +1605,9 @@ public class Apg {
|
||||
}
|
||||
|
||||
if (dataChunk instanceof PGPLiteralData) {
|
||||
progress.setProgress("unpacking data...", 70, 100);
|
||||
progress.setProgress("decrypting data...", 70, 100);
|
||||
PGPLiteralData literalData = (PGPLiteralData) dataChunk;
|
||||
BufferedOutputStream out = new BufferedOutputStream(outStream);
|
||||
OutputStream out = outStream;
|
||||
|
||||
byte[] buffer = new byte[1 << 16];
|
||||
InputStream dataIn = literalData.getInputStream();
|
||||
|
@ -183,14 +183,9 @@ public class DecryptFileActivity extends BaseActivity {
|
||||
|
||||
try {
|
||||
InputStream in = new FileInputStream(mInputFilename);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
OutputStream out = new FileOutputStream(mOutputFilename);
|
||||
|
||||
data = Apg.decrypt(in, out, Apg.getPassPhrase(), this, mAssumeSymmetricEncryption);
|
||||
|
||||
out.close();
|
||||
OutputStream fileOut = new FileOutputStream(mOutputFilename);
|
||||
fileOut.write(out.toByteArray());
|
||||
fileOut.close();
|
||||
} catch (PGPException e) {
|
||||
error = e.getMessage();
|
||||
} catch (IOException e) {
|
||||
|
@ -333,7 +333,7 @@ public class EncryptFileActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
InputStream in = new FileInputStream(mInputFilename);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
OutputStream out = new FileOutputStream(mOutputFilename);
|
||||
|
||||
String passPhrase = null;
|
||||
if (mEncryptionMode.getCheckedRadioButtonId() == R.id.use_symmetric) {
|
||||
@ -342,17 +342,18 @@ public class EncryptFileActivity extends BaseActivity {
|
||||
passPhrase = null;
|
||||
}
|
||||
}
|
||||
Apg.encrypt(in, out, mAsciiArmour.isChecked(),
|
||||
mEncryptionKeyIds, getSecretKeyId(),
|
||||
Apg.getPassPhrase(), this,
|
||||
((Choice) mAlgorithm.getSelectedItem()).getId(),
|
||||
getDefaultHashAlgorithm(),
|
||||
passPhrase);
|
||||
|
||||
File file = new File(mInputFilename);
|
||||
long fileSize = file.length();
|
||||
|
||||
Apg.encrypt(in, out, fileSize, mAsciiArmour.isChecked(),
|
||||
mEncryptionKeyIds, getSecretKeyId(),
|
||||
Apg.getPassPhrase(), this,
|
||||
((Choice) mAlgorithm.getSelectedItem()).getId(),
|
||||
getDefaultHashAlgorithm(),
|
||||
passPhrase);
|
||||
|
||||
out.close();
|
||||
OutputStream fileOut = new FileOutputStream(mOutputFilename);
|
||||
fileOut.write(out.toByteArray());
|
||||
fileOut.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
error = "file not found: " + e.getMessage();
|
||||
}
|
||||
|
@ -193,12 +193,12 @@ public class EncryptMessageActivity extends BaseActivity {
|
||||
message = message.replaceFirst("\n*$", "\n");
|
||||
}
|
||||
|
||||
ByteArrayInputStream in =
|
||||
new ByteArrayInputStream(Strings.toUTF8ByteArray(message));
|
||||
byte[] byteData = Strings.toUTF8ByteArray(message);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(byteData);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
if (encryptIt) {
|
||||
Apg.encrypt(in, out, true, mEncryptionKeyIds, getSecretKeyId(),
|
||||
Apg.encrypt(in, out, byteData.length, true, mEncryptionKeyIds, getSecretKeyId(),
|
||||
Apg.getPassPhrase(), this,
|
||||
getDefaultEncryptionAlgorithm(), getDefaultHashAlgorithm(),
|
||||
null);
|
||||
|
@ -221,6 +221,9 @@ public class MainActivity extends BaseActivity {
|
||||
SpannableString info =
|
||||
new SpannableString("Read the warnings!\n\n" +
|
||||
"Changes:\n" +
|
||||
"* fixed several crashes\n" +
|
||||
"* can encrypt large files\n" +
|
||||
"* better progress bar calculation\n" +
|
||||
"\n" +
|
||||
"WARNING: be careful editing your existing keys, as they " +
|
||||
"WILL be stripped of certificates right now.\n" +
|
||||
|
Loading…
Reference in New Issue
Block a user