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