mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 19:22:14 -05:00
Introduction of metadata api, starting to fix decryption progress
This commit is contained in:
parent
1abae04cda
commit
b0821a3ddd
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.pgp;
|
package org.sufficientlysecure.keychain.pgp;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpDecryptMetadata;
|
||||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||||
import org.spongycastle.openpgp.PGPCompressedData;
|
import org.spongycastle.openpgp.PGPCompressedData;
|
||||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||||
@ -45,6 +46,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
|||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@ -269,8 +271,8 @@ public class PgpDecryptVerify {
|
|||||||
|
|
||||||
// allow only specific keys for decryption?
|
// allow only specific keys for decryption?
|
||||||
if (mAllowedKeyIds != null) {
|
if (mAllowedKeyIds != null) {
|
||||||
Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
|
Log.d(Constants.TAG, "encData.getKeyID(): " + encData.getKeyID());
|
||||||
Log.d(Constants.TAG, "allowedKeyIds: " + mAllowedKeyIds);
|
Log.d(Constants.TAG, "mAllowedKeyIds: " + mAllowedKeyIds);
|
||||||
Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
|
Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
|
||||||
|
|
||||||
if (!mAllowedKeyIds.contains(masterKeyId)) {
|
if (!mAllowedKeyIds.contains(masterKeyId)) {
|
||||||
@ -344,7 +346,7 @@ public class PgpDecryptVerify {
|
|||||||
if (!secretEncryptionKey.unlock(mPassphrase)) {
|
if (!secretEncryptionKey.unlock(mPassphrase)) {
|
||||||
throw new WrongPassphraseException();
|
throw new WrongPassphraseException();
|
||||||
}
|
}
|
||||||
} catch(PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
throw new KeyExtractionException();
|
throw new KeyExtractionException();
|
||||||
}
|
}
|
||||||
currentProgress += 5;
|
currentProgress += 5;
|
||||||
@ -371,8 +373,9 @@ public class PgpDecryptVerify {
|
|||||||
if (dataChunk instanceof PGPCompressedData) {
|
if (dataChunk instanceof PGPCompressedData) {
|
||||||
updateProgress(R.string.progress_decompressing_data, currentProgress, 100);
|
updateProgress(R.string.progress_decompressing_data, currentProgress, 100);
|
||||||
|
|
||||||
PGPObjectFactory fact = new PGPObjectFactory(
|
PGPCompressedData compressedData = (PGPCompressedData) dataChunk;
|
||||||
((PGPCompressedData) dataChunk).getDataStream());
|
|
||||||
|
PGPObjectFactory fact = new PGPObjectFactory(compressedData.getDataStream());
|
||||||
dataChunk = fact.nextObject();
|
dataChunk = fact.nextObject();
|
||||||
plainFact = fact;
|
plainFact = fact;
|
||||||
currentProgress += 10;
|
currentProgress += 10;
|
||||||
@ -410,8 +413,8 @@ public class PgpDecryptVerify {
|
|||||||
signatureResultBuilder.keyId(signingRing.getMasterKeyId());
|
signatureResultBuilder.keyId(signingRing.getMasterKeyId());
|
||||||
try {
|
try {
|
||||||
signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback());
|
signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback());
|
||||||
} catch(PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No primary user id in key " + signingRing.getMasterKeyId());
|
Log.d(Constants.TAG, "No primary user id in keyring with master key id " + signingRing.getMasterKeyId());
|
||||||
}
|
}
|
||||||
signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0);
|
signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0);
|
||||||
|
|
||||||
@ -433,6 +436,7 @@ public class PgpDecryptVerify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dataChunk instanceof PGPSignatureList) {
|
if (dataChunk instanceof PGPSignatureList) {
|
||||||
|
// skip
|
||||||
dataChunk = plainFact.nextObject();
|
dataChunk = plainFact.nextObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,44 +445,67 @@ public class PgpDecryptVerify {
|
|||||||
|
|
||||||
PGPLiteralData literalData = (PGPLiteralData) dataChunk;
|
PGPLiteralData literalData = (PGPLiteralData) dataChunk;
|
||||||
|
|
||||||
byte[] buffer = new byte[1 << 16];
|
// TODO: how to get the real original size?
|
||||||
InputStream dataIn = literalData.getInputStream();
|
// this is the encrypted size
|
||||||
|
long originalSize = mData.getSize() - mData.getStreamPosition();
|
||||||
|
if (originalSize < 0) {
|
||||||
|
originalSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int startProgress = currentProgress;
|
OpenPgpDecryptMetadata metadata = new OpenPgpDecryptMetadata(
|
||||||
int endProgress = 100;
|
literalData.getFileName(),
|
||||||
|
literalData.getModificationTime().getTime(),
|
||||||
|
literalData.getFormat(),
|
||||||
|
originalSize);
|
||||||
|
result.setDecryptMetadata(metadata);
|
||||||
|
|
||||||
|
int endProgress;
|
||||||
if (signature != null) {
|
if (signature != null) {
|
||||||
endProgress = 90;
|
endProgress = 90;
|
||||||
} else if (encryptedData.isIntegrityProtected()) {
|
} else if (encryptedData.isIntegrityProtected()) {
|
||||||
endProgress = 95;
|
endProgress = 95;
|
||||||
|
} else {
|
||||||
|
endProgress = 100;
|
||||||
}
|
}
|
||||||
|
ProgressScaler progressScaler =
|
||||||
|
new ProgressScaler(mProgressable, currentProgress, endProgress, 100);
|
||||||
|
|
||||||
int n;
|
InputStream dataIn = literalData.getInputStream();
|
||||||
// TODO: progress calculation is broken here! Try to rework it based on commented code!
|
|
||||||
// int progress = 0;
|
int alreadyWritten = 0;
|
||||||
long startPos = mData.getStreamPosition();
|
long wholeSize = mData.getSize() - mData.getStreamPosition();
|
||||||
while ((n = dataIn.read(buffer)) > 0) {
|
Log.d(Constants.TAG, "mData.getStreamPosition(): " + mData.getStreamPosition());
|
||||||
mOutStream.write(buffer, 0, n);
|
Log.d(Constants.TAG, "wholeSize: " + wholeSize);
|
||||||
// progress += n;
|
|
||||||
|
int length;
|
||||||
|
byte[] buffer = new byte[1 << 16];
|
||||||
|
while ((length = dataIn.read(buffer)) > 0) {
|
||||||
|
mOutStream.write(buffer, 0, length);
|
||||||
|
|
||||||
|
// update signature buffer if signature is also present
|
||||||
if (signature != null) {
|
if (signature != null) {
|
||||||
try {
|
try {
|
||||||
signature.update(buffer, 0, n);
|
signature.update(buffer, 0, length);
|
||||||
} catch (SignatureException e) {
|
} catch (SignatureException e) {
|
||||||
Log.d(Constants.TAG, "SIGNATURE_ERROR");
|
Log.e(Constants.TAG, "SignatureException -> Not a valid signature!", e);
|
||||||
signatureResultBuilder.validSignature(false);
|
signatureResultBuilder.validSignature(false);
|
||||||
signature = null;
|
signature = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: dead code?!
|
|
||||||
// unknown size, but try to at least have a moving, slowing down progress bar
|
alreadyWritten += length;
|
||||||
// currentProgress = startProgress + (endProgress - startProgress) * progress
|
if (wholeSize > 0) {
|
||||||
// / (progress + 100000);
|
int progress = 100 * alreadyWritten / (int) wholeSize;
|
||||||
if (mData.getSize() - startPos == 0) {
|
Log.d(Constants.TAG, "progress: " + progress);
|
||||||
currentProgress = endProgress;
|
|
||||||
} else {
|
// stop at 100 for buggy sizes...
|
||||||
currentProgress = (int) (startProgress + (endProgress - startProgress)
|
if (progress > 100) {
|
||||||
* (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos));
|
progress = 100;
|
||||||
|
}
|
||||||
|
progressScaler.setProgress(progress, 100);
|
||||||
|
} else {
|
||||||
|
// TODO: slow annealing to fake a progress?
|
||||||
}
|
}
|
||||||
updateProgress(currentProgress, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signature != null) {
|
if (signature != null) {
|
||||||
@ -597,7 +624,7 @@ public class PgpDecryptVerify {
|
|||||||
signatureResultBuilder.keyId(signingRing.getMasterKeyId());
|
signatureResultBuilder.keyId(signingRing.getMasterKeyId());
|
||||||
try {
|
try {
|
||||||
signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback());
|
signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback());
|
||||||
} catch(PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No primary user id in key " + signingRing.getMasterKeyId());
|
Log.d(Constants.TAG, "No primary user id in key " + signingRing.getMasterKeyId());
|
||||||
}
|
}
|
||||||
signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0);
|
signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0);
|
||||||
|
@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp;
|
|||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpDecryptMetadata;
|
||||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
|
|
||||||
public class PgpDecryptVerifyResult implements Parcelable {
|
public class PgpDecryptVerifyResult implements Parcelable {
|
||||||
@ -31,21 +32,22 @@ public class PgpDecryptVerifyResult implements Parcelable {
|
|||||||
long mKeyIdPassphraseNeeded;
|
long mKeyIdPassphraseNeeded;
|
||||||
|
|
||||||
OpenPgpSignatureResult mSignatureResult;
|
OpenPgpSignatureResult mSignatureResult;
|
||||||
|
OpenPgpDecryptMetadata mDecryptMetadata;
|
||||||
|
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return mStatus;
|
return mStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStatus(int mStatus) {
|
public void setStatus(int status) {
|
||||||
this.mStatus = mStatus;
|
mStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getKeyIdPassphraseNeeded() {
|
public long getKeyIdPassphraseNeeded() {
|
||||||
return mKeyIdPassphraseNeeded;
|
return mKeyIdPassphraseNeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeyIdPassphraseNeeded(long mKeyIdPassphraseNeeded) {
|
public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) {
|
||||||
this.mKeyIdPassphraseNeeded = mKeyIdPassphraseNeeded;
|
mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult getSignatureResult() {
|
public OpenPgpSignatureResult getSignatureResult() {
|
||||||
@ -53,7 +55,15 @@ public class PgpDecryptVerifyResult implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
|
public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
|
||||||
this.mSignatureResult = signatureResult;
|
mSignatureResult = signatureResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpDecryptMetadata getDecryptMetadata() {
|
||||||
|
return mDecryptMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDecryptMetadata(OpenPgpDecryptMetadata decryptMetadata) {
|
||||||
|
mDecryptMetadata = decryptMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PgpDecryptVerifyResult() {
|
public PgpDecryptVerifyResult() {
|
||||||
@ -64,6 +74,7 @@ public class PgpDecryptVerifyResult implements Parcelable {
|
|||||||
this.mStatus = b.mStatus;
|
this.mStatus = b.mStatus;
|
||||||
this.mKeyIdPassphraseNeeded = b.mKeyIdPassphraseNeeded;
|
this.mKeyIdPassphraseNeeded = b.mKeyIdPassphraseNeeded;
|
||||||
this.mSignatureResult = b.mSignatureResult;
|
this.mSignatureResult = b.mSignatureResult;
|
||||||
|
this.mDecryptMetadata = b.mDecryptMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -75,6 +86,7 @@ public class PgpDecryptVerifyResult implements Parcelable {
|
|||||||
dest.writeInt(mStatus);
|
dest.writeInt(mStatus);
|
||||||
dest.writeLong(mKeyIdPassphraseNeeded);
|
dest.writeLong(mKeyIdPassphraseNeeded);
|
||||||
dest.writeParcelable(mSignatureResult, 0);
|
dest.writeParcelable(mSignatureResult, 0);
|
||||||
|
dest.writeParcelable(mDecryptMetadata, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() {
|
public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() {
|
||||||
@ -83,6 +95,7 @@ public class PgpDecryptVerifyResult implements Parcelable {
|
|||||||
vr.mStatus = source.readInt();
|
vr.mStatus = source.readInt();
|
||||||
vr.mKeyIdPassphraseNeeded = source.readLong();
|
vr.mKeyIdPassphraseNeeded = source.readLong();
|
||||||
vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
|
vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
|
||||||
|
vr.mDecryptMetadata = source.readParcelable(OpenPgpDecryptMetadata.class.getClassLoader());
|
||||||
return vr;
|
return vr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,6 +357,7 @@ public class PgpSignEncrypt {
|
|||||||
BCPGOutputStream bcpgOut;
|
BCPGOutputStream bcpgOut;
|
||||||
if (enableEncryption) {
|
if (enableEncryption) {
|
||||||
/* actual encryption */
|
/* actual encryption */
|
||||||
|
updateProgress(R.string.progress_encrypting, 20, 100);
|
||||||
|
|
||||||
encryptionOut = cPk.open(out, new byte[1 << 16]);
|
encryptionOut = cPk.open(out, new byte[1 << 16]);
|
||||||
|
|
||||||
@ -379,27 +380,26 @@ public class PgpSignEncrypt {
|
|||||||
// file name not needed, so empty string
|
// file name not needed, so empty string
|
||||||
pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(),
|
pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(),
|
||||||
new byte[1 << 16]);
|
new byte[1 << 16]);
|
||||||
updateProgress(R.string.progress_encrypting, 20, 100);
|
|
||||||
|
|
||||||
long progress = 0;
|
long alreadyWritten = 0;
|
||||||
int n;
|
int length;
|
||||||
byte[] buffer = new byte[1 << 16];
|
byte[] buffer = new byte[1 << 16];
|
||||||
InputStream in = mData.getInputStream();
|
InputStream in = mData.getInputStream();
|
||||||
while ((n = in.read(buffer)) > 0) {
|
while ((length = in.read(buffer)) > 0) {
|
||||||
pOut.write(buffer, 0, n);
|
pOut.write(buffer, 0, length);
|
||||||
|
|
||||||
// update signature buffer if signature is requested
|
// update signature buffer if signature is requested
|
||||||
if (enableSignature) {
|
if (enableSignature) {
|
||||||
if (mSignatureForceV3) {
|
if (mSignatureForceV3) {
|
||||||
signatureV3Generator.update(buffer, 0, n);
|
signatureV3Generator.update(buffer, 0, length);
|
||||||
} else {
|
} else {
|
||||||
signatureGenerator.update(buffer, 0, n);
|
signatureGenerator.update(buffer, 0, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progress += n;
|
alreadyWritten += length;
|
||||||
if (mData.getSize() != 0) {
|
if (mData.getSize() != 0) {
|
||||||
updateProgress((int) (20 + (95 - 20) * progress / mData.getSize()), 100);
|
updateProgress((int) (20 + (95 - 20) * alreadyWritten / mData.getSize()), 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user