From bac767d184b9120a251330242a79ed363ad854fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 7 Aug 2014 08:51:56 +0200 Subject: Edit key: prevent the combination of change to primary user id and revocation --- .../main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 5be196a45..ae294547f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -339,6 +339,10 @@ public class EditKeyFragment extends LoaderFragment implements mSaveKeyringParcel.mRevokeUserIds.remove(userId); } else { mSaveKeyringParcel.mRevokeUserIds.add(userId); + // not possible to revoke and change to primary user id + if (mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) { + mSaveKeyringParcel.mChangePrimaryUserId = null; + } } break; } -- cgit v1.2.3 From 1abae04cda368409b54c7b3d0b3b8401040ef39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 Aug 2014 20:27:34 +0200 Subject: Fix compression setting for encryption of files --- .../org/sufficientlysecure/keychain/ui/EncryptActivity.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 94f828b48..ab26d539a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -264,24 +264,27 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn // fill values for this action Bundle data = new Bundle(); + int compressionId; if (isContentMessage()) { data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES); data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, mMessage.getBytes()); + + compressionId = Preferences.getPreferences(this).getDefaultMessageCompression(); } else { data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URIS); data.putParcelableArrayList(KeychainIntentService.ENCRYPT_INPUT_URIS, mInputUris); data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URIS); data.putParcelableArrayList(KeychainIntentService.ENCRYPT_OUTPUT_URIS, mOutputUris); + + compressionId = Preferences.getPreferences(this).getDefaultFileCompression(); } + data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); + // Always use armor for messages data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, mUseArmor || isContentMessage()); - // TODO: Only default compression right now... - int compressionId = Preferences.getPreferences(this).getDefaultMessageCompression(); - data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); - if (isModeSymmetric()) { Log.d(Constants.TAG, "Symmetric encryption enabled!"); String passphrase = mPassphrase; -- cgit v1.2.3 From b0821a3ddd56ebcd16b5e1b0de098cb90cab4c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 Aug 2014 20:44:02 +0200 Subject: Introduction of metadata api, starting to fix decryption progress --- .../keychain/pgp/PgpDecryptVerify.java | 87 ++++++++++++++-------- .../keychain/pgp/PgpDecryptVerifyResult.java | 23 ++++-- .../keychain/pgp/PgpSignEncrypt.java | 18 ++--- 3 files changed, 84 insertions(+), 44 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 7f2d971ed..6f34816f1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.pgp; +import org.openintents.openpgp.OpenPgpDecryptMetadata; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.openpgp.PGPCompressedData; 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.util.InputData; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressScaler; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -269,8 +271,8 @@ public class PgpDecryptVerify { // allow only specific keys for decryption? if (mAllowedKeyIds != null) { - Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); - Log.d(Constants.TAG, "allowedKeyIds: " + mAllowedKeyIds); + Log.d(Constants.TAG, "encData.getKeyID(): " + encData.getKeyID()); + Log.d(Constants.TAG, "mAllowedKeyIds: " + mAllowedKeyIds); Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); if (!mAllowedKeyIds.contains(masterKeyId)) { @@ -344,7 +346,7 @@ public class PgpDecryptVerify { if (!secretEncryptionKey.unlock(mPassphrase)) { throw new WrongPassphraseException(); } - } catch(PgpGeneralException e) { + } catch (PgpGeneralException e) { throw new KeyExtractionException(); } currentProgress += 5; @@ -371,8 +373,9 @@ public class PgpDecryptVerify { if (dataChunk instanceof PGPCompressedData) { updateProgress(R.string.progress_decompressing_data, currentProgress, 100); - PGPObjectFactory fact = new PGPObjectFactory( - ((PGPCompressedData) dataChunk).getDataStream()); + PGPCompressedData compressedData = (PGPCompressedData) dataChunk; + + PGPObjectFactory fact = new PGPObjectFactory(compressedData.getDataStream()); dataChunk = fact.nextObject(); plainFact = fact; currentProgress += 10; @@ -410,8 +413,8 @@ public class PgpDecryptVerify { signatureResultBuilder.keyId(signingRing.getMasterKeyId()); try { signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback()); - } catch(PgpGeneralException e) { - Log.d(Constants.TAG, "No primary user id in key " + signingRing.getMasterKeyId()); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No primary user id in keyring with master key id " + signingRing.getMasterKeyId()); } signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0); @@ -433,6 +436,7 @@ public class PgpDecryptVerify { } if (dataChunk instanceof PGPSignatureList) { + // skip dataChunk = plainFact.nextObject(); } @@ -441,44 +445,67 @@ public class PgpDecryptVerify { PGPLiteralData literalData = (PGPLiteralData) dataChunk; - byte[] buffer = new byte[1 << 16]; - InputStream dataIn = literalData.getInputStream(); + // TODO: how to get the real original size? + // this is the encrypted size + long originalSize = mData.getSize() - mData.getStreamPosition(); + if (originalSize < 0) { + originalSize = 0; + } - int startProgress = currentProgress; - int endProgress = 100; + OpenPgpDecryptMetadata metadata = new OpenPgpDecryptMetadata( + literalData.getFileName(), + literalData.getModificationTime().getTime(), + literalData.getFormat(), + originalSize); + result.setDecryptMetadata(metadata); + + int endProgress; if (signature != null) { endProgress = 90; } else if (encryptedData.isIntegrityProtected()) { endProgress = 95; + } else { + endProgress = 100; } + ProgressScaler progressScaler = + new ProgressScaler(mProgressable, currentProgress, endProgress, 100); + + InputStream dataIn = literalData.getInputStream(); + + int alreadyWritten = 0; + long wholeSize = mData.getSize() - mData.getStreamPosition(); + Log.d(Constants.TAG, "mData.getStreamPosition(): " + mData.getStreamPosition()); + Log.d(Constants.TAG, "wholeSize: " + wholeSize); + + int length; + byte[] buffer = new byte[1 << 16]; + while ((length = dataIn.read(buffer)) > 0) { + mOutStream.write(buffer, 0, length); - int n; - // TODO: progress calculation is broken here! Try to rework it based on commented code! -// int progress = 0; - long startPos = mData.getStreamPosition(); - while ((n = dataIn.read(buffer)) > 0) { - mOutStream.write(buffer, 0, n); -// progress += n; + // update signature buffer if signature is also present if (signature != null) { try { - signature.update(buffer, 0, n); + signature.update(buffer, 0, length); } catch (SignatureException e) { - Log.d(Constants.TAG, "SIGNATURE_ERROR"); + Log.e(Constants.TAG, "SignatureException -> Not a valid signature!", e); signatureResultBuilder.validSignature(false); signature = null; } } - // TODO: dead code?! - // unknown size, but try to at least have a moving, slowing down progress bar -// currentProgress = startProgress + (endProgress - startProgress) * progress -// / (progress + 100000); - if (mData.getSize() - startPos == 0) { - currentProgress = endProgress; + + alreadyWritten += length; + if (wholeSize > 0) { + int progress = 100 * alreadyWritten / (int) wholeSize; + Log.d(Constants.TAG, "progress: " + progress); + + // stop at 100 for buggy sizes... + if (progress > 100) { + progress = 100; + } + progressScaler.setProgress(progress, 100); } else { - currentProgress = (int) (startProgress + (endProgress - startProgress) - * (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos)); + // TODO: slow annealing to fake a progress? } - updateProgress(currentProgress, 100); } if (signature != null) { @@ -597,7 +624,7 @@ public class PgpDecryptVerify { signatureResultBuilder.keyId(signingRing.getMasterKeyId()); try { signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback()); - } catch(PgpGeneralException e) { + } catch (PgpGeneralException e) { Log.d(Constants.TAG, "No primary user id in key " + signingRing.getMasterKeyId()); } signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java index ad240e834..d16c6ecc0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp; import android.os.Parcel; import android.os.Parcelable; +import org.openintents.openpgp.OpenPgpDecryptMetadata; import org.openintents.openpgp.OpenPgpSignatureResult; public class PgpDecryptVerifyResult implements Parcelable { @@ -31,21 +32,22 @@ public class PgpDecryptVerifyResult implements Parcelable { long mKeyIdPassphraseNeeded; OpenPgpSignatureResult mSignatureResult; + OpenPgpDecryptMetadata mDecryptMetadata; public int getStatus() { return mStatus; } - public void setStatus(int mStatus) { - this.mStatus = mStatus; + public void setStatus(int status) { + mStatus = status; } public long getKeyIdPassphraseNeeded() { return mKeyIdPassphraseNeeded; } - public void setKeyIdPassphraseNeeded(long mKeyIdPassphraseNeeded) { - this.mKeyIdPassphraseNeeded = mKeyIdPassphraseNeeded; + public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) { + mKeyIdPassphraseNeeded = keyIdPassphraseNeeded; } public OpenPgpSignatureResult getSignatureResult() { @@ -53,7 +55,15 @@ public class PgpDecryptVerifyResult implements Parcelable { } public void setSignatureResult(OpenPgpSignatureResult signatureResult) { - this.mSignatureResult = signatureResult; + mSignatureResult = signatureResult; + } + + public OpenPgpDecryptMetadata getDecryptMetadata() { + return mDecryptMetadata; + } + + public void setDecryptMetadata(OpenPgpDecryptMetadata decryptMetadata) { + mDecryptMetadata = decryptMetadata; } public PgpDecryptVerifyResult() { @@ -64,6 +74,7 @@ public class PgpDecryptVerifyResult implements Parcelable { this.mStatus = b.mStatus; this.mKeyIdPassphraseNeeded = b.mKeyIdPassphraseNeeded; this.mSignatureResult = b.mSignatureResult; + this.mDecryptMetadata = b.mDecryptMetadata; } @@ -75,6 +86,7 @@ public class PgpDecryptVerifyResult implements Parcelable { dest.writeInt(mStatus); dest.writeLong(mKeyIdPassphraseNeeded); dest.writeParcelable(mSignatureResult, 0); + dest.writeParcelable(mDecryptMetadata, 0); } public static final Creator CREATOR = new Creator() { @@ -83,6 +95,7 @@ public class PgpDecryptVerifyResult implements Parcelable { vr.mStatus = source.readInt(); vr.mKeyIdPassphraseNeeded = source.readLong(); vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); + vr.mDecryptMetadata = source.readParcelable(OpenPgpDecryptMetadata.class.getClassLoader()); return vr; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index d8bf0d4d9..b42e832fa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -357,6 +357,7 @@ public class PgpSignEncrypt { BCPGOutputStream bcpgOut; if (enableEncryption) { /* actual encryption */ + updateProgress(R.string.progress_encrypting, 20, 100); encryptionOut = cPk.open(out, new byte[1 << 16]); @@ -379,27 +380,26 @@ public class PgpSignEncrypt { // file name not needed, so empty string pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), new byte[1 << 16]); - updateProgress(R.string.progress_encrypting, 20, 100); - long progress = 0; - int n; + long alreadyWritten = 0; + int length; byte[] buffer = new byte[1 << 16]; InputStream in = mData.getInputStream(); - while ((n = in.read(buffer)) > 0) { - pOut.write(buffer, 0, n); + while ((length = in.read(buffer)) > 0) { + pOut.write(buffer, 0, length); // update signature buffer if signature is requested if (enableSignature) { if (mSignatureForceV3) { - signatureV3Generator.update(buffer, 0, n); + signatureV3Generator.update(buffer, 0, length); } else { - signatureGenerator.update(buffer, 0, n); + signatureGenerator.update(buffer, 0, length); } } - progress += n; + alreadyWritten += length; if (mData.getSize() != 0) { - updateProgress((int) (20 + (95 - 20) * progress / mData.getSize()), 100); + updateProgress((int) (20 + (95 - 20) * alreadyWritten / mData.getSize()), 100); } } -- cgit v1.2.3 From c981902abab0a95067937384a89efcea6ca35f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 Aug 2014 20:59:13 +0200 Subject: Handle missing integrity protection MDC packet as if integrity check would have failed. An attacker could strip the MDC on its way to the receiver... --- .../org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 6f34816f1..46e69afc4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -399,8 +399,7 @@ public class PgpDecryptVerify { signingKey = signingRing.getPublicKey(sigKeyId); signatureIndex = i; } catch (ProviderHelper.NotFoundException e) { - Log.d(Constants.TAG, "key not found!"); - // try next one... + Log.d(Constants.TAG, "key not found, trying next signature…"); } } @@ -537,8 +536,10 @@ public class PgpDecryptVerify { } } else { // no integrity check - Log.e(Constants.TAG, "Encrypted data was not integrity protected!"); - // TODO: inform user? + Log.d(Constants.TAG, "Encrypted data was not integrity protected! MDC packet is missing!"); + // Handle missing integrity protection like failed integrity protection! + // The MDC packet can be stripped by an attacker! + throw new IntegrityCheckFailedException(); } updateProgress(R.string.progress_done, 100, 100); -- cgit v1.2.3 From 33a4d6852008c81070adabb2795c256ea34cac55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 Aug 2014 21:09:10 +0200 Subject: More fixes for decryption progress --- .../org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 46e69afc4..b38caa80e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -471,7 +471,7 @@ public class PgpDecryptVerify { InputStream dataIn = literalData.getInputStream(); - int alreadyWritten = 0; + long alreadyWritten = 0; long wholeSize = mData.getSize() - mData.getStreamPosition(); Log.d(Constants.TAG, "mData.getStreamPosition(): " + mData.getStreamPosition()); Log.d(Constants.TAG, "wholeSize: " + wholeSize); @@ -494,14 +494,12 @@ public class PgpDecryptVerify { alreadyWritten += length; if (wholeSize > 0) { - int progress = 100 * alreadyWritten / (int) wholeSize; - Log.d(Constants.TAG, "progress: " + progress); - - // stop at 100 for buggy sizes... + long progress = 100 * alreadyWritten / wholeSize; + // stop at 100% for wrong file sizes... if (progress > 100) { progress = 100; } - progressScaler.setProgress(progress, 100); + progressScaler.setProgress((int) progress, 100); } else { // TODO: slow annealing to fake a progress? } -- cgit v1.2.3 From 13f86890d68f68529df692531a830c0a8b3134c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 10 Aug 2014 21:50:46 +0200 Subject: Handle missing MDC as failed only if no valid signature is present --- .../keychain/pgp/OpenPgpSignatureResultBuilder.java | 4 ++++ .../java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java index 75f8bdb66..a116ea665 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java @@ -65,6 +65,10 @@ public class OpenPgpSignatureResultBuilder { this.mSignatureAvailable = signatureAvailable; } + public boolean isValidSignature() { + return mValidSignature; + } + public OpenPgpSignatureResult build() { if (mSignatureAvailable) { OpenPgpSignatureResult result = new OpenPgpSignatureResult(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index b38caa80e..518975907 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -535,9 +535,13 @@ public class PgpDecryptVerify { } else { // no integrity check Log.d(Constants.TAG, "Encrypted data was not integrity protected! MDC packet is missing!"); + + // If no valid signature is present: // Handle missing integrity protection like failed integrity protection! // The MDC packet can be stripped by an attacker! - throw new IntegrityCheckFailedException(); + if (!signatureResultBuilder.isValidSignature()) { + throw new IntegrityCheckFailedException(); + } } updateProgress(R.string.progress_done, 100, 100); -- cgit v1.2.3 From 867b89be0aff81781ccf15a172aae875fca9f940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 01:31:51 +0200 Subject: More fixes for decryption progress --- .../keychain/pgp/PgpDecryptVerify.java | 29 ++++++++-------------- 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 518975907..6ce483989 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -229,8 +229,6 @@ public class PgpDecryptVerify { InputStream clear; PGPEncryptedData encryptedData; - currentProgress += 5; - PGPPublicKeyEncryptedData encryptedDataAsymmetric = null; PGPPBEEncryptedData encryptedDataSymmetric = null; CanonicalizedSecretKey secretEncryptionKey = null; @@ -241,6 +239,7 @@ public class PgpDecryptVerify { while (it.hasNext()) { Object obj = it.next(); if (obj instanceof PGPPublicKeyEncryptedData) { + currentProgress += 2; updateProgress(R.string.progress_finding_key, currentProgress, 100); PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; @@ -327,6 +326,7 @@ public class PgpDecryptVerify { } if (symmetricPacketFound) { + currentProgress += 2; updateProgress(R.string.progress_preparing_streams, currentProgress, 100); PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() @@ -338,9 +338,8 @@ public class PgpDecryptVerify { clear = encryptedDataSymmetric.getDataStream(decryptorFactory); encryptedData = encryptedDataSymmetric; - currentProgress += 5; } else if (asymmetricPacketFound) { - currentProgress += 5; + currentProgress += 2; updateProgress(R.string.progress_extracting_key, currentProgress, 100); try { if (!secretEncryptionKey.unlock(mPassphrase)) { @@ -349,15 +348,13 @@ public class PgpDecryptVerify { } catch (PgpGeneralException e) { throw new KeyExtractionException(); } - currentProgress += 5; + + currentProgress += 2; updateProgress(R.string.progress_preparing_streams, currentProgress, 100); PublicKeyDataDecryptorFactory decryptorFactory = secretEncryptionKey.getDecryptorFactory(); - clear = encryptedDataAsymmetric.getDataStream(decryptorFactory); - encryptedData = encryptedDataAsymmetric; - currentProgress += 5; } else { // no packet has been found where we have the corresponding secret key in our db throw new NoSecretKeyException(); @@ -371,6 +368,7 @@ public class PgpDecryptVerify { CanonicalizedPublicKey signingKey = null; if (dataChunk instanceof PGPCompressedData) { + currentProgress += 2; updateProgress(R.string.progress_decompressing_data, currentProgress, 100); PGPCompressedData compressedData = (PGPCompressedData) dataChunk; @@ -378,12 +376,11 @@ public class PgpDecryptVerify { PGPObjectFactory fact = new PGPObjectFactory(compressedData.getDataStream()); dataChunk = fact.nextObject(); plainFact = fact; - currentProgress += 10; } PGPOnePassSignature signature = null; - if (dataChunk instanceof PGPOnePassSignatureList) { + currentProgress += 2; updateProgress(R.string.progress_processing_signature, currentProgress, 100); PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; @@ -399,7 +396,7 @@ public class PgpDecryptVerify { signingKey = signingRing.getPublicKey(sigKeyId); signatureIndex = i; } catch (ProviderHelper.NotFoundException e) { - Log.d(Constants.TAG, "key not found, trying next signature…"); + Log.d(Constants.TAG, "key not found, trying next signature..."); } } @@ -431,7 +428,6 @@ public class PgpDecryptVerify { } dataChunk = plainFact.nextObject(); - currentProgress += 10; } if (dataChunk instanceof PGPSignatureList) { @@ -440,6 +436,7 @@ public class PgpDecryptVerify { } if (dataChunk instanceof PGPLiteralData) { + currentProgress += 4; updateProgress(R.string.progress_decrypting, currentProgress, 100); PGPLiteralData literalData = (PGPLiteralData) dataChunk; @@ -473,9 +470,6 @@ public class PgpDecryptVerify { long alreadyWritten = 0; long wholeSize = mData.getSize() - mData.getStreamPosition(); - Log.d(Constants.TAG, "mData.getStreamPosition(): " + mData.getStreamPosition()); - Log.d(Constants.TAG, "wholeSize: " + wholeSize); - int length; byte[] buffer = new byte[1 << 16]; while ((length = dataIn.read(buffer)) > 0) { @@ -611,8 +605,7 @@ public class PgpDecryptVerify { signingKey = signingRing.getPublicKey(sigKeyId); signatureIndex = i; } catch (ProviderHelper.NotFoundException e) { - Log.d(Constants.TAG, "key not found!"); - // try next one... + Log.d(Constants.TAG, "key not found, trying next signature..."); } } @@ -628,7 +621,7 @@ public class PgpDecryptVerify { try { signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback()); } 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 with master key id " + signingRing.getMasterKeyId()); } signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0); -- cgit v1.2.3 From 94b7b1b5d85339f38aff6a49535522af12213c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 09:55:24 +0200 Subject: progress for signing binary --- .../keychain/pgp/PgpSignEncrypt.java | 42 ++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index b42e832fa..dda3f260c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -37,6 +37,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressScaler; import java.io.BufferedReader; import java.io.IOException; @@ -131,7 +132,7 @@ public class PgpSignEncrypt { this.mOutStream = outStream; } - public Builder setProgressable(Progressable progressable) { + public Builder setProgressable(Progressable progressable) { mProgressable = progressable; return this; } @@ -277,7 +278,7 @@ public class PgpSignEncrypt { } try { signingKey = signingKeyRing.getSigningSubKey(); - } catch(PgpGeneralException e) { + } catch (PgpGeneralException e) { throw new NoSigningKeyException(); } @@ -293,7 +294,7 @@ public class PgpSignEncrypt { throw new KeyExtractionException(); } } - updateProgress(R.string.progress_preparing_streams, 5, 100); + updateProgress(R.string.progress_preparing_streams, 2, 100); /* Initialize PGPEncryptedDataGenerator for later usage */ PGPEncryptedDataGenerator cPk = null; @@ -334,13 +335,13 @@ public class PgpSignEncrypt { PGPSignatureGenerator signatureGenerator = null; PGPV3SignatureGenerator signatureV3Generator = null; if (enableSignature) { - updateProgress(R.string.progress_preparing_signature, 10, 100); + updateProgress(R.string.progress_preparing_signature, 4, 100); try { boolean cleartext = mCleartextInput && mEnableAsciiArmorOutput && !enableEncryption; if (mSignatureForceV3) { signatureV3Generator = signingKey.getV3SignatureGenerator( - mSignatureHashAlgorithm,cleartext); + mSignatureHashAlgorithm, cleartext); } else { signatureGenerator = signingKey.getSignatureGenerator( mSignatureHashAlgorithm, cleartext); @@ -351,13 +352,15 @@ public class PgpSignEncrypt { } } + ProgressScaler progressScaler = + new ProgressScaler(mProgressable, 8, 95, 100); PGPCompressedDataGenerator compressGen = null; OutputStream pOut; OutputStream encryptionOut = null; BCPGOutputStream bcpgOut; if (enableEncryption) { /* actual encryption */ - updateProgress(R.string.progress_encrypting, 20, 100); + updateProgress(R.string.progress_encrypting, 8, 100); encryptionOut = cPk.open(out, new byte[1 << 16]); @@ -398,8 +401,9 @@ public class PgpSignEncrypt { } alreadyWritten += length; - if (mData.getSize() != 0) { - updateProgress((int) (20 + (95 - 20) * alreadyWritten / mData.getSize()), 100); + if (mData.getSize() > 0) { + long progress = 100 * alreadyWritten / mData.getSize(); + progressScaler.setProgress((int) progress, 100); } } @@ -407,7 +411,7 @@ public class PgpSignEncrypt { } else if (enableSignature && mCleartextInput && mEnableAsciiArmorOutput) { /* cleartext signature: sign-only of ascii text */ - updateProgress(R.string.progress_signing, 40, 100); + updateProgress(R.string.progress_signing, 8, 100); // write -----BEGIN PGP SIGNED MESSAGE----- armorOut.beginClearText(mSignatureHashAlgorithm); @@ -422,6 +426,7 @@ public class PgpSignEncrypt { processLine(reader.readLine(), armorOut, signatureGenerator); } + // TODO: progress: fake annealing? while (true) { String line = reader.readLine(); @@ -449,7 +454,7 @@ public class PgpSignEncrypt { } else if (enableSignature && !mCleartextInput) { /* sign-only binary (files/data stream) */ - updateProgress(R.string.progress_signing, 40, 100); + updateProgress(R.string.progress_signing, 8, 100); InputStream in = mData.getInputStream(); @@ -471,15 +476,22 @@ public class PgpSignEncrypt { pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), new byte[1 << 16]); + long alreadyWritten = 0; + int length; byte[] buffer = new byte[1 << 16]; - int n; - while ((n = in.read(buffer)) > 0) { - pOut.write(buffer, 0, n); + while ((length = in.read(buffer)) > 0) { + pOut.write(buffer, 0, length); if (mSignatureForceV3) { - signatureV3Generator.update(buffer, 0, n); + signatureV3Generator.update(buffer, 0, length); } else { - signatureGenerator.update(buffer, 0, n); + signatureGenerator.update(buffer, 0, length); + } + + alreadyWritten += length; + if (mData.getSize() > 0) { + long progress = 100 * alreadyWritten / mData.getSize(); + progressScaler.setProgress((int) progress, 100); } } -- cgit v1.2.3 From 549feb69ed0a339f8320f52da9246aac74b60ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 10:00:24 +0200 Subject: Add option to pass original filename to PgpSignEncrypt --- .../keychain/pgp/PgpSignEncrypt.java | 32 ++++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index dda3f260c..4973f64bb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -72,6 +72,7 @@ public class PgpSignEncrypt { private String mSignaturePassphrase; private boolean mEncryptToSigner; private boolean mCleartextInput; + private String mOriginalFilename; private static byte[] NEW_LINE; @@ -102,6 +103,7 @@ public class PgpSignEncrypt { this.mSignaturePassphrase = builder.mSignaturePassphrase; this.mEncryptToSigner = builder.mEncryptToSigner; this.mCleartextInput = builder.mCleartextInput; + this.mOriginalFilename = builder.mOriginalFilename; } public static class Builder { @@ -124,12 +126,13 @@ public class PgpSignEncrypt { private String mSignaturePassphrase = null; private boolean mEncryptToSigner = false; private boolean mCleartextInput = false; + private String mOriginalFilename = ""; public Builder(ProviderHelper providerHelper, String versionHeader, InputData data, OutputStream outStream) { - this.mProviderHelper = providerHelper; - this.mVersionHeader = versionHeader; - this.mData = data; - this.mOutStream = outStream; + mProviderHelper = providerHelper; + mVersionHeader = versionHeader; + mData = data; + mOutStream = outStream; } public Builder setProgressable(Progressable progressable) { @@ -148,12 +151,12 @@ public class PgpSignEncrypt { } public Builder setEncryptionMasterKeyIds(long[] encryptionMasterKeyIds) { - this.mEncryptionMasterKeyIds = encryptionMasterKeyIds; + mEncryptionMasterKeyIds = encryptionMasterKeyIds; return this; } public Builder setSymmetricPassphrase(String symmetricPassphrase) { - this.mSymmetricPassphrase = symmetricPassphrase; + mSymmetricPassphrase = symmetricPassphrase; return this; } @@ -183,11 +186,13 @@ public class PgpSignEncrypt { } /** + * Also encrypt with the signing keyring + * * @param encryptToSigner * @return */ public Builder setEncryptToSigner(boolean encryptToSigner) { - this.mEncryptToSigner = encryptToSigner; + mEncryptToSigner = encryptToSigner; return this; } @@ -198,7 +203,12 @@ public class PgpSignEncrypt { * @return */ public Builder setCleartextInput(boolean cleartextInput) { - this.mCleartextInput = cleartextInput; + mCleartextInput = cleartextInput; + return this; + } + + public Builder setOriginalFilename(String originalFilename) { + mOriginalFilename = originalFilename; return this; } @@ -380,8 +390,7 @@ public class PgpSignEncrypt { } PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); - // file name not needed, so empty string - pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), + pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, mOriginalFilename, new Date(), new byte[1 << 16]); long alreadyWritten = 0; @@ -472,8 +481,7 @@ public class PgpSignEncrypt { } PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); - // file name not needed, so empty string - pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), + pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, mOriginalFilename, new Date(), new byte[1 << 16]); long alreadyWritten = 0; -- cgit v1.2.3 From b67356503511725df1b016d8a8513b6356cb450a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 17:10:47 +0200 Subject: Get original filename for decryption --- .../keychain/pgp/PgpDecryptVerify.java | 23 +++++- .../keychain/service/KeychainIntentService.java | 81 ++++++++++++++++-- .../keychain/ui/DecryptFileFragment.java | 95 ++++++++++++++++++++-- .../keychain/ui/EncryptActivity.java | 9 +- 4 files changed, 188 insertions(+), 20 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 6ce483989..2ab93ca41 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -71,6 +71,7 @@ public class PgpDecryptVerify { private boolean mAllowSymmetricDecryption; private String mPassphrase; private Set mAllowedKeyIds; + private boolean mReturnMetadataOnly; private PgpDecryptVerify(Builder builder) { // private Constructor can only be called from Builder @@ -83,6 +84,7 @@ public class PgpDecryptVerify { this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption; this.mPassphrase = builder.mPassphrase; this.mAllowedKeyIds = builder.mAllowedKeyIds; + this.mReturnMetadataOnly = builder.mReturnMetadataOnly; } public static class Builder { @@ -97,6 +99,7 @@ public class PgpDecryptVerify { private boolean mAllowSymmetricDecryption = true; private String mPassphrase = null; private Set mAllowedKeyIds = null; + private boolean mReturnMetadataOnly = false; public Builder(ProviderHelper providerHelper, PassphraseCache passphraseCache, InputData data, OutputStream outStream) { @@ -126,7 +129,16 @@ public class PgpDecryptVerify { * This means only ciphertexts encrypted for one of these private key can be decrypted. */ public Builder setAllowedKeyIds(Set allowedKeyIds) { - this.mAllowedKeyIds = allowedKeyIds; + mAllowedKeyIds = allowedKeyIds; + return this; + } + + /** + * If enabled, the actual decryption/verification of the content will not be executed. + * The metadata only will be decrypted and returned. + */ + public Builder setReturnMetadataOnly(boolean returnMetadataOnly) { + mReturnMetadataOnly = returnMetadataOnly; return this; } @@ -442,7 +454,7 @@ public class PgpDecryptVerify { PGPLiteralData literalData = (PGPLiteralData) dataChunk; // TODO: how to get the real original size? - // this is the encrypted size + // this is the encrypted size so if we enable compression this value is wrong! long originalSize = mData.getSize() - mData.getStreamPosition(); if (originalSize < 0) { originalSize = 0; @@ -455,6 +467,13 @@ public class PgpDecryptVerify { originalSize); result.setDecryptMetadata(metadata); + Log.d(Constants.TAG, "metadata: " + metadata); + + // return here if we want to decrypt the metadata only + if (mReturnMetadataOnly) { + return result; + } + int endProgress; if (signature != null) { endProgress = 90; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 30108d52d..680f2fb27 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -86,6 +86,8 @@ public class KeychainIntentService extends IntentService public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY"; + public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA"; + public static final String ACTION_SAVE_KEYRING = Constants.INTENT_PREFIX + "SAVE_KEYRING"; public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX @@ -241,6 +243,7 @@ public class KeychainIntentService extends IntentService data.putInt(SELECTED_URI, i); InputData inputData = createEncryptInputData(data); OutputStream outStream = createCryptOutputStream(data); + String originalFilename = getOriginalFilename(data); /* Operation */ PgpSignEncrypt.Builder builder = @@ -262,7 +265,8 @@ public class KeychainIntentService extends IntentService .setSignatureHashAlgorithm( Preferences.getPreferences(this).getDefaultHashAlgorithm()) .setSignaturePassphrase( - PassphraseCacheService.getCachedPassphrase(this, signatureKeyId)); + PassphraseCacheService.getCachedPassphrase(this, signatureKeyId)) + .setOriginalFilename(originalFilename); // this assumes that the bytes are cleartext (valid for current implementation!) if (source == IO_BYTES) { @@ -308,10 +312,10 @@ public class KeychainIntentService extends IntentService KeychainIntentService.this, masterKeyId); } }, - inputData, outStream); - builder.setProgressable(this); - - builder.setAllowSymmetricDecryption(true) + inputData, outStream + ); + builder.setProgressable(this) + .setAllowSymmetricDecryption(true) .setPassphrase(passphrase); PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); @@ -326,6 +330,46 @@ public class KeychainIntentService extends IntentService OtherHelper.logDebugBundle(resultData, "resultData"); + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData); + } catch (Exception e) { + sendErrorToHandler(e); + } + } else if (ACTION_DECRYPT_METADATA.equals(action)) { + try { + /* Input */ + String passphrase = data.getString(DECRYPT_PASSPHRASE); + + InputData inputData = createDecryptInputData(data); + + /* Operation */ + + Bundle resultData = new Bundle(); + + // verifyText and decrypt returning additional resultData values for the + // verification of signatures + PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder( + new ProviderHelper(this), + new PgpDecryptVerify.PassphraseCache() { + @Override + public String getCachedPassphrase(long masterKeyId) { + return PassphraseCacheService.getCachedPassphrase( + KeychainIntentService.this, masterKeyId); + } + }, + inputData, null + ); + builder.setProgressable(this) + .setAllowSymmetricDecryption(true) + .setPassphrase(passphrase) + .setReturnMetadataOnly(true); + + PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); + + resultData.putParcelable(RESULT_DECRYPT_VERIFY_RESULT, decryptVerifyResult); + + /* Output */ + OtherHelper.logDebugBundle(resultData, "resultData"); + sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, resultData); } catch (Exception e) { sendErrorToHandler(e); @@ -356,7 +400,7 @@ public class KeychainIntentService extends IntentService UncachedKeyRing ring = result.getRing(); - providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100)); + providerHelper.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100)); // cache new passphrase if (saveParcel.mNewPassphrase != null) { @@ -403,7 +447,7 @@ public class KeychainIntentService extends IntentService } else { // get entries from cached file FileImportCache cache = - new FileImportCache(this); + new FileImportCache(this); entries = cache.readCacheIntoList(); } @@ -576,7 +620,7 @@ public class KeychainIntentService extends IntentService CanonicalizedPublicKeyRing publicRing = providerHelper.getCanonicalizedPublicKeyRing(pubKeyId); CanonicalizedSecretKeyRing secretKeyRing = providerHelper.getCanonicalizedSecretKeyRing(masterKeyId); CanonicalizedSecretKey certificationKey = secretKeyRing.getSecretKey(); - if(!certificationKey.unlock(signaturePassphrase)) { + if (!certificationKey.unlock(signaturePassphrase)) { throw new PgpGeneralException("Error extracting key (bad passphrase?)"); } UncachedKeyRing newRing = certificationKey.certifyUserIds(publicRing, userIds); @@ -729,6 +773,27 @@ public class KeychainIntentService extends IntentService } } + private String getOriginalFilename(Bundle data) throws PgpGeneralException, FileNotFoundException { + int target = data.getInt(TARGET); + switch (target) { + case IO_BYTES: + return ""; + + case IO_URI: + Uri providerUri = data.getParcelable(ENCRYPT_INPUT_URI); + + return FileHelper.getFilename(this, providerUri); + + case IO_URIS: + providerUri = data.getParcelableArrayList(ENCRYPT_INPUT_URIS).get(data.getInt(SELECTED_URI)); + + return FileHelper.getFilename(this, providerUri); + + default: + throw new PgpGeneralException("No target choosen!"); + } + } + private OutputStream createCryptOutputStream(Bundle data) throws PgpGeneralException, FileNotFoundException { int target = data.getInt(TARGET); switch (target) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index c33b1489a..845fbfa3b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -23,8 +23,10 @@ import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.os.Message; import android.os.Messenger; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -38,6 +40,7 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Notify; @@ -113,7 +116,8 @@ public class DecryptFileFragment extends DecryptFragment { return; } - askForOutputFilename(); +// askForOutputFilename(); + decryptOriginalFilename(null); } private String removeEncryptedAppend(String name) { @@ -123,8 +127,13 @@ public class DecryptFileFragment extends DecryptFragment { return name; } - private void askForOutputFilename() { - String targetName = removeEncryptedAppend(FileHelper.getFilename(getActivity(), mInputUri)); + private void askForOutputFilename(String originalFilename) { + String targetName; + if (!TextUtils.isEmpty(originalFilename)) { + targetName = originalFilename; + } else { + targetName = removeEncryptedAppend(FileHelper.getFilename(getActivity(), mInputUri)); + } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { File file = new File(mInputUri.getPath()); File parentDir = file.exists() ? file.getParentFile() : Constants.Path.APP_DIR; @@ -136,6 +145,82 @@ public class DecryptFileFragment extends DecryptFragment { } } + private void decryptOriginalFilename(String passphrase) { + Log.d(Constants.TAG, "decryptOriginalFilename"); + + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + // fill values for this action + Bundle data = new Bundle(); + intent.setAction(KeychainIntentService.ACTION_DECRYPT_METADATA); + + // data + Log.d(Constants.TAG, "mInputUri=" + mInputUri + ", mOutputUri=" + mOutputUri); + + data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URI); + data.putParcelable(KeychainIntentService.ENCRYPT_INPUT_URI, mInputUri); + + data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URI); + data.putParcelable(KeychainIntentService.ENCRYPT_OUTPUT_URI, mOutputUri); + + data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, passphrase); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after decrypting is done in KeychainIntentService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), + getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + PgpDecryptVerifyResult decryptVerifyResult = + returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT); + + if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { + showPassphraseDialogForFilename(decryptVerifyResult.getKeyIdPassphraseNeeded()); + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == + decryptVerifyResult.getStatus()) { + showPassphraseDialogForFilename(Constants.key.symmetric); + } else { + + // go on... + askForOutputFilename(decryptVerifyResult.getDecryptMetadata().getFilename()); + } + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(getActivity()); + + // start service with intent + getActivity().startService(intent); + } + + protected void showPassphraseDialogForFilename(long keyId) { + PassphraseDialogFragment.show(getActivity(), keyId, + new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + String passphrase = + message.getData().getString(PassphraseDialogFragment.MESSAGE_DATA_PASSPHRASE); + decryptOriginalFilename(passphrase); + } + } + } + ); + } + @Override protected void decryptStart(String passphrase) { Log.d(Constants.TAG, "decryptStart"); @@ -161,7 +246,7 @@ public class DecryptFileFragment extends DecryptFragment { intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - // Message is received after encrypting is done in KeychainIntentService + // Message is received after decrypting is done in KeychainIntentService KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) { public void handleMessage(Message message) { @@ -178,7 +263,7 @@ public class DecryptFileFragment extends DecryptFragment { if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { showPassphraseDialog(decryptVerifyResult.getKeyIdPassphraseNeeded()); } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == - decryptVerifyResult.getStatus()) { + decryptVerifyResult.getStatus()) { showPassphraseDialog(Constants.key.symmetric); } else { // display signature result in activity diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index ab26d539a..a5cf4d84d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -264,12 +264,12 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn // fill values for this action Bundle data = new Bundle(); - int compressionId; if (isContentMessage()) { data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_BYTES); data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, mMessage.getBytes()); - compressionId = Preferences.getPreferences(this).getDefaultMessageCompression(); + data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, + Preferences.getPreferences(this).getDefaultMessageCompression()); } else { data.putInt(KeychainIntentService.SOURCE, KeychainIntentService.IO_URIS); data.putParcelableArrayList(KeychainIntentService.ENCRYPT_INPUT_URIS, mInputUris); @@ -277,10 +277,10 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn data.putInt(KeychainIntentService.TARGET, KeychainIntentService.IO_URIS); data.putParcelableArrayList(KeychainIntentService.ENCRYPT_OUTPUT_URIS, mOutputUris); - compressionId = Preferences.getPreferences(this).getDefaultFileCompression(); + data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, + Preferences.getPreferences(this).getDefaultFileCompression()); } - data.putInt(KeychainIntentService.ENCRYPT_COMPRESSION_ID, compressionId); // Always use armor for messages data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, mUseArmor || isContentMessage()); @@ -429,7 +429,6 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn if (isModeSymmetric()) { // symmetric encryption checks - if (mPassphrase == null) { Notify.showNotify(this, R.string.passphrases_do_not_match, Notify.Style.ERROR); return false; -- cgit v1.2.3 From 59096b37fdfef1d9294990a64c755080585b1da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 17:22:53 +0200 Subject: Support API versions 3 and 4 --- .../java/org/sufficientlysecure/keychain/remote/OpenPgpService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 5ed95acb3..d3a38c5d7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -507,7 +507,10 @@ public class OpenPgpService extends RemoteService { } // version code is required and needs to correspond to version code of service! - if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) { + // History of versions in org.openintents.openpgp.util.OpenPgpApi + // we support 3 and 4 + if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 3 + || data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 4) { Intent result = new Intent(); OpenPgpError error = new OpenPgpError (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); -- cgit v1.2.3 From d5b40de70a9a53372a3c538ad4ec2656a63b7984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 17:29:41 +0200 Subject: Decrypt metadata api --- .../keychain/pgp/PgpDecryptVerify.java | 12 ++++++------ .../keychain/remote/OpenPgpService.java | 20 +++++++++++++++++--- .../keychain/service/KeychainIntentService.java | 2 +- 3 files changed, 24 insertions(+), 10 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 2ab93ca41..5a5e51f99 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -71,7 +71,7 @@ public class PgpDecryptVerify { private boolean mAllowSymmetricDecryption; private String mPassphrase; private Set mAllowedKeyIds; - private boolean mReturnMetadataOnly; + private boolean mDecryptMetadataOnly; private PgpDecryptVerify(Builder builder) { // private Constructor can only be called from Builder @@ -84,7 +84,7 @@ public class PgpDecryptVerify { this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption; this.mPassphrase = builder.mPassphrase; this.mAllowedKeyIds = builder.mAllowedKeyIds; - this.mReturnMetadataOnly = builder.mReturnMetadataOnly; + this.mDecryptMetadataOnly = builder.mDecryptMetadataOnly; } public static class Builder { @@ -99,7 +99,7 @@ public class PgpDecryptVerify { private boolean mAllowSymmetricDecryption = true; private String mPassphrase = null; private Set mAllowedKeyIds = null; - private boolean mReturnMetadataOnly = false; + private boolean mDecryptMetadataOnly = false; public Builder(ProviderHelper providerHelper, PassphraseCache passphraseCache, InputData data, OutputStream outStream) { @@ -137,8 +137,8 @@ public class PgpDecryptVerify { * If enabled, the actual decryption/verification of the content will not be executed. * The metadata only will be decrypted and returned. */ - public Builder setReturnMetadataOnly(boolean returnMetadataOnly) { - mReturnMetadataOnly = returnMetadataOnly; + public Builder setDecryptMetadataOnly(boolean decryptMetadataOnly) { + mDecryptMetadataOnly = decryptMetadataOnly; return this; } @@ -470,7 +470,7 @@ public class PgpDecryptVerify { Log.d(Constants.TAG, "metadata: " + metadata); // return here if we want to decrypt the metadata only - if (mReturnMetadataOnly) { + if (mDecryptMetadataOnly) { return result; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index d3a38c5d7..5c94f4796 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -25,6 +25,7 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.OpenPgpDecryptMetadata; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpApi; @@ -326,7 +327,8 @@ public class OpenPgpService extends RemoteService { } private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input, - ParcelFileDescriptor output, Set allowedKeyIds) { + ParcelFileDescriptor output, Set allowedKeyIds, + boolean decryptMetadataOnly) { try { // Get Input- and OutputStream from ParcelFileDescriptor InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); @@ -353,7 +355,8 @@ public class OpenPgpService extends RemoteService { builder.setAllowSymmetricDecryption(false) // no support for symmetric encryption .setAllowedKeyIds(allowedKeyIds) // allow only private keys associated with // accounts of this app - .setPassphrase(passphrase); + .setPassphrase(passphrase) + .setDecryptMetadataOnly(decryptMetadataOnly); PgpDecryptVerifyResult decryptVerifyResult; try { @@ -403,6 +406,11 @@ public class OpenPgpService extends RemoteService { } } + OpenPgpDecryptMetadata metadata = decryptVerifyResult.getDecryptMetadata(); + if (metadata != null) { + result.putExtra(OpenPgpApi.RESULT_METADATA, metadata); + } + } finally { is.close(); os.close(); @@ -561,7 +569,13 @@ public class OpenPgpService extends RemoteService { Set allowedKeyIds = mProviderHelper.getAllKeyIdsForApp( ApiAccounts.buildBaseUri(currentPkg)); - return decryptAndVerifyImpl(data, input, output, allowedKeyIds); + return decryptAndVerifyImpl(data, input, output, allowedKeyIds, false); + } else if (OpenPgpApi.ACTION_DECRYPT_METADATA.equals(action)) { + String currentPkg = getCurrentCallingPackage(); + Set allowedKeyIds = + mProviderHelper.getAllKeyIdsForApp( + ApiAccounts.buildBaseUri(currentPkg)); + return decryptAndVerifyImpl(data, input, output, allowedKeyIds, true); } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) { return getKeyImpl(data); } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 680f2fb27..54895973b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -361,7 +361,7 @@ public class KeychainIntentService extends IntentService builder.setProgressable(this) .setAllowSymmetricDecryption(true) .setPassphrase(passphrase) - .setReturnMetadataOnly(true); + .setDecryptMetadataOnly(true); PgpDecryptVerifyResult decryptVerifyResult = builder.build().execute(); -- cgit v1.2.3 From abf50c37500dd0f3dfdc10820cb46bf4f9566cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 20:16:21 +0200 Subject: Support mime type in metadata --- .../keychain/pgp/PgpDecryptVerify.java | 29 ++++++++++++++++++++-- .../keychain/ui/EncryptActivity.java | 1 - 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 5a5e51f99..9a18fc5f0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -18,6 +18,8 @@ package org.sufficientlysecure.keychain.pgp; +import android.webkit.MimeTypeMap; + import org.openintents.openpgp.OpenPgpDecryptMetadata; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.openpgp.PGPCompressedData; @@ -54,6 +56,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.URLConnection; import java.security.SignatureException; import java.util.Iterator; import java.util.Set; @@ -460,10 +463,32 @@ public class PgpDecryptVerify { originalSize = 0; } + String originalFilename = literalData.getFileName(); + String mimeType = null; + if (literalData.getFormat() == PGPLiteralData.TEXT + || literalData.getFormat() == PGPLiteralData.UTF8) { + mimeType = "text/plain"; + } else { + // TODO: better would be: https://github.com/open-keychain/open-keychain/issues/753 + + // try to guess from file ending + String extension = MimeTypeMap.getFileExtensionFromUrl(originalFilename); + if (extension != null) { + MimeTypeMap mime = MimeTypeMap.getSingleton(); + mimeType = mime.getMimeTypeFromExtension(extension); + } + if (mimeType == null) { + mimeType = URLConnection.guessContentTypeFromName(originalFilename); + } + if (mimeType == null) { + mimeType = "*/*"; + } + } + OpenPgpDecryptMetadata metadata = new OpenPgpDecryptMetadata( - literalData.getFileName(), + originalFilename, + mimeType, literalData.getModificationTime().getTime(), - literalData.getFormat(), originalSize); result.setDecryptMetadata(metadata); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index a5cf4d84d..b140c5a03 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -281,7 +281,6 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn Preferences.getPreferences(this).getDefaultFileCompression()); } - // Always use armor for messages data.putBoolean(KeychainIntentService.ENCRYPT_USE_ASCII_ARMOR, mUseArmor || isContentMessage()); -- cgit v1.2.3 From acf5b99434ab959feea8d6dd183b39b36e111814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 21:26:52 +0200 Subject: Update api lib --- .../org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java | 4 ++-- .../keychain/pgp/PgpDecryptVerifyResult.java | 10 +++++----- .../org/sufficientlysecure/keychain/remote/OpenPgpService.java | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 9a18fc5f0..6fa380357 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.pgp; import android.webkit.MimeTypeMap; -import org.openintents.openpgp.OpenPgpDecryptMetadata; +import org.openintents.openpgp.OpenPgpMetadata; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.openpgp.PGPCompressedData; import org.spongycastle.openpgp.PGPEncryptedData; @@ -485,7 +485,7 @@ public class PgpDecryptVerify { } } - OpenPgpDecryptMetadata metadata = new OpenPgpDecryptMetadata( + OpenPgpMetadata metadata = new OpenPgpMetadata( originalFilename, mimeType, literalData.getModificationTime().getTime(), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java index d16c6ecc0..506f48c52 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyResult.java @@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.pgp; import android.os.Parcel; import android.os.Parcelable; -import org.openintents.openpgp.OpenPgpDecryptMetadata; +import org.openintents.openpgp.OpenPgpMetadata; import org.openintents.openpgp.OpenPgpSignatureResult; public class PgpDecryptVerifyResult implements Parcelable { @@ -32,7 +32,7 @@ public class PgpDecryptVerifyResult implements Parcelable { long mKeyIdPassphraseNeeded; OpenPgpSignatureResult mSignatureResult; - OpenPgpDecryptMetadata mDecryptMetadata; + OpenPgpMetadata mDecryptMetadata; public int getStatus() { return mStatus; @@ -58,11 +58,11 @@ public class PgpDecryptVerifyResult implements Parcelable { mSignatureResult = signatureResult; } - public OpenPgpDecryptMetadata getDecryptMetadata() { + public OpenPgpMetadata getDecryptMetadata() { return mDecryptMetadata; } - public void setDecryptMetadata(OpenPgpDecryptMetadata decryptMetadata) { + public void setDecryptMetadata(OpenPgpMetadata decryptMetadata) { mDecryptMetadata = decryptMetadata; } @@ -95,7 +95,7 @@ public class PgpDecryptVerifyResult implements Parcelable { vr.mStatus = source.readInt(); vr.mKeyIdPassphraseNeeded = source.readLong(); vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); - vr.mDecryptMetadata = source.readParcelable(OpenPgpDecryptMetadata.class.getClassLoader()); + vr.mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader()); return vr; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 5c94f4796..365401584 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -25,7 +25,7 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; import org.openintents.openpgp.IOpenPgpService; -import org.openintents.openpgp.OpenPgpDecryptMetadata; +import org.openintents.openpgp.OpenPgpMetadata; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpApi; @@ -406,7 +406,7 @@ public class OpenPgpService extends RemoteService { } } - OpenPgpDecryptMetadata metadata = decryptVerifyResult.getDecryptMetadata(); + OpenPgpMetadata metadata = decryptVerifyResult.getDecryptMetadata(); if (metadata != null) { result.putExtra(OpenPgpApi.RESULT_METADATA, metadata); } -- cgit v1.2.3 From ae5e75f4e1e86831facc25fe97c1951b4a1aecee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 11 Aug 2014 23:57:11 +0200 Subject: Implement EXTRA_ORIGINAL_FILENAME for API --- .../org/sufficientlysecure/keychain/remote/OpenPgpService.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 365401584..da419b241 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -226,6 +226,10 @@ public class OpenPgpService extends RemoteService { boolean sign) { try { boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + String originalFilename = data.getStringExtra(OpenPgpApi.EXTRA_ORIGINAL_FILENAME); + if (originalFilename == null) { + originalFilename = ""; + } long[] keyIds; if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) { @@ -271,7 +275,8 @@ public class OpenPgpService extends RemoteService { builder.setEnableAsciiArmorOutput(asciiArmor) .setCompressionId(accSettings.getCompression()) .setSymmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm()) - .setEncryptionMasterKeyIds(keyIds); + .setEncryptionMasterKeyIds(keyIds) + .setOriginalFilename(originalFilename); if (sign) { String passphrase; -- cgit v1.2.3 From 4fdf9ab48608c02e7673cacd20e732fb9eaa08a7 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 12 Aug 2014 12:57:08 +0200 Subject: Only show keyrings that have a valid sign key in from field, fixes #756 --- .../keychain/ui/EncryptAsymmetricFragment.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 3de617ca0..67adbc136 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -145,24 +145,16 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi KeyRings.MASTER_KEY_ID, KeyRings.KEY_ID, KeyRings.USER_ID, - KeyRings.EXPIRY, - KeyRings.IS_REVOKED, - // can certify info only related to master key - KeyRings.CAN_CERTIFY, // has sign may be any subkey KeyRings.HAS_SIGN, - KeyRings.HAS_ANY_SECRET, - KeyRings.HAS_SECRET + KeyRings.HAS_ANY_SECRET }; - String where = KeyRings.HAS_ANY_SECRET + " = 1"; + String where = KeyRings.HAS_ANY_SECRET + " = 1 AND " + KeyRings.HAS_SIGN + " NOT NULL"; // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. return new CursorLoader(getActivity(), baseUri, projection, where, null, null); - /*return new CursorLoader(getActivity(), KeyRings.buildUnifiedKeyRingsUri(), - new String[]{KeyRings.USER_ID, KeyRings.KEY_ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET}, SIGN_KEY_SELECTION, - null, null);*/ } @Override -- cgit v1.2.3 From a4a6314041ebd20b9945acf503817766c99473be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 12 Aug 2014 13:54:46 +0200 Subject: Fix API version support, update api lib --- .../java/org/sufficientlysecure/keychain/remote/OpenPgpService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index da419b241..c81b29a5e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -523,10 +523,12 @@ public class OpenPgpService extends RemoteService { // History of versions in org.openintents.openpgp.util.OpenPgpApi // we support 3 and 4 if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 3 - || data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 4) { + && data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 4) { Intent result = new Intent(); OpenPgpError error = new OpenPgpError - (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); + (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!\n" + + "used API version: " + data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) + "\n" + + "supported API versions: 3, 4"); result.putExtra(OpenPgpApi.RESULT_ERROR, error); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); return result; -- cgit v1.2.3 From 80674021b58395371f3dab31defb055b4ee0b288 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 12 Aug 2014 13:54:56 +0200 Subject: Add convenience method to unified keyrings to determine whether a keyring is expired, fix is_revoked for certain usages --- .../org/sufficientlysecure/keychain/provider/KeychainContract.java | 3 ++- .../org/sufficientlysecure/keychain/provider/KeychainProvider.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 56168847f..dd59f8603 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -105,8 +105,9 @@ public class KeychainContract { public static class KeyRings implements BaseColumns, KeysColumns, UserIdsColumns { public static final String MASTER_KEY_ID = KeysColumns.MASTER_KEY_ID; - public static final String IS_REVOKED = KeysColumns.IS_REVOKED; + public static final String IS_REVOKED = KeychainDatabase.Tables.KEYS + "." + KeysColumns.IS_REVOKED; public static final String VERIFIED = CertsColumns.VERIFIED; + public static final String IS_EXPIRED = "is_expired"; public static final String HAS_ANY_SECRET = "has_any_secret"; public static final String HAS_ENCRYPT = "has_encrypt"; public static final String HAS_SIGN = "has_sign"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index b651069e9..2b686b8ff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -271,6 +271,9 @@ public class KeychainProvider extends ContentProvider { "kE." + Keys.KEY_ID + " AS " + KeyRings.HAS_ENCRYPT); projectionMap.put(KeyRings.HAS_SIGN, "kS." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN); + projectionMap.put(KeyRings.IS_EXPIRED, + "(" + Tables.KEYS + "." + Keys.EXPIRY + " < " + new Date().getTime() / 1000 + ") AS " + + KeyRings.IS_EXPIRED); qb.setProjectionMap(projectionMap); // Need this as list so we can search in it -- cgit v1.2.3 From 82a41a2f7cf446d774408f08b26ebb69e7069109 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Tue, 12 Aug 2014 13:56:30 +0200 Subject: Only show relevant keys in encrypt, fix #756 #757 --- .../keychain/ui/EncryptAsymmetricFragment.java | 5 ++-- .../ui/widget/EncryptKeyCompletionView.java | 35 +++++++++++++++------- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 67adbc136..bc3b140c3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -145,12 +145,13 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi KeyRings.MASTER_KEY_ID, KeyRings.KEY_ID, KeyRings.USER_ID, - // has sign may be any subkey + KeyRings.IS_EXPIRED, KeyRings.HAS_SIGN, KeyRings.HAS_ANY_SECRET }; - String where = KeyRings.HAS_ANY_SECRET + " = 1 AND " + KeyRings.HAS_SIGN + " NOT NULL"; + String where = KeyRings.HAS_ANY_SECRET + " = 1 AND " + KeyRings.HAS_SIGN + " NOT NULL AND " + + KeyRings.IS_REVOKED + " = 0 AND " + KeyRings.IS_EXPIRED + " = 0"; // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index 7e762fe77..20b9570bb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -22,6 +22,7 @@ import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Rect; +import android.net.Uri; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; @@ -45,7 +46,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; -import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; @@ -113,9 +114,23 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks() { @Override public Loader onCreateLoader(int id, Bundle args) { - return new CursorLoader(getContext(), KeychainContract.KeyRings.buildUnifiedKeyRingsUri(), - new String[]{KeychainContract.KeyRings.HAS_ENCRYPT, KeychainContract.KeyRings.KEY_ID, KeychainContract.KeyRings.USER_ID, KeychainContract.KeyRings.FINGERPRINT}, - null, null, null); + // These are the rows that we will retrieve. + Uri baseUri = KeyRings.buildUnifiedKeyRingsUri(); + + String[] projection = new String[]{ + KeyRings._ID, + KeyRings.MASTER_KEY_ID, + KeyRings.KEY_ID, + KeyRings.USER_ID, + KeyRings.FINGERPRINT, + KeyRings.IS_EXPIRED, + KeyRings.HAS_ENCRYPT + }; + + String where = KeyRings.HAS_ENCRYPT + " NOT NULL AND " + KeyRings.IS_EXPIRED + " = 0 AND " + + KeyRings.IS_REVOKED + " = 0"; + + return new CursorLoader(getContext(), baseUri, projection, where, null, null); } @Override @@ -148,10 +163,8 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { ArrayList keys = new ArrayList(); while (cursor.moveToNext()) { try { - if (cursor.getInt(cursor.getColumnIndexOrThrow(KeychainContract.KeyRings.HAS_ENCRYPT)) != 0) { - EncryptionKey key = new EncryptionKey(cursor); - keys.add(key); - } + EncryptionKey key = new EncryptionKey(cursor); + keys.add(key); } catch (Exception e) { Log.w(Constants.TAG, e); return; @@ -174,10 +187,10 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { } public EncryptionKey(Cursor cursor) { - this(cursor.getString(cursor.getColumnIndexOrThrow(KeychainContract.KeyRings.USER_ID)), - cursor.getLong(cursor.getColumnIndexOrThrow(KeychainContract.KeyRings.KEY_ID)), + this(cursor.getString(cursor.getColumnIndexOrThrow(KeyRings.USER_ID)), + cursor.getLong(cursor.getColumnIndexOrThrow(KeyRings.KEY_ID)), PgpKeyHelper.convertFingerprintToHex( - cursor.getBlob(cursor.getColumnIndexOrThrow(KeychainContract.KeyRings.FINGERPRINT)))); + cursor.getBlob(cursor.getColumnIndexOrThrow(KeyRings.FINGERPRINT)))); } -- cgit v1.2.3 From fd055a893be2bcc75dfb2ef768479e8536df6ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 12 Aug 2014 17:04:11 +0200 Subject: Fix DECRYPT_METADATA api --- .../keychain/remote/OpenPgpService.java | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index c81b29a5e..50c8fcf3b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -213,6 +213,7 @@ public class OpenPgpService extends RemoteService { result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); return result; } catch (Exception e) { + Log.d(Constants.TAG, "signImpl", e); Intent result = new Intent(); result.putExtra(OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); @@ -323,6 +324,7 @@ public class OpenPgpService extends RemoteService { result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); return result; } catch (Exception e) { + Log.d(Constants.TAG, "encryptAndSignImpl", e); Intent result = new Intent(); result.putExtra(OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); @@ -337,7 +339,13 @@ public class OpenPgpService extends RemoteService { try { // Get Input- and OutputStream from ParcelFileDescriptor InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); - OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + + OutputStream os; + if (decryptMetadataOnly) { + os = null; + } else { + os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + } Intent result = new Intent(); try { @@ -357,10 +365,12 @@ public class OpenPgpService extends RemoteService { }, inputData, os ); - builder.setAllowSymmetricDecryption(false) // no support for symmetric encryption - .setAllowedKeyIds(allowedKeyIds) // allow only private keys associated with - // accounts of this app - .setPassphrase(passphrase) + + // allow only private keys associated with accounts of this app + // no support for symmetric encryption + builder.setPassphrase(passphrase) + .setAllowSymmetricDecryption(false) + .setAllowedKeyIds(allowedKeyIds) .setDecryptMetadataOnly(decryptMetadataOnly); PgpDecryptVerifyResult decryptVerifyResult; @@ -386,8 +396,7 @@ public class OpenPgpService extends RemoteService { Intent passphraseBundle = getPassphraseBundleIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded()); return passphraseBundle; - } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == - decryptVerifyResult.getStatus()) { + } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) { throw new PgpGeneralException("Decryption of symmetric content not supported by API!"); } @@ -418,12 +427,15 @@ public class OpenPgpService extends RemoteService { } finally { is.close(); - os.close(); + if (os != null) { + os.close(); + } } result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); return result; } catch (Exception e) { + Log.d(Constants.TAG, "decryptAndVerifyImpl", e); Intent result = new Intent(); result.putExtra(OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); @@ -473,6 +485,7 @@ public class OpenPgpService extends RemoteService { return result; } } catch (Exception e) { + Log.d(Constants.TAG, "getKeyImpl", e); Intent result = new Intent(); result.putExtra(OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); @@ -493,7 +506,6 @@ public class OpenPgpService extends RemoteService { return result; } else { // get key ids based on given user ids - String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); Intent result = getKeyIdsFromEmails(data, userIds); return result; -- cgit v1.2.3 From e8b7bbd978c9a832b6ac34a0039cf0fc8feb99b9 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Wed, 13 Aug 2014 12:48:02 +0200 Subject: fix message and uri from encrypt intent --- .../org/sufficientlysecure/keychain/ui/EncryptActivity.java | 12 ++++-------- .../sufficientlysecure/keychain/ui/EncryptFileFragment.java | 10 ---------- 2 files changed, 4 insertions(+), 18 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index b140c5a03..6f4db88e8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -83,8 +83,6 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn // tabs Bundle mAsymmetricFragmentBundle = new Bundle(); Bundle mSymmetricFragmentBundle = new Bundle(); - Bundle mMessageFragmentBundle = new Bundle(); - Bundle mFileFragmentBundle = new Bundle(); int mSwitchToMode = PAGER_MODE_ASYMMETRIC; int mSwitchToContent = PAGER_CONTENT_MESSAGE; @@ -509,10 +507,8 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn mSymmetricFragmentBundle, getString(R.string.label_symmetric)); mViewPagerMode.setCurrentItem(mSwitchToMode); - mTabsAdapterContent.addTab(EncryptMessageFragment.class, - mMessageFragmentBundle, getString(R.string.label_message)); - mTabsAdapterContent.addTab(EncryptFileFragment.class, - mFileFragmentBundle, getString(R.string.label_files)); + mTabsAdapterContent.addTab(EncryptMessageFragment.class, null, getString(R.string.label_message)); + mTabsAdapterContent.addTab(EncryptFileFragment.class, null, getString(R.string.label_files)); mViewPagerContent.setCurrentItem(mSwitchToContent); mUseArmor = Preferences.getPreferences(this).getDefaultAsciiArmor(); @@ -619,11 +615,11 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn */ if (ACTION_ENCRYPT.equals(action) && textData != null) { // encrypt text based on given extra - mMessageFragmentBundle.putString(EncryptMessageFragment.ARG_TEXT, textData); + mMessage = textData; mSwitchToContent = PAGER_CONTENT_MESSAGE; } else if (ACTION_ENCRYPT.equals(action) && uris != null && !uris.isEmpty()) { // encrypt file based on Uri - mFileFragmentBundle.putParcelableArrayList(EncryptFileFragment.ARG_URIS, uris); + mInputUris = uris; mSwitchToContent = PAGER_CONTENT_FILE; } else if (ACTION_ENCRYPT.equals(action)) { Log.e(Constants.TAG, diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index 8a9e17020..14d3d1c4a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -111,8 +111,6 @@ public class EncryptFileFragment extends Fragment implements EncryptActivityInte @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - - addInputUris(getArguments().getParcelableArrayList(ARG_URIS)); } private void addInputUri() { @@ -125,14 +123,6 @@ public class EncryptFileFragment extends Fragment implements EncryptActivityInte } } - private void addInputUris(List uris) { - if (uris != null) { - for (Uri uri : uris) { - addInputUri(uri); - } - } - } - private void addInputUri(Uri inputUri) { if (inputUri == null) { return; -- cgit v1.2.3 From f34597a3c06d4ef6a096939237431aef6c2a3f96 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Wed, 13 Aug 2014 13:02:30 +0200 Subject: remove bundle for symmetric/asymmetric fragment as it was useless --- .../keychain/ui/EncryptActivity.java | 18 ++++---------- .../keychain/ui/EncryptAsymmetricFragment.java | 29 ++++++++-------------- 2 files changed, 16 insertions(+), 31 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 6f4db88e8..33deddd81 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -81,8 +81,6 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn PagerTabStripAdapter mTabsAdapterContent; // tabs - Bundle mAsymmetricFragmentBundle = new Bundle(); - Bundle mSymmetricFragmentBundle = new Bundle(); int mSwitchToMode = PAGER_MODE_ASYMMETRIC; int mSwitchToContent = PAGER_CONTENT_MESSAGE; @@ -91,7 +89,7 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn private static final int PAGER_CONTENT_MESSAGE = 0; private static final int PAGER_CONTENT_FILE = 1; - // model used by message and file fragments + // model used by fragments private long mEncryptionKeyIds[] = null; private String mEncryptionUserIds[] = null; private long mSigningKeyId = Constants.key.none; @@ -501,10 +499,8 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn // Handle intent actions handleActions(getIntent()); - mTabsAdapterMode.addTab(EncryptAsymmetricFragment.class, - mAsymmetricFragmentBundle, getString(R.string.label_asymmetric)); - mTabsAdapterMode.addTab(EncryptSymmetricFragment.class, - mSymmetricFragmentBundle, getString(R.string.label_symmetric)); + mTabsAdapterMode.addTab(EncryptAsymmetricFragment.class, null, getString(R.string.label_asymmetric)); + mTabsAdapterMode.addTab(EncryptSymmetricFragment.class, null, getString(R.string.label_symmetric)); mViewPagerMode.setCurrentItem(mSwitchToMode); mTabsAdapterContent.addTab(EncryptMessageFragment.class, null, getString(R.string.label_message)); @@ -600,14 +596,10 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn String textData = extras.getString(EXTRA_TEXT); - long signatureKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); - long[] encryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); + mSigningKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); + mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); // preselect keys given by intent - mAsymmetricFragmentBundle.putLongArray(EncryptAsymmetricFragment.ARG_ENCRYPTION_KEY_IDS, - encryptionKeyIds); - mAsymmetricFragmentBundle.putLong(EncryptAsymmetricFragment.ARG_SIGNATURE_KEY_ID, - signatureKeyId); mSwitchToMode = PAGER_MODE_ASYMMETRIC; /** diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index bc3b140c3..a402b6f68 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -123,14 +123,10 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - - long signatureKeyId = getArguments().getLong(ARG_SIGNATURE_KEY_ID); - long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS); - mProviderHelper = new ProviderHelper(getActivity()); - // preselect keys given by arguments (given by Intent to EncryptActivity) - preselectKeys(signatureKeyId, encryptionKeyIds, mProviderHelper); + // preselect keys given + preselectKeys(); getLoaderManager().initLoader(1, null, new LoaderManager.LoaderCallbacks() { @Override @@ -187,19 +183,15 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi /** * If an Intent gives a signatureMasterKeyId and/or encryptionMasterKeyIds, preselect those! - * - * @param preselectedSignatureKeyId - * @param preselectedEncryptionKeyIds */ - private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds, - ProviderHelper providerHelper) { + private void preselectKeys() { // TODO all of this works under the assumption that the first suitable subkey is always used! // not sure if we need to distinguish between different subkeys here? - if (preselectedSignatureKeyId != 0) { + long signatureKey = mEncryptInterface.getSignatureKey(); + if (signatureKey != Constants.key.none) { try { - CachedPublicKeyRing keyring = - providerHelper.getCachedPublicKeyRing( - KeyRings.buildUnifiedKeyRingUri(preselectedSignatureKeyId)); + CachedPublicKeyRing keyring = mProviderHelper.getCachedPublicKeyRing( + KeyRings.buildUnifiedKeyRingUri(signatureKey)); if(keyring.hasAnySecret()) { setSignatureKeyId(keyring.getMasterKeyId()); } @@ -208,10 +200,11 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi } } - if (preselectedEncryptionKeyIds != null) { - for (long preselectedId : preselectedEncryptionKeyIds) { + long[] encryptionKeyIds = mEncryptInterface.getEncryptionKeys(); + if (encryptionKeyIds != null) { + for (long preselectedId : encryptionKeyIds) { try { - CachedPublicKeyRing ring = providerHelper.getCachedPublicKeyRing( + CachedPublicKeyRing ring = mProviderHelper.getCachedPublicKeyRing( KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(preselectedId)); mEncryptKeyView.addObject(mEncryptKeyView.new EncryptionKey(ring)); } catch (PgpGeneralException e) { -- cgit v1.2.3 From 38da2af0e89ca05f2a01ed08801dee635784168e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 13 Aug 2014 16:37:28 +0200 Subject: Better error handling for passphrase cache if key is missing --- .../keychain/pgp/PgpDecryptVerify.java | 4 +- .../keychain/remote/OpenPgpService.java | 16 ++-- .../keychain/service/KeychainIntentService.java | 20 ++-- .../keychain/service/PassphraseCacheService.java | 101 ++++++++++++--------- .../keychain/ui/CertifyKeyActivity.java | 9 +- .../keychain/ui/EditKeyFragment.java | 10 +- .../keychain/ui/EncryptActivity.java | 26 +++--- 7 files changed, 115 insertions(+), 71 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java index 6fa380357..7d113241b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -163,7 +164,8 @@ public class PgpDecryptVerify { } public interface PassphraseCache { - public String getCachedPassphrase(long masterKeyId); + public String getCachedPassphrase(long masterKeyId) + throws NoSecretKeyException; } public static class InvalidDataException extends Exception { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 50c8fcf3b..1d3d7d02f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -168,8 +168,7 @@ public class OpenPgpService extends RemoteService { } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); - return passphraseBundle; + return getPassphraseBundleIntent(data, accSettings.getKeyId()); } // Get Input- and OutputStream from ParcelFileDescriptor @@ -289,8 +288,7 @@ public class OpenPgpService extends RemoteService { } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId()); - return passphraseBundle; + return getPassphraseBundleIntent(data, accSettings.getKeyId()); } // sign and encrypt @@ -358,9 +356,13 @@ public class OpenPgpService extends RemoteService { new ProviderHelper(this), new PgpDecryptVerify.PassphraseCache() { @Override - public String getCachedPassphrase(long masterKeyId) { - return PassphraseCacheService.getCachedPassphrase( - OpenPgpService.this, masterKeyId); + public String getCachedPassphrase(long masterKeyId) throws PgpDecryptVerify.NoSecretKeyException { + try { + return PassphraseCacheService.getCachedPassphrase( + OpenPgpService.this, masterKeyId); + } catch (PassphraseCacheService.KeyNotFoundException e) { + throw new PgpDecryptVerify.NoSecretKeyException(); + } } }, inputData, os diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 54895973b..443f66d58 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -307,9 +307,13 @@ public class KeychainIntentService extends IntentService new ProviderHelper(this), new PgpDecryptVerify.PassphraseCache() { @Override - public String getCachedPassphrase(long masterKeyId) { - return PassphraseCacheService.getCachedPassphrase( - KeychainIntentService.this, masterKeyId); + public String getCachedPassphrase(long masterKeyId) throws PgpDecryptVerify.NoSecretKeyException { + try { + return PassphraseCacheService.getCachedPassphrase( + KeychainIntentService.this, masterKeyId); + } catch (PassphraseCacheService.KeyNotFoundException e) { + throw new PgpDecryptVerify.NoSecretKeyException(); + } } }, inputData, outStream @@ -351,9 +355,13 @@ public class KeychainIntentService extends IntentService new ProviderHelper(this), new PgpDecryptVerify.PassphraseCache() { @Override - public String getCachedPassphrase(long masterKeyId) { - return PassphraseCacheService.getCachedPassphrase( - KeychainIntentService.this, masterKeyId); + public String getCachedPassphrase(long masterKeyId) throws PgpDecryptVerify.NoSecretKeyException { + try { + return PassphraseCacheService.getCachedPassphrase( + KeychainIntentService.this, masterKeyId); + } catch (PassphraseCacheService.KeyNotFoundException e) { + throw new PgpDecryptVerify.NoSecretKeyException(); + } } }, inputData, null diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java index e95e737d5..ae1b026a5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java @@ -76,12 +76,24 @@ public class PassphraseCacheService extends Service { private static final int NOTIFICATION_ID = 1; + private static final int MSG_PASSPHRASE_CACHE_GET_OKAY = 1; + private static final int MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND = 2; + private BroadcastReceiver mIntentReceiver; private LongSparseArray mPassphraseCache = new LongSparseArray(); Context mContext; + public static class KeyNotFoundException extends Exception { + public KeyNotFoundException() { + } + + public KeyNotFoundException(String name) { + super(name); + } + } + /** * This caches a new passphrase in memory by sending a new command to the service. An android * service is only run once. Thus, when the service is already started, new commands just add @@ -114,24 +126,23 @@ public class PassphraseCacheService extends Service { * @param keyId * @return passphrase or null (if no passphrase is cached for this keyId) */ - public static String getCachedPassphrase(Context context, long keyId) { + public static String getCachedPassphrase(Context context, long keyId) throws KeyNotFoundException { Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphrase() get masterKeyId for " + keyId); Intent intent = new Intent(context, PassphraseCacheService.class); intent.setAction(ACTION_PASSPHRASE_CACHE_GET); final Object mutex = new Object(); - final Bundle returnBundle = new Bundle(); + final Message returnMessage = Message.obtain(); HandlerThread handlerThread = new HandlerThread("getPassphraseThread"); handlerThread.start(); Handler returnHandler = new Handler(handlerThread.getLooper()) { @Override public void handleMessage(Message message) { - if (message.obj != null) { - String passphrase = ((Bundle) message.obj).getString(EXTRA_PASSPHRASE); - returnBundle.putString(EXTRA_PASSPHRASE, passphrase); - } + // copy over result to handle after mutex.wait + returnMessage.what = message.what; + returnMessage.copyFrom(message); synchronized (mutex) { mutex.notify(); } @@ -155,10 +166,13 @@ public class PassphraseCacheService extends Service { } } - if (returnBundle.containsKey(EXTRA_PASSPHRASE)) { - return returnBundle.getString(EXTRA_PASSPHRASE); - } else { - return null; + switch (returnMessage.what) { + case MSG_PASSPHRASE_CACHE_GET_OKAY: + return returnMessage.getData().getString(EXTRA_PASSPHRASE); + case MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND: + throw new KeyNotFoundException(); + default: + throw new KeyNotFoundException("should not happen!"); } } @@ -168,7 +182,7 @@ public class PassphraseCacheService extends Service { * @param keyId * @return */ - private String getCachedPassphraseImpl(long keyId) { + private String getCachedPassphraseImpl(long keyId) throws ProviderHelper.NotFoundException { // passphrase for symmetric encryption? if (keyId == Constants.key.symmetric) { Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphraseImpl() for symmetric encryption"); @@ -181,39 +195,33 @@ public class PassphraseCacheService extends Service { } // try to get master key id which is used as an identifier for cached passphrases - try { - Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphraseImpl() for masterKeyId " + keyId); - CanonicalizedSecretKeyRing key = new ProviderHelper(this).getCanonicalizedSecretKeyRing( - KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(keyId)); - // no passphrase needed? just add empty string and return it, then - if (!key.hasPassphrase()) { - Log.d(Constants.TAG, "Key has no passphrase! Caches and returns empty passphrase!"); - - try { - addCachedPassphrase(this, keyId, "", key.getPrimaryUserIdWithFallback()); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "PgpGeneralException occured"); - } - return ""; - } + Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphraseImpl() for masterKeyId " + keyId); + CanonicalizedSecretKeyRing key = new ProviderHelper(this).getCanonicalizedSecretKeyRing( + KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(keyId)); + // no passphrase needed? just add empty string and return it, then + if (!key.hasPassphrase()) { + Log.d(Constants.TAG, "Key has no passphrase! Caches and returns empty passphrase!"); - // get cached passphrase - CachedPassphrase cachedPassphrase = mPassphraseCache.get(keyId); - if (cachedPassphrase == null) { - Log.d(Constants.TAG, "PassphraseCacheService: Passphrase not (yet) cached, returning null"); - // not really an error, just means the passphrase is not cached but not empty either - return null; + try { + addCachedPassphrase(this, keyId, "", key.getPrimaryUserIdWithFallback()); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "PgpGeneralException occured"); } + return ""; + } - // set it again to reset the cache life cycle - Log.d(Constants.TAG, "PassphraseCacheService: Cache passphrase again when getting it!"); - addCachedPassphrase(this, keyId, cachedPassphrase.getPassphrase(), cachedPassphrase.getPrimaryUserID()); - return cachedPassphrase.getPassphrase(); - - } catch (ProviderHelper.NotFoundException e) { - Log.e(Constants.TAG, "PassphraseCacheService: Passphrase for unknown key was requested!"); + // get cached passphrase + CachedPassphrase cachedPassphrase = mPassphraseCache.get(keyId); + if (cachedPassphrase == null) { + Log.d(Constants.TAG, "PassphraseCacheService: Passphrase not (yet) cached, returning null"); + // not really an error, just means the passphrase is not cached but not empty either return null; } + + // set it again to reset the cache life cycle + Log.d(Constants.TAG, "PassphraseCacheService: Cache passphrase again when getting it!"); + addCachedPassphrase(this, keyId, cachedPassphrase.getPassphrase(), cachedPassphrase.getPrimaryUserID()); + return cachedPassphrase.getPassphrase(); } /** @@ -295,12 +303,19 @@ public class PassphraseCacheService extends Service { long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1); Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER); - String passphrase = getCachedPassphraseImpl(keyId); Message msg = Message.obtain(); - Bundle bundle = new Bundle(); - bundle.putString(EXTRA_PASSPHRASE, passphrase); - msg.obj = bundle; + try { + String passphrase = getCachedPassphraseImpl(keyId); + msg.what = MSG_PASSPHRASE_CACHE_GET_OKAY; + Bundle bundle = new Bundle(); + bundle.putString(EXTRA_PASSPHRASE, passphrase); + msg.setData(bundle); + } catch (ProviderHelper.NotFoundException e) { + Log.e(Constants.TAG, "PassphraseCacheService: Passphrase for unknown key was requested!"); + msg.what = MSG_PASSPHRASE_CACHE_GET_KEY_NO_FOUND; + } + try { messenger.send(msg); } catch (RemoteException e) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 467e0c14a..c1986825c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -231,7 +231,14 @@ public class CertifyKeyActivity extends ActionBarActivity implements */ private void initiateCertifying() { // get the user's passphrase for this key (if required) - String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); + String passphrase = null; + try { + passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); + } catch (PassphraseCacheService.KeyNotFoundException e) { + Log.e(Constants.TAG, "Key not found!", e); + finish(); + return; + } if (passphrase == null) { PassphraseDialogFragment.show(this, mMasterKeyId, new Handler() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index ae294547f..03074bb6a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -475,8 +475,14 @@ public class EditKeyFragment extends LoaderFragment implements } private void cachePassphraseForEdit() { - mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(getActivity(), - mSaveKeyringParcel.mMasterKeyId); + try { + mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(getActivity(), + mSaveKeyringParcel.mMasterKeyId); + } catch (PassphraseCacheService.KeyNotFoundException e) { + Log.e(Constants.TAG, "Key not found!", e); + getActivity().finish(); + return; + } if (mCurrentPassphrase == null) { PassphraseDialogFragment.show(getActivity(), mSaveKeyringParcel.mMasterKeyId, new Handler() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 33deddd81..7e08f6b7c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -450,20 +450,24 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn return false; } - if (mSigningKeyId != 0 && PassphraseCacheService.getCachedPassphrase(this, mSigningKeyId) == null) { - PassphraseDialogFragment.show(this, mSigningKeyId, - new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - // restart - startEncrypt(); + try { + if (mSigningKeyId != 0 && PassphraseCacheService.getCachedPassphrase(this, mSigningKeyId) == null) { + PassphraseDialogFragment.show(this, mSigningKeyId, + new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + // restart + startEncrypt(); + } } } - } - ); + ); - return false; + return false; + } + } catch (PassphraseCacheService.KeyNotFoundException e) { + Log.e(Constants.TAG, "Key not found!", e); } } return true; -- cgit v1.2.3 From db12f782f284e56dd3872ef4a16a49e037c6c078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 13 Aug 2014 18:48:42 +0200 Subject: API: User interaction when account keys are deleted --- .../keychain/provider/ProviderHelper.java | 2 +- .../keychain/remote/OpenPgpService.java | 8 ++- .../remote/ui/AccountSettingsActivity.java | 2 +- .../keychain/remote/ui/RemoteServiceActivity.java | 80 ++++++++++++++++------ 4 files changed, 67 insertions(+), 25 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 6111a4ef4..99b622f69 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -925,7 +925,7 @@ public class ProviderHelper { mContentResolver.insert(uri, contentValueForApiAccounts(accSettings)); } - public void updateApiAccount(AccountSettings accSettings, Uri uri) { + public void updateApiAccount(Uri uri, AccountSettings accSettings) { if (mContentResolver.update(uri, contentValueForApiAccounts(accSettings), null, null) <= 0) { throw new RuntimeException(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 1d3d7d02f..2f07f9785 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -164,7 +164,13 @@ public class OpenPgpService extends RemoteService { if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE); } else { - passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId()); + try { + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId()); + } catch (PassphraseCacheService.KeyNotFoundException e) { + // secret key that is set for this account is deleted? + // show account config again! + return getCreateAccountIntent(data, data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME)); + } } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java index 8f1f46c04..666252353 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java @@ -102,7 +102,7 @@ public class AccountSettingsActivity extends ActionBarActivity { } private void save() { - new ProviderHelper(this).updateApiAccount(mAccountSettingsFragment.getAccSettings(), mAccountUri); + new ProviderHelper(this).updateApiAccount(mAccountUri, mAccountSettingsFragment.getAccSettings()); finish(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java index d0b958844..48c76d561 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java @@ -18,11 +18,13 @@ package org.sufficientlysecure.keychain.remote.ui; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.ActionBarActivity; import android.view.View; +import android.widget.TextView; import org.openintents.openpgp.util.OpenPgpApi; import org.sufficientlysecure.htmltextview.HtmlTextView; @@ -37,6 +39,7 @@ import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; +import java.security.Provider; import java.util.ArrayList; public class RemoteServiceActivity extends ActionBarActivity { @@ -76,10 +79,17 @@ public class RemoteServiceActivity extends ActionBarActivity { // select pub keys view private SelectPublicKeyFragment mSelectFragment; + private ProviderHelper mProviderHelper; + + // for ACTION_CREATE_ACCOUNT + boolean mUpdateExistingAccount; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mProviderHelper = new ProviderHelper(this); + handleActions(getIntent(), savedInstanceState); } @@ -94,6 +104,14 @@ public class RemoteServiceActivity extends ActionBarActivity { final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName); + setContentView(R.layout.api_remote_register_app); + + mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_app_settings_fragment); + + AppSettings settings = new AppSettings(packageName, packageSignature); + mAppSettingsFragment.setAppSettings(settings); + // Inflate a "Done"/"Cancel" custom action bar view ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.api_register_allow, R.drawable.ic_action_done, @@ -102,8 +120,7 @@ public class RemoteServiceActivity extends ActionBarActivity { public void onClick(View v) { // Allow - new ProviderHelper(RemoteServiceActivity.this).insertApiApp( - mAppSettingsFragment.getAppSettings()); + mProviderHelper.insertApiApp(mAppSettingsFragment.getAppSettings()); // give data through for new service call Intent resultData = extras.getParcelable(EXTRA_DATA); @@ -120,18 +137,34 @@ public class RemoteServiceActivity extends ActionBarActivity { } } ); - - setContentView(R.layout.api_remote_register_app); - - mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById( - R.id.api_app_settings_fragment); - - AppSettings settings = new AppSettings(packageName, packageSignature); - mAppSettingsFragment.setAppSettings(settings); } else if (ACTION_CREATE_ACCOUNT.equals(action)) { final String packageName = extras.getString(EXTRA_PACKAGE_NAME); final String accName = extras.getString(EXTRA_ACC_NAME); + setContentView(R.layout.api_remote_create_account); + + mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById( + R.id.api_account_settings_fragment); + + TextView text = (TextView) findViewById(R.id.api_remote_create_account_text); + + // update existing? + Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(packageName, accName); + AccountSettings settings = mProviderHelper.getApiAccountSettings(uri); + if (settings == null) { + // create new account + settings = new AccountSettings(accName); + mUpdateExistingAccount = false; + + text.setText(R.string.api_create_account_text); + } else { + // update existing account + mUpdateExistingAccount = true; + + text.setText(R.string.api_update_account_text); + } + mAccSettingsFragment.setAccSettings(settings); + // Inflate a "Done"/"Cancel" custom action bar view ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.api_settings_save, R.drawable.ic_action_done, @@ -145,9 +178,17 @@ public class RemoteServiceActivity extends ActionBarActivity { mAccSettingsFragment.setErrorOnSelectKeyFragment( getString(R.string.api_register_error_select_key)); } else { - new ProviderHelper(RemoteServiceActivity.this).insertApiAccount( - KeychainContract.ApiAccounts.buildBaseUri(packageName), - mAccSettingsFragment.getAccSettings()); + if (mUpdateExistingAccount) { + Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(packageName); + Uri accountUri = baseUri.buildUpon().appendEncodedPath(accName).build(); + mProviderHelper.updateApiAccount( + accountUri, + mAccSettingsFragment.getAccSettings()); + } else { + mProviderHelper.insertApiAccount( + KeychainContract.ApiAccounts.buildBaseUri(packageName), + mAccSettingsFragment.getAccSettings()); + } // give data through for new service call Intent resultData = extras.getParcelable(EXTRA_DATA); @@ -166,13 +207,6 @@ public class RemoteServiceActivity extends ActionBarActivity { } ); - setContentView(R.layout.api_remote_create_account); - - mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById( - R.id.api_account_settings_fragment); - - AccountSettings settings = new AccountSettings(accName); - mAccSettingsFragment.setAccSettings(settings); } else if (ACTION_CACHE_PASSPHRASE.equals(action)) { long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID); final Intent resultData = extras.getParcelable(EXTRA_DATA); @@ -190,7 +224,8 @@ public class RemoteServiceActivity extends ActionBarActivity { RemoteServiceActivity.this.finish(); } - }); + } + ); } else if (ACTION_SELECT_PUB_KEYS.equals(action)) { long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS); @@ -286,7 +321,8 @@ public class RemoteServiceActivity extends ActionBarActivity { RemoteServiceActivity.this.setResult(RESULT_CANCELED); RemoteServiceActivity.this.finish(); } - }); + } + ); setContentView(R.layout.api_remote_error_message); -- cgit v1.2.3 From f941431d634b1e008726ce5501ffed55cb6899de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 13 Aug 2014 21:49:04 +0200 Subject: Add user info dialog --- .../keychain/ui/ViewKeyMainFragment.java | 28 +++++++ .../keychain/ui/adapter/UserIdsAdapter.java | 25 ++---- .../ui/dialog/UserIdInfoDialogFragment.java | 95 ++++++++++++++++++++++ 3 files changed, 128 insertions(+), 20 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/UserIdInfoDialogFragment.java (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 370a7312f..08243f06b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -22,17 +22,22 @@ import android.database.Cursor; import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.ImageView; import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract; @@ -41,6 +46,8 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; +import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Notify; @@ -88,9 +95,30 @@ public class ViewKeyMainFragment extends LoaderFragment implements PorterDuff.Mode.SRC_IN); mActionUpdate = view.findViewById(R.id.view_key_action_update); + mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + showUserIdInfo(position); + } + }); + return root; } + private void showUserIdInfo(final int position) { + final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position); + final int isVerified = mUserIdsAdapter.getIsVerified(position); + + DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { + public void run() { + UserIdInfoDialogFragment dialogFragment = + UserIdInfoDialogFragment.newInstance(isRevoked, isVerified); + + dialogFragment.show(getActivity().getSupportFragmentManager(), "userIdInfoDialog"); + } + }); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java index 9bf47a387..717dcf818 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java @@ -257,6 +257,11 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC return mCursor.getInt(INDEX_IS_REVOKED) > 0; } + public int getIsVerified(int position) { + mCursor.moveToPosition(position); + return mCursor.getInt(INDEX_VERIFIED); + } + public boolean getIsRevokedPending(int position) { mCursor.moveToPosition(position); String userId = mCursor.getString(INDEX_USER_ID); @@ -280,24 +285,4 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC return view; } - // Disable selection of items for lists without checkboxes, http://stackoverflow.com/a/4075045 - @Override - public boolean areAllItemsEnabled() { - if (mCheckStates == null && mSaveKeyringParcel == null) { - return false; - } else { - return super.areAllItemsEnabled(); - } - } - - // Disable selection of items for lists without checkboxes, http://stackoverflow.com/a/4075045 - @Override - public boolean isEnabled(int position) { - if (mCheckStates == null && mSaveKeyringParcel == null) { - return false; - } else { - return super.isEnabled(position); - } - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/UserIdInfoDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/UserIdInfoDialogFragment.java new file mode 100644 index 000000000..968b2429b --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/UserIdInfoDialogFragment.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui.dialog; + +import android.app.Activity; +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.KeychainContract; + +public class UserIdInfoDialogFragment extends DialogFragment { + private static final String ARG_IS_REVOKED = "is_revoked"; + private static final String ARG_IS_VERIFIED = "is_verified"; + + /** + * Creates new instance of this dialog fragment + */ + public static UserIdInfoDialogFragment newInstance(boolean isRevoked, int isVerified) { + UserIdInfoDialogFragment frag = new UserIdInfoDialogFragment(); + Bundle args = new Bundle(); + args.putBoolean(ARG_IS_REVOKED, isRevoked); + args.putInt(ARG_IS_VERIFIED, isVerified); + + frag.setArguments(args); + + return frag; + } + + /** + * Creates dialog + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Activity activity = getActivity(); + + int isVerified = getArguments().getInt(ARG_IS_VERIFIED); + boolean isRevoked = getArguments().getBoolean(ARG_IS_REVOKED); + + CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity); + + String title; + String message; + if (isRevoked) { + title = getString(R.string.user_id_info_revoked_title); + message = getString(R.string.user_id_info_revoked_text); + } else { + switch (isVerified) { + case KeychainContract.Certs.VERIFIED_SECRET: + title = getString(R.string.user_id_info_verified_title); + message = getString(R.string.user_id_info_verified_text); + break; + case KeychainContract.Certs.VERIFIED_SELF: + title = getString(R.string.user_id_info_not_verified_title); + message = getString(R.string.user_id_info_not_verified_text); + break; + default: + title = getString(R.string.user_id_info_invalid_title); + message = getString(R.string.user_id_info_invalid_text); + break; + } + } + + alert.setTitle(title); + alert.setMessage(message); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int id) { + dismiss(); + } + }); + + return alert.show(); + } + +} -- cgit v1.2.3 From b8f7dd5676db460c722276d4c98ca82e9d484562 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 14 Aug 2014 11:21:59 +0200 Subject: Handle keys without expiry date right Fixes #765 --- .../org/sufficientlysecure/keychain/provider/KeychainProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 2b686b8ff..c914cb5b7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -272,8 +272,8 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(KeyRings.HAS_SIGN, "kS." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN); projectionMap.put(KeyRings.IS_EXPIRED, - "(" + Tables.KEYS + "." + Keys.EXPIRY + " < " + new Date().getTime() / 1000 + ") AS " - + KeyRings.IS_EXPIRED); + "(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY + + " < " + new Date().getTime() / 1000 + ") AS " + KeyRings.IS_EXPIRED); qb.setProjectionMap(projectionMap); // Need this as list so we can search in it -- cgit v1.2.3 From d0987edab96573b210ce14432432248f609b14f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 11:44:47 +0200 Subject: Dont write version header by default --- .../org/sufficientlysecure/keychain/Constants.java | 2 +- .../keychain/helper/Preferences.java | 8 ++++---- .../org/sufficientlysecure/keychain/pgp/PgpHelper.java | 8 ++++---- .../keychain/pgp/PgpImportExport.java | 10 ++++++++-- .../keychain/pgp/PgpSignEncrypt.java | 14 ++++++++++---- .../keychain/pgp/UncachedKeyRing.java | 4 +++- .../keychain/provider/ProviderHelper.java | 5 ++++- .../keychain/remote/OpenPgpService.java | 4 ++-- .../keychain/service/KeychainIntentService.java | 2 +- .../keychain/ui/PreferencesActivity.java | 18 +++++++++--------- 10 files changed, 46 insertions(+), 29 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 05676c5d0..f240b5cc2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -67,7 +67,7 @@ public final class Constants { public static final String FORCE_V3_SIGNATURES = "forceV3Signatures"; public static final String KEY_SERVERS = "keyServers"; public static final String KEY_SERVERS_DEFAULT_VERSION = "keyServersDefaultVersion"; - public static final String CONCEAL_PGP_APPLICATION = "concealPgpApplication"; + public static final String WRITE_VERSION_HEADER = "writeVersionHeader"; public static final String FIRST_TIME = "firstTime"; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java index 00f6b6715..a0bac80aa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/Preferences.java @@ -205,13 +205,13 @@ public class Preferences { } } - public void setConcealPgpApplication(boolean conceal) { + public void setWriteVersionHeader(boolean conceal) { SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.putBoolean(Constants.Pref.CONCEAL_PGP_APPLICATION, conceal); + editor.putBoolean(Constants.Pref.WRITE_VERSION_HEADER, conceal); editor.commit(); } - public boolean getConcealPgpApplication() { - return mSharedPreferences.getBoolean(Constants.Pref.CONCEAL_PGP_APPLICATION, false); + public boolean getWriteVersionHeader() { + return mSharedPreferences.getBoolean(Constants.Pref.WRITE_VERSION_HEADER, false); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java index 0ceefc4d9..1cf027721 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpHelper.java @@ -60,11 +60,11 @@ public class PgpHelper { } } - public static String getFullVersion(Context context) { - if(Preferences.getPreferences(context).getConcealPgpApplication()){ - return ""; - } else { + public static String getVersionForHeader(Context context) { + if(Preferences.getPreferences(context).getWriteVersionHeader()){ return "OpenKeychain v" + getVersion(context); + } else { + return null; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java index 846b00ef2..f14eacda2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpImportExport.java @@ -230,7 +230,10 @@ public class PgpImportExport { progress++; // Create an output stream ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream); - arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext)); + String version = PgpHelper.getVersionForHeader(mContext); + if (version != null) { + arOutStream.setHeader("Version", version); + } updateProgress(progress * 100 / masterKeyIdsSize, 100); @@ -258,7 +261,10 @@ public class PgpImportExport { progress++; // Create an output stream ArmoredOutputStream arOutStream = new ArmoredOutputStream(outStream); - arOutStream.setHeader("Version", PgpHelper.getFullVersion(mContext)); + String version = PgpHelper.getVersionForHeader(mContext); + if (version != null) { + arOutStream.setHeader("Version", version); + } updateProgress(progress * 100 / masterKeyIdsSize, 100); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index 4973f64bb..b0e546662 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -109,11 +109,11 @@ public class PgpSignEncrypt { public static class Builder { // mandatory parameter private ProviderHelper mProviderHelper; - private String mVersionHeader; private InputData mData; private OutputStream mOutStream; // optional + private String mVersionHeader = null; private Progressable mProgressable = null; private boolean mEnableAsciiArmorOutput = false; private int mCompressionId = CompressionAlgorithmTags.UNCOMPRESSED; @@ -128,13 +128,17 @@ public class PgpSignEncrypt { private boolean mCleartextInput = false; private String mOriginalFilename = ""; - public Builder(ProviderHelper providerHelper, String versionHeader, InputData data, OutputStream outStream) { + public Builder(ProviderHelper providerHelper, InputData data, OutputStream outStream) { mProviderHelper = providerHelper; - mVersionHeader = versionHeader; mData = data; mOutStream = outStream; } + public Builder setVersionHeader(String versionHeader) { + mVersionHeader = versionHeader; + return this; + } + public Builder setProgressable(Progressable progressable) { mProgressable = progressable; return this; @@ -271,7 +275,9 @@ public class PgpSignEncrypt { OutputStream out; if (mEnableAsciiArmorOutput) { armorOut = new ArmoredOutputStream(mOutStream); - armorOut.setHeader("Version", mVersionHeader); + if (mVersionHeader != null) { + armorOut.setHeader("Version", mVersionHeader); + } out = armorOut; } else { out = mOutStream; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 18ddaa0ec..73a51942d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -204,7 +204,9 @@ public class UncachedKeyRing { public void encodeArmored(OutputStream out, String version) throws IOException { ArmoredOutputStream aos = new ArmoredOutputStream(out); - aos.setHeader("Version", version); + if (version != null) { + aos.setHeader("Version", version); + } aos.write(mRing.getEncoded()); aos.close(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 99b622f69..a13bb9c98 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -862,7 +862,10 @@ public class ProviderHelper { UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(data); ByteArrayOutputStream bos = new ByteArrayOutputStream(); - keyRing.encodeArmored(bos, PgpHelper.getFullVersion(mContext)); + String version = PgpHelper.getVersionForHeader(mContext); + if (version != null) { + keyRing.encodeArmored(bos, version); + } String armoredKey = bos.toString("UTF-8"); Log.d(Constants.TAG, "armoredKey:" + armoredKey); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 2f07f9785..3c2f7ebda 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -187,9 +187,9 @@ public class OpenPgpService extends RemoteService { // sign-only PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder( new ProviderHelper(getContext()), - PgpHelper.getFullVersion(getContext()), inputData, os); builder.setEnableAsciiArmorOutput(asciiArmor) + .setVersionHeader(PgpHelper.getVersionForHeader(this)) .setSignatureHashAlgorithm(accSettings.getHashAlgorithm()) .setSignatureForceV3(false) .setSignatureMasterKeyId(accSettings.getKeyId()) @@ -276,9 +276,9 @@ public class OpenPgpService extends RemoteService { PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder( new ProviderHelper(getContext()), - PgpHelper.getFullVersion(getContext()), inputData, os); builder.setEnableAsciiArmorOutput(asciiArmor) + .setVersionHeader(PgpHelper.getVersionForHeader(this)) .setCompressionId(accSettings.getCompression()) .setSymmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm()) .setEncryptionMasterKeyIds(keyIds) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 443f66d58..d1d848066 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -249,11 +249,11 @@ public class KeychainIntentService extends IntentService PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder( new ProviderHelper(this), - PgpHelper.getFullVersion(this), inputData, outStream); builder.setProgressable(this); builder.setEnableAsciiArmorOutput(useAsciiArmor) + .setVersionHeader(PgpHelper.getVersionForHeader(this)) .setCompressionId(compressionId) .setSymmetricEncryptionAlgorithm( Preferences.getPreferences(this).getDefaultEncryptionAlgorithm()) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java index e0261730d..5bef6cc9f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java @@ -122,8 +122,8 @@ public class PreferencesActivity extends PreferenceActivity { initializeForceV3Signatures( (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES)); - initializeConcealPgpApplication( - (CheckBoxPreference) findPreference(Constants.Pref.CONCEAL_PGP_APPLICATION)); + initializeWriteVersionHeader( + (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER)); } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { // Load the legacy preferences headers @@ -269,8 +269,8 @@ public class PreferencesActivity extends PreferenceActivity { initializeForceV3Signatures( (CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES)); - initializeConcealPgpApplication( - (CheckBoxPreference) findPreference(Constants.Pref.CONCEAL_PGP_APPLICATION)); + initializeWriteVersionHeader( + (CheckBoxPreference) findPreference(Constants.Pref.WRITE_VERSION_HEADER)); } } @@ -404,12 +404,12 @@ public class PreferencesActivity extends PreferenceActivity { }); } - private static void initializeConcealPgpApplication(final CheckBoxPreference mConcealPgpApplication) { - mConcealPgpApplication.setChecked(sPreferences.getConcealPgpApplication()); - mConcealPgpApplication.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + private static void initializeWriteVersionHeader(final CheckBoxPreference mWriteVersionHeader) { + mWriteVersionHeader.setChecked(sPreferences.getWriteVersionHeader()); + mWriteVersionHeader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { - mConcealPgpApplication.setChecked((Boolean) newValue); - sPreferences.setConcealPgpApplication((Boolean) newValue); + mWriteVersionHeader.setChecked((Boolean) newValue); + sPreferences.setWriteVersionHeader((Boolean) newValue); return false; } }); -- cgit v1.2.3 From 1a8606f194ec0a4ba54abb49f7e679e9283f6a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 13:08:39 +0200 Subject: API: Return metadata only for v4 api clients --- .../org/sufficientlysecure/keychain/remote/OpenPgpService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 3c2f7ebda..fd616f0cd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -428,9 +428,11 @@ public class OpenPgpService extends RemoteService { } } - OpenPgpMetadata metadata = decryptVerifyResult.getDecryptMetadata(); - if (metadata != null) { - result.putExtra(OpenPgpApi.RESULT_METADATA, metadata); + if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) == 4) { + OpenPgpMetadata metadata = decryptVerifyResult.getDecryptMetadata(); + if (metadata != null) { + result.putExtra(OpenPgpApi.RESULT_METADATA, metadata); + } } } finally { -- cgit v1.2.3 From 37edd0f390064e725d1b5c1c866a76c9922b0f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2014 13:10:38 +0200 Subject: API: Return metadata only for v4 api clients and above... --- .../java/org/sufficientlysecure/keychain/remote/OpenPgpService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index fd616f0cd..492ade7c3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -428,7 +428,7 @@ public class OpenPgpService extends RemoteService { } } - if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) == 4) { + if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) >= 4) { OpenPgpMetadata metadata = decryptVerifyResult.getDecryptMetadata(); if (metadata != null) { result.putExtra(OpenPgpApi.RESULT_METADATA, metadata); -- cgit v1.2.3