From 63774a063212cccb1e4b1476f79a5ff21582cd62 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 15 May 2017 16:22:03 +0200 Subject: [PATCH] use autovalue for CryptoInputParcel --- OpenKeychain/build.gradle | 1 + .../processing/ImportKeysListCloudLoader.java | 2 +- .../keychain/operations/BackupOperation.java | 2 +- .../operations/BenchmarkOperation.java | 4 +- .../KeybaseVerificationOperation.java | 2 +- .../keychain/operations/RevokeOperation.java | 2 +- .../pgp/PgpDecryptVerifyOperation.java | 5 +- .../keychain/pgp/PgpKeyOperation.java | 2 +- .../keychain/pgp/PgpSignEncryptData.java | 2 +- .../keychain/remote/OpenPgpService.java | 20 +- .../service/KeyserverSyncAdapterService.java | 4 +- .../service/input/CryptoInputParcel.java | 215 +++++++----------- .../keychain/ui/BackupCodeFragment.java | 5 +- .../keychain/ui/CertifyKeyFragment.java | 2 +- .../keychain/ui/CreateKeyFinalFragment.java | 2 +- ...reateSecurityTokenImportResetFragment.java | 2 +- .../keychain/ui/DeleteKeyDialogActivity.java | 2 +- .../keychain/ui/EditKeyFragment.java | 2 +- .../keychain/ui/EncryptFilesFragment.java | 8 +- .../keychain/ui/EncryptTextFragment.java | 6 +- .../ui/OrbotRequiredDialogActivity.java | 4 +- .../keychain/ui/PassphraseDialogActivity.java | 6 +- .../ui/SecurityTokenOperationActivity.java | 8 +- .../ui/base/CryptoOperationHelper.java | 2 +- .../keychain/util/ByteMapParcelAdapter.java | 35 +++ .../operations/BackupOperationTest.java | 9 +- .../operations/CertifyOperationTest.java | 10 +- .../keychain/pgp/InputDataOperationTest.java | 4 +- .../keychain/pgp/PgpEncryptDecryptTest.java | 70 +++--- .../keychain/pgp/PgpKeyOperationTest.java | 25 +- .../pgp/UncachedKeyringCanonicalizeTest.java | 2 +- .../pgp/UncachedKeyringMergeTest.java | 18 +- .../keychain/provider/InteropTest.java | 2 +- .../remote/KeychainExternalProviderTest.java | 2 +- .../jcajce/CachingDataDecryptorFactory.java | 25 +- 35 files changed, 256 insertions(+), 256 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ByteMapParcelAdapter.java diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 0bcf7b249..93c8f5c17 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -92,6 +92,7 @@ dependencies { provided "com.google.auto.value:auto-value:1.4.1" apt "com.google.auto.value:auto-value:1.4.1" apt "com.ryanharter.auto.value:auto-value-parcel:0.2.5" + compile 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.5' } // Output of ./gradlew -q calculateChecksums diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListCloudLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListCloudLoader.java index c1b287923..b236f0355 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListCloudLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListCloudLoader.java @@ -129,7 +129,7 @@ public class ImportKeysListCloudLoader mEntryList.clear(); GetKeyResult pendingResult = new GetKeyResult(null, RequiredInputParcel.createOrbotRequiredOperation(), - new CryptoInputParcel()); + CryptoInputParcel.createCryptoInputParcel()); mEntryListWrapper = new AsyncTaskResultWrapper<>(mEntryList, pendingResult); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java index f5b4ad1fc..924514cef 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java @@ -202,7 +202,7 @@ public class BackupOperation extends BaseOperation { outStream = mContext.getContentResolver().openOutputStream(backupInput.mOutputUri); } - return signEncryptOperation.execute(inputParcel, new CryptoInputParcel(), inputData, outStream); + return signEncryptOperation.execute(inputParcel, CryptoInputParcel.createCryptoInputParcel(), inputData, outStream); } boolean exportKeysToStream(OperationLog log, long[] masterKeyIds, boolean exportSecret, OutputStream outStream) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java index 6c8f3e276..5abfe463b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java @@ -88,7 +88,7 @@ public class BenchmarkOperation extends BaseOperation { data.setSymmetricEncryptionAlgorithm(OpenKeychainSymmetricKeyAlgorithmTags.AES_128); SignEncryptParcel input = new SignEncryptParcel(data.build()); input.setBytes(buf); - encryptResult = op.execute(input, new CryptoInputParcel()); + encryptResult = op.execute(input, CryptoInputParcel.createCryptoInputParcel()); log.add(encryptResult, 1); log.add(LogType.MSG_BENCH_ENC_TIME, 2, String.format("%.2f", encryptResult.getResults().get(0).mOperationTime / 1000.0)); @@ -107,7 +107,7 @@ public class BenchmarkOperation extends BaseOperation { new ProgressScaler(mProgressable, 50 +i*(50/numRepeats), 50 +(i+1)*(50/numRepeats), 100)); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(encryptResult.getResultBytes()); input.setAllowSymmetricDecryption(true); - decryptResult = op.execute(input, new CryptoInputParcel(passphrase)); + decryptResult = op.execute(input, CryptoInputParcel.createCryptoInputParcel(passphrase)); log.add(decryptResult, 1); log.add(LogType.MSG_BENCH_DEC_TIME, 2, String.format("%.2f", decryptResult.mOperationTime / 1000.0)); totalTime += decryptResult.mOperationTime; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java index d3dbd3dc7..89c48ad1b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java @@ -154,7 +154,7 @@ public class KeybaseVerificationOperation extends BaseOperation CryptoInputParcel cryptoInputParcel) { // we don't cache passphrases during revocation - cryptoInputParcel.mCachePassphrase = false; + cryptoInputParcel = cryptoInputParcel.withNoCachePassphrase(); long masterKeyId = revokeKeyringParcel.mMasterKeyId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java index 1ec57e727..99a7afcdb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -69,10 +69,9 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.LogTyp import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem.DecryptVerifySecurityProblemBuilder; -import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureBitStrength; +import org.sufficientlysecure.keychain.pgp.SecurityProblem.EncryptionAlgorithmProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem; import org.sufficientlysecure.keychain.pgp.SecurityProblem.MissingMdc; -import org.sufficientlysecure.keychain.pgp.SecurityProblem.EncryptionAlgorithmProblem; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; @@ -321,6 +320,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation cachedSessionKeys = decryptorFactory.getCachedSessionKeys(); - cryptoInput.addCryptoData(cachedSessionKeys); if (cachedSessionKeys.size() >= 1) { Entry entry = cachedSessionKeys.entrySet().iterator().next(); result.sessionKey = entry.getKey().array(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 73fc8c5a7..c8dfc783d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -336,7 +336,7 @@ public class PgpKeyOperation { masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator()); subProgressPush(50, 100); - CryptoInputParcel cryptoInput = new CryptoInputParcel(creationTime, new Passphrase("")); + CryptoInputParcel cryptoInput = CryptoInputParcel.createCryptoInputParcel(creationTime, new Passphrase("")); return internal(sKR, masterSecretKey, add.mFlags, add.mExpiry, cryptoInput, saveParcel, log, indent); } catch (PGPException e) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java index aba9f3c01..297f150ff 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2015 Dominik Schürmann - * Copyright (C) 2014 Vincent Breitmoser + * Copyright (C) 2017 Vincent Breitmoser * * 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 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 aa59d6a26..be3e76a32 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -154,12 +154,12 @@ public class OpenPgpService extends Service { CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data); if (inputParcel == null) { - inputParcel = new CryptoInputParcel(new Date()); + inputParcel = CryptoInputParcel.createCryptoInputParcel(new Date()); } // override passphrase in input parcel if given by API call if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { - inputParcel.mPassphrase = - new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)); + inputParcel = inputParcel.withPassphrase( + new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE))); } // execute PGP operation! @@ -265,11 +265,12 @@ public class OpenPgpService extends Service { CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data); if (inputParcel == null) { - inputParcel = new CryptoInputParcel(new Date()); + inputParcel = CryptoInputParcel.createCryptoInputParcel(new Date()); } // override passphrase in input parcel if given by API call if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { - inputParcel.mPassphrase = new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)); + inputParcel = inputParcel.withPassphrase( + new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE))); } // TODO this is not correct! @@ -352,17 +353,18 @@ public class OpenPgpService extends Service { CryptoInputParcel cryptoInput = CryptoInputParcelCacheService.getCryptoInputParcel(this, data); if (cryptoInput == null) { - cryptoInput = new CryptoInputParcel(); + cryptoInput = CryptoInputParcel.createCryptoInputParcel(); } // override passphrase in input parcel if given by API call if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) { - cryptoInput.mPassphrase = - new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)); + cryptoInput = cryptoInput.withPassphrase( + new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE))); } if (data.hasExtra(OpenPgpApi.EXTRA_DECRYPTION_RESULT)) { OpenPgpDecryptionResult decryptionResult = data.getParcelableExtra(OpenPgpApi.EXTRA_DECRYPTION_RESULT); if (decryptionResult != null && decryptionResult.hasDecryptedSessionKey()) { - cryptoInput.addCryptoData(decryptionResult.getSessionKey(), decryptionResult.getDecryptedSessionKey()); + cryptoInput = cryptoInput.withCryptoData( + decryptionResult.getSessionKey(), decryptionResult.getDecryptedSessionKey()); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java index b511f6293..9ff89df18 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java @@ -110,7 +110,7 @@ public class KeyserverSyncAdapterService extends Service { } case ACTION_UPDATE_ALL: { // does not check for screen on/off - asyncKeyUpdate(this, new CryptoInputParcel(), startId); + asyncKeyUpdate(this, CryptoInputParcel.createCryptoInputParcel(), startId); // we depend on handleUpdateResult to call stopSelf when it is no longer necessary // for the intent to be redelivered return START_REDELIVER_INTENT; @@ -118,7 +118,7 @@ public class KeyserverSyncAdapterService extends Service { case ACTION_IGNORE_TOR: { NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); manager.cancel(Constants.Notification.KEYSERVER_SYNC_FAIL_ORBOT); - asyncKeyUpdate(this, new CryptoInputParcel(ParcelableProxy.getForNoProxy()), + asyncKeyUpdate(this, CryptoInputParcel.createCryptoInputParcel(ParcelableProxy.getForNoProxy()), startId); // we depend on handleUpdateResult to call stopSelf when it is no longer necessary // for the intent to be redelivered diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java index 080c34c04..27907b24e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/CryptoInputParcel.java @@ -19,181 +19,128 @@ package org.sufficientlysecure.keychain.service.input; import java.nio.ByteBuffer; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; -import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.CheckResult; +import android.support.annotation.Nullable; +import com.google.auto.value.AutoValue; +import com.ryanharter.auto.value.parcel.ParcelAdapter; +import org.sufficientlysecure.keychain.util.ByteMapParcelAdapter; import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Passphrase; -/** - * This is a base class for the input of crypto operations. - */ -public class CryptoInputParcel implements Parcelable { +@AutoValue +public abstract class CryptoInputParcel implements Parcelable { + @Nullable + public abstract Date getSignatureTime(); + @Nullable + public abstract Passphrase getPassphrase(); + public abstract boolean isCachePassphrase(); - private Date mSignatureTime; - private boolean mHasSignature; + public boolean hasPassphrase() { + return getPassphrase() != null; + } - public Passphrase mPassphrase; // used to supply an explicit proxy to operations that require it // this is not final so it can be added to an existing CryptoInputParcel // (e.g) CertifyOperation with upload might require both passphrase and orbot to be enabled - private ParcelableProxy mParcelableProxy; - - // specifies whether passphrases should be cached - public boolean mCachePassphrase = true; + @Nullable + public abstract ParcelableProxy getParcelableProxy(); // this map contains both decrypted session keys and signed hashes to be // used in the crypto operation described by this parcel. - private HashMap mCryptoData = new HashMap<>(); + @ParcelAdapter(ByteMapParcelAdapter.class) + public abstract Map getCryptoData(); - public CryptoInputParcel() { - mSignatureTime = null; - mPassphrase = null; - mCachePassphrase = true; + + public static CryptoInputParcel createCryptoInputParcel() { + return new AutoValue_CryptoInputParcel(null, null, true, null, Collections.emptyMap()); } - public CryptoInputParcel(Date signatureTime, Passphrase passphrase) { - mHasSignature = true; - mSignatureTime = signatureTime == null ? new Date() : signatureTime; - mPassphrase = passphrase; - mCachePassphrase = true; - } - - public CryptoInputParcel(Passphrase passphrase) { - mPassphrase = passphrase; - mCachePassphrase = true; - } - - public CryptoInputParcel(Date signatureTime) { - mHasSignature = true; - mSignatureTime = signatureTime == null ? new Date() : signatureTime; - mPassphrase = null; - mCachePassphrase = true; - } - - public CryptoInputParcel(ParcelableProxy parcelableProxy) { - this(); - mParcelableProxy = parcelableProxy; - } - - public CryptoInputParcel(Date signatureTime, boolean cachePassphrase) { - mHasSignature = true; - mSignatureTime = signatureTime == null ? new Date() : signatureTime; - mPassphrase = null; - mCachePassphrase = cachePassphrase; - } - - public CryptoInputParcel(boolean cachePassphrase) { - mCachePassphrase = cachePassphrase; - } - - protected CryptoInputParcel(Parcel source) { - mHasSignature = source.readByte() != 0; - if (mHasSignature) { - mSignatureTime = new Date(source.readLong()); + public static CryptoInputParcel createCryptoInputParcel(Date signatureTime, Passphrase passphrase) { + if (signatureTime == null) { + signatureTime = new Date(); } - mPassphrase = source.readParcelable(getClass().getClassLoader()); - mParcelableProxy = source.readParcelable(getClass().getClassLoader()); - mCachePassphrase = source.readByte() != 0; + return new AutoValue_CryptoInputParcel(signatureTime, passphrase, true, null, + Collections.emptyMap()); + } - { - int count = source.readInt(); - mCryptoData = new HashMap<>(count); - for (int i = 0; i < count; i++) { - byte[] key = source.createByteArray(); - byte[] value = source.createByteArray(); - mCryptoData.put(ByteBuffer.wrap(key), value); - } + public static CryptoInputParcel createCryptoInputParcel(Passphrase passphrase) { + return new AutoValue_CryptoInputParcel(null, passphrase, true, null, Collections.emptyMap()); + } + + public static CryptoInputParcel createCryptoInputParcel(Date signatureTime) { + if (signatureTime == null) { + signatureTime = new Date(); } - + return new AutoValue_CryptoInputParcel(signatureTime, null, true, null, + Collections.emptyMap()); } - @Override - public int describeContents() { - return 0; + public static CryptoInputParcel createCryptoInputParcel(ParcelableProxy parcelableProxy) { + return new AutoValue_CryptoInputParcel(null, null, true, parcelableProxy, new HashMap()); } - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeByte((byte) (mHasSignature ? 1 : 0)); - if (mHasSignature) { - dest.writeLong(mSignatureTime.getTime()); - } - dest.writeParcelable(mPassphrase, 0); - dest.writeParcelable(mParcelableProxy, 0); - dest.writeByte((byte) (mCachePassphrase ? 1 : 0)); - - dest.writeInt(mCryptoData.size()); - for (HashMap.Entry entry : mCryptoData.entrySet()) { - dest.writeByteArray(entry.getKey().array()); - dest.writeByteArray(entry.getValue()); + public static CryptoInputParcel createCryptoInputParcel(Date signatureTime, boolean cachePassphrase) { + if (signatureTime == null) { + signatureTime = new Date(); } + return new AutoValue_CryptoInputParcel(signatureTime, null, cachePassphrase, null, + new HashMap()); } - public void addParcelableProxy(ParcelableProxy parcelableProxy) { - mParcelableProxy = parcelableProxy; + public static CryptoInputParcel createCryptoInputParcel(boolean cachePassphrase) { + return new AutoValue_CryptoInputParcel(null, null, cachePassphrase, null, new HashMap()); } - public void addSignatureTime(Date signatureTime) { - mSignatureTime = signatureTime; + // TODO get rid of this! + @CheckResult + public CryptoInputParcel withCryptoData(byte[] hash, byte[] signedHash) { + Map newCryptoData = new HashMap<>(getCryptoData()); + newCryptoData.put(ByteBuffer.wrap(hash), signedHash); + newCryptoData = Collections.unmodifiableMap(newCryptoData); + + return new AutoValue_CryptoInputParcel(getSignatureTime(), getPassphrase(), isCachePassphrase(), + getParcelableProxy(), newCryptoData); } - public void addCryptoData(byte[] hash, byte[] signedHash) { - mCryptoData.put(ByteBuffer.wrap(hash), signedHash); + @CheckResult + public CryptoInputParcel withCryptoData(Map cachedSessionKeys) { + Map newCryptoData = new HashMap<>(getCryptoData()); + newCryptoData.putAll(cachedSessionKeys); + newCryptoData = Collections.unmodifiableMap(newCryptoData); + + return new AutoValue_CryptoInputParcel(getSignatureTime(), getPassphrase(), isCachePassphrase(), + getParcelableProxy(), newCryptoData); } - public void addCryptoData(Map cachedSessionKeys) { - mCryptoData.putAll(cachedSessionKeys); + + @CheckResult + public CryptoInputParcel withPassphrase(Passphrase passphrase) { + return new AutoValue_CryptoInputParcel(getSignatureTime(), passphrase, isCachePassphrase(), + getParcelableProxy(), getCryptoData()); } - public ParcelableProxy getParcelableProxy() { - return mParcelableProxy; + @CheckResult + public CryptoInputParcel withNoCachePassphrase() { + return new AutoValue_CryptoInputParcel(getSignatureTime(), getPassphrase(), false, getParcelableProxy(), + getCryptoData()); } - public Map getCryptoData() { - return mCryptoData; + @CheckResult + public CryptoInputParcel withSignatureTime(Date signatureTime) { + return new AutoValue_CryptoInputParcel(signatureTime, getPassphrase(), isCachePassphrase(), + getParcelableProxy(), getCryptoData()); } - public Date getSignatureTime() { - return mSignatureTime; + @CheckResult + public CryptoInputParcel withParcelableProxy(ParcelableProxy parcelableProxy) { + return new AutoValue_CryptoInputParcel(getSignatureTime(), getPassphrase(), isCachePassphrase(), + parcelableProxy, getCryptoData()); } - - public boolean hasPassphrase() { - return mPassphrase != null; - } - - public Passphrase getPassphrase() { - return mPassphrase; - } - - public static final Creator CREATOR = new Creator() { - public CryptoInputParcel createFromParcel(final Parcel source) { - return new CryptoInputParcel(source); - } - - public CryptoInputParcel[] newArray(final int size) { - return new CryptoInputParcel[size]; - } - }; - - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - b.append("CryptoInput: { "); - b.append(mSignatureTime).append(" "); - if (mPassphrase != null) { - b.append("passphrase"); - } - if (mCryptoData != null) { - b.append(mCryptoData.size()); - b.append(" hashes "); - } - b.append("}"); - return b.toString(); - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java index 27264a498..3aee1542d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java @@ -523,7 +523,8 @@ public class BackupCodeFragment extends CryptoOperationFragment(2, this, callback, R.string.progress_modify); - mMoveToCardOpHelper.cryptoOperation(new CryptoInputParcel(new Date())); + mMoveToCardOpHelper.cryptoOperation(CryptoInputParcel.createCryptoInputParcel(new Date())); } private void uploadKey(final EditKeyResult saveKeyResult) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java index 691102627..eab4525a0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java @@ -235,7 +235,7 @@ public class CreateSecurityTokenImportResetFragment Intent intent = new Intent(getActivity(), SecurityTokenOperationActivity.class); RequiredInputParcel resetP = RequiredInputParcel.createSecurityTokenReset(); intent.putExtra(SecurityTokenOperationActivity.EXTRA_REQUIRED_INPUT, resetP); - intent.putExtra(SecurityTokenOperationActivity.EXTRA_CRYPTO_INPUT, new CryptoInputParcel()); + intent.putExtra(SecurityTokenOperationActivity.EXTRA_CRYPTO_INPUT, CryptoInputParcel.createCryptoInputParcel()); startActivityForResult(intent, REQUEST_CODE_RESET); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java index 21ee1f83a..c1c865312 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java @@ -139,7 +139,7 @@ public class DeleteKeyDialogActivity extends FragmentActivity { } private void startRevocationOperation() { - mRevokeOpHelper.cryptoOperation(new CryptoInputParcel(new Date(), false)); + mRevokeOpHelper.cryptoOperation(CryptoInputParcel.createCryptoInputParcel(new Date(), false)); } private void startDeletionOperation() { 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 eb6f97cc0..336916e3e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -156,7 +156,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment> { + @Override + public Map fromParcel(Parcel source) { + int count = source.readInt(); + Map result = new HashMap<>(count); + for (int i = 0; i < count; i++) { + byte[] key = source.createByteArray(); + byte[] value = source.createByteArray(); + result.put(ByteBuffer.wrap(key), value); + } + return Collections.unmodifiableMap(result); + } + + @Override + public void toParcel(Map value, Parcel dest) { + dest.writeInt(value.size()); + for (Map.Entry entry : value.entrySet()) { + dest.writeByteArray(entry.getKey().array()); + dest.writeByteArray(entry.getValue()); + } + } +} diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java index 87fd0a4cf..6d1ffb889 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java @@ -310,7 +310,7 @@ public class BackupOperationTest { BackupKeyringParcel parcel = new BackupKeyringParcel( new long[] { mStaticRing1.getMasterKeyId() }, false, true, true, fakeOutputUri); - CryptoInputParcel inputParcel = new CryptoInputParcel(passphrase); + CryptoInputParcel inputParcel = CryptoInputParcel.createCryptoInputParcel(passphrase); ExportResult result = op.execute(parcel, inputParcel); verify(mockResolver).openOutputStream(fakePipedUri); @@ -330,19 +330,20 @@ public class BackupOperationTest { input.setAllowSymmetricDecryption(true); { - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel()); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel()); assertTrue("decryption must return pending without passphrase", result.isPending()); Assert.assertTrue("should contain pending passphrase log entry", result.getLog().containsType(LogType.MSG_DC_PENDING_PASSPHRASE)); } { - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(new Passphrase("bad"))); + DecryptVerifyResult result = op.execute(input, + CryptoInputParcel.createCryptoInputParcel(new Passphrase("bad"))); assertFalse("decryption must fail with bad passphrase", result.success()); Assert.assertTrue("should contain bad passphrase log entry", result.getLog().containsType(LogType.MSG_DC_ERROR_SYM_PASSPHRASE)); } - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(passphrase)); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(passphrase)); assertTrue("decryption must succeed with passphrase", result.success()); assertEquals("backup filename should be backup_keyid.pub.asc", diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java index 2c4fd2f8c..0423a83b9 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java @@ -156,7 +156,7 @@ public class CertifyOperationTest { CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserIds(), null)); - CertifyResult result = op.execute(actions, new CryptoInputParcel(new Date(), mKeyPhrase1)); + CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertTrue("certification must succeed", result.success()); @@ -184,7 +184,7 @@ public class CertifyOperationTest { CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(), null, mStaticRing2.getPublicKey().getUnorderedUserAttributes())); - CertifyResult result = op.execute(actions, new CryptoInputParcel(new Date(), mKeyPhrase1)); + CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertTrue("certification must succeed", result.success()); @@ -207,7 +207,7 @@ public class CertifyOperationTest { actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserIds(), null)); - CertifyResult result = op.execute(actions, new CryptoInputParcel(new Date(), mKeyPhrase1)); + CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertFalse("certification with itself must fail!", result.success()); Assert.assertTrue("error msg must be about self certification", @@ -226,7 +226,7 @@ public class CertifyOperationTest { uids.add("nonexistent"); actions.add(new CertifyAction(1234L, uids, null)); - CertifyResult result = op.execute(actions, new CryptoInputParcel(new Date(), + CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertFalse("certification of nonexistent key must fail", result.success()); @@ -239,7 +239,7 @@ public class CertifyOperationTest { actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserIds(), null)); - CertifyResult result = op.execute(actions, new CryptoInputParcel(new Date(), + CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertFalse("certification of nonexistent key must fail", result.success()); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java index 2c1c2ba4b..96518f125 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java @@ -130,7 +130,7 @@ public class InputDataOperationTest { InputDataParcel input = new InputDataParcel(fakeInputUri, null); - InputDataResult result = op.execute(input, new CryptoInputParcel()); + InputDataResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel()); // must be successful, no verification, have two output URIs Assert.assertTrue(result.success()); @@ -309,7 +309,7 @@ public class InputDataOperationTest { KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); InputDataParcel input = new InputDataParcel(FAKE_CONTENT_INPUT_URI_1, null); - return op.execute(input, new CryptoInputParcel()); + return op.execute(input, CryptoInputParcel.createCryptoInputParcel()); } } diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java index d058aa988..32b239595 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -184,7 +184,7 @@ public class PgpEncryptDecryptTest { PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()), + PgpSignEncryptResult result = op.execute(b, CryptoInputParcel.createCryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); @@ -203,7 +203,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); input.setAllowSymmetricDecryption(true); DecryptVerifyResult result = op.execute( - input, new CryptoInputParcel(mSymmetricPassphrase), data, out); + input, CryptoInputParcel.createCryptoInputParcel(mSymmetricPassphrase), data, out); Assert.assertTrue("decryption must succeed", result.success()); Assert.assertArrayEquals("decrypted ciphertext should equal plaintext", @@ -233,7 +233,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); input.setAllowSymmetricDecryption(true); DecryptVerifyResult result = op.execute(input, - new CryptoInputParcel(new Passphrase(new String(mSymmetricPassphrase.getCharArray()) + "x")), + CryptoInputParcel.createCryptoInputParcel(new Passphrase(new String(mSymmetricPassphrase.getCharArray()) + "x")), data, out); Assert.assertFalse("decryption must fail", result.success()); @@ -255,7 +255,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); input.setAllowSymmetricDecryption(true); DecryptVerifyResult result = op.execute(input, - new CryptoInputParcel(), data, out); + CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertFalse("decryption must fail", result.success()); Assert.assertEquals("decrypted plaintext should be empty", 0, out.size()); @@ -276,7 +276,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); input.setAllowSymmetricDecryption(false); DecryptVerifyResult result = op.execute(input, - new CryptoInputParcel(), data, out); + CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertFalse("decryption must fail", result.success()); Assert.assertEquals("decrypted plaintext should be empty", 0, out.size()); @@ -312,7 +312,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("signing must succeed", result.success()); ciphertext = out.toByteArray(); @@ -326,7 +326,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("verification must succeed", result.success()); Assert.assertArrayEquals("verification text should equal plaintext", @@ -369,7 +369,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("signing must succeed", result.success()); ciphertext = out.toByteArray(); @@ -386,7 +386,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("verification must succeed", result.success()); @@ -429,7 +429,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("signing must succeed", result.success()); detachedSignature = result.getDetachedSignature(); @@ -444,7 +444,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); input.setDetachedSignature(detachedSignature); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("verification must succeed", result.success()); Assert.assertArrayEquals("verification text should equal plaintext (save for a newline)", @@ -485,7 +485,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), + PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); @@ -500,7 +500,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("decryption with provided passphrase must succeed", result.success()); Assert.assertArrayEquals("decrypted ciphertext with provided passphrase should equal plaintext", @@ -529,7 +529,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); CryptoInputParcel cryptoInput = result.getCachedCryptoInputParcel(); Assert.assertEquals("must have one cached session key", @@ -553,7 +553,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( null, mStaticRing1.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertFalse("decryption with no passphrase must return pending", result.success()); Assert.assertTrue("decryption with no passphrase should return pending", result.isPending()); @@ -588,7 +588,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), + PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); @@ -626,7 +626,7 @@ public class PgpEncryptDecryptTest { parcel.mChangeSubKeys.add(new SubkeyChange(encKeyId1, true, false)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList(), new ArrayList(), - new CryptoInputParcel(new Date(), mKeyPhrase1)); + CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); KeyWritableRepository databaseInteractor = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application); @@ -635,7 +635,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(ciphertext); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1)); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1)); Assert.assertTrue("decryption must succeed", result.success()); Assert.assertTrue("decryption must have skipped first key", @@ -649,7 +649,7 @@ public class PgpEncryptDecryptTest { parcel.mChangeSubKeys.add(new SubkeyChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList(), new ArrayList(), - new CryptoInputParcel(new Date(), mKeyPhrase1)); + CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); KeyWritableRepository databaseInteractor = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application); @@ -658,7 +658,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(ciphertext); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1)); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1)); Assert.assertTrue("decryption must succeed", result.success()); Assert.assertTrue("decryption must have skipped first key", @@ -677,7 +677,7 @@ public class PgpEncryptDecryptTest { parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(mStaticRing1, 2)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList(), new ArrayList(), - new CryptoInputParcel(new Date(), mKeyPhrase1)); + CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); KeyWritableRepository databaseInteractor = KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application); @@ -701,7 +701,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), + PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); @@ -749,7 +749,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()), + PgpSignEncryptResult result = op.execute(b, CryptoInputParcel.createCryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); @@ -765,7 +765,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success()); Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", @@ -795,7 +795,7 @@ public class PgpEncryptDecryptTest { mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); input.setAllowedKeyIds(allowed); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed for allowed key", result.success()); Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", @@ -818,7 +818,7 @@ public class PgpEncryptDecryptTest { mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); input.setAllowedKeyIds(new HashSet()); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertFalse("decryption must fail if no key allowed", result.success()); Assert.assertEquals("decryption must fail with key disllowed status", @@ -840,7 +840,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed", result.success()); Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", @@ -881,7 +881,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(b, - new CryptoInputParcel(new Date(), mKeyPhrase1), data, out); + CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1), data, out); Assert.assertTrue("encryption must succeed", result.success()); ciphertext = out.toByteArray(); @@ -896,7 +896,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success()); Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", @@ -923,7 +923,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed", result.success()); Assert.assertArrayEquals("decrypted ciphertext with cached passphrase should equal plaintext", @@ -965,7 +965,7 @@ public class PgpEncryptDecryptTest { PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); - PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()), + PgpSignEncryptResult result = op.execute(b, CryptoInputParcel.createCryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); @@ -980,7 +980,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("decryption with provided passphrase must succeed", result.success()); Assert.assertArrayEquals("decrypted ciphertext should equal plaintext bytes", @@ -1008,7 +1008,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue(result.success()); @@ -1031,7 +1031,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue(result.success()); @@ -1052,7 +1052,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(), data, out); + DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue(result.success()); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java index 7e0fa413d..3d48e3a3e 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -119,7 +119,7 @@ public class PgpKeyOperationTest { // we sleep here for a second, to make sure all new certificates have different timestamps Thread.sleep(1000); - cryptoInput = new CryptoInputParcel(new Date(), passphrase); + cryptoInput = CryptoInputParcel.createCryptoInputParcel(new Date(), passphrase); } @@ -327,7 +327,7 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("allure"); assertModifyFailure("keyring modification with bad passphrase should fail", - ring, parcel, new CryptoInputParcel(badphrase), LogType.MSG_MF_UNLOCK_ERROR); + ring, parcel, CryptoInputParcel.createCryptoInputParcel(badphrase), LogType.MSG_MF_UNLOCK_ERROR); } { @@ -685,7 +685,7 @@ public class PgpKeyOperationTest { parcel.mRevokeSubKeys.add(keyId); modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, - new CryptoInputParcel(new Date(), passphrase)); + CryptoInputParcel.createCryptoInputParcel(new Date(), passphrase)); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); @@ -805,7 +805,8 @@ public class PgpKeyOperationTest { { // we should be able to change the stripped status of subkeys without passphrase parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false)); - modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, new CryptoInputParcel()); + modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, + CryptoInputParcel.createCryptoInputParcel()); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertEquals("new packet should have GNU_DUMMY S2K type", @@ -885,8 +886,8 @@ public class PgpKeyOperationTest { 0x6a, 0x6f, 0x6c, 0x6f, 0x73, 0x77, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - CryptoInputParcel inputParcel = new CryptoInputParcel(); - inputParcel.addCryptoData(keyIdBytes, serial); + CryptoInputParcel inputParcel = CryptoInputParcel.createCryptoInputParcel(); + inputParcel = inputParcel.withCryptoData(keyIdBytes, serial); modified = applyModificationWithChecks(parcelSecurityToken, ringSecurityToken, onlyA, onlyB, inputParcel); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); @@ -1082,7 +1083,7 @@ public class PgpKeyOperationTest { // applying the same modification AGAIN should not add more certifications but drop those // as duplicates modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, - new CryptoInputParcel(new Date(), passphrase), true, false); + CryptoInputParcel.createCryptoInputParcel(new Date(), passphrase), true, false); Assert.assertEquals("duplicate modification: one extra packet in original", 1, onlyA.size()); Assert.assertEquals("duplicate modification: one extra packet in modified", 1, onlyB.size()); @@ -1158,10 +1159,10 @@ public class PgpKeyOperationTest { // modify keyring, change to non-empty passphrase Passphrase otherPassphrase = TestingUtils.genPassphrase(true); - CryptoInputParcel otherCryptoInput = new CryptoInputParcel(otherPassphrase); + CryptoInputParcel otherCryptoInput = CryptoInputParcel.createCryptoInputParcel(otherPassphrase); parcel.setNewUnlock(new ChangeUnlockParcel(otherPassphrase)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, - new CryptoInputParcel(new Date(), new Passphrase())); + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase())); Assert.assertEquals("exactly three packets should have been modified (the secret keys)", 3, onlyB.size()); @@ -1210,7 +1211,8 @@ public class PgpKeyOperationTest { PgpKeyOperation op = new PgpKeyOperation(null); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0); - PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(otherPassphrase2), parcel); + PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(otherPassphrase2), parcel); Assert.assertTrue("key modification must succeed", result.success()); Assert.assertTrue("log must contain a failed passphrase change warning", result.getLog().containsType(LogType.MSG_MF_PASSPHRASE_FAIL)); @@ -1225,7 +1227,8 @@ public class PgpKeyOperationTest { parcel.mAddUserIds.add("discord"); PgpKeyOperation op = new PgpKeyOperation(null); - PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date()), parcel); + PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(new Date()), parcel); Assert.assertFalse("non-restricted operations should fail without passphrase", result.success()); } diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java index 7265282ef..c835d2449 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -549,7 +549,7 @@ public class UncachedKeyringCanonicalizeTest { CanonicalizedSecretKey masterSecretKey = canonicalized.getSecretKey(); masterSecretKey.unlock(new Passphrase()); PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey(); - CryptoInputParcel cryptoInput = new CryptoInputParcel(new Date()); + CryptoInputParcel cryptoInput = CryptoInputParcel.createCryptoInputParcel(new Date()); PGPSignature cert = PgpKeyOperation.generateSubkeyBindingSignature( PgpKeyOperation.getSignatureGenerator(masterSecretKey.getSecretKey(), cryptoInput), cryptoInput.getSignatureTime(), diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index 5c4a6514d..b8a1e3525 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -189,11 +189,13 @@ public class UncachedKeyringMergeTest { parcel.reset(); parcel.mAddUserIds.add("flim"); - modifiedA = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + modifiedA = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); parcel.reset(); parcel.mAddUserIds.add("flam"); - modifiedB = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + modifiedB = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); } { // merge A into base @@ -230,8 +232,10 @@ public class UncachedKeyringMergeTest { parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - modifiedA = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); - modifiedB = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + modifiedA = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + modifiedB = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); subKeyIdA = KeyringTestingHelper.getSubkeyId(modifiedA, 2); subKeyIdB = KeyringTestingHelper.getSubkeyId(modifiedB, 2); @@ -272,7 +276,8 @@ public class UncachedKeyringMergeTest { parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(ringA, 1)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing( ringA.getEncoded(), 0); - modified = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + modified = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); } { @@ -371,7 +376,8 @@ public class UncachedKeyringMergeTest { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing( ringA.getEncoded(), 0); - modified = op.modifySecretKeyRing(secretRing, new CryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + modified = op.modifySecretKeyRing(secretRing, + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); } { diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/provider/InteropTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/provider/InteropTest.java index 9d5a6a919..1220d1a8d 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/provider/InteropTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/provider/InteropTest.java @@ -144,7 +144,7 @@ public class InteropTest { PgpDecryptVerifyOperation op = makeOperation(base.toString(), pass, decrypt, verify); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - CryptoInputParcel cip = new CryptoInputParcel(pass); + CryptoInputParcel cip = CryptoInputParcel.createCryptoInputParcel(pass); DecryptVerifyResult result = op.execute(input, cip, data, out); byte[] plaintext = config.getString("textcontent").getBytes("utf-8"); String filename = config.getString("filename"); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java index 493e1f2a6..deb94f439 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java @@ -198,7 +198,7 @@ public class KeychainExternalProviderTest { certifyActionsParcel.add(new CertifyAction(publicMasterKeyId, Collections.singletonList(userId), null)); CertifyOperation op = new CertifyOperation( RuntimeEnvironment.application, databaseInteractor, new ProgressScaler(), null); - CertifyResult certifyResult = op.execute(certifyActionsParcel, new CryptoInputParcel()); + CertifyResult certifyResult = op.execute(certifyActionsParcel, CryptoInputParcel.createCryptoInputParcel()); assertTrue(certifyResult.success()); } diff --git a/libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java b/libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java index 7679f8486..d558ba9b1 100644 --- a/libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java +++ b/libkeychain/src/main/java/org/bouncycastle/openpgp/operator/jcajce/CachingDataDecryptorFactory.java @@ -1,5 +1,6 @@ -/** +/* * Copyright (c) 2013-2014 Philipp Jakubeit, Signe Rüsch, Dominik Schürmann + * Copyright (c) 2017 Vincent Breitmoser * * Licensed under the Bouncy Castle License (MIT license). See LICENSE file for details. */ @@ -8,6 +9,8 @@ package org.bouncycastle.openpgp.operator.jcajce; import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; import org.bouncycastle.jcajce.util.NamedJcaJceHelper; @@ -19,25 +22,27 @@ import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; public class CachingDataDecryptorFactory implements PublicKeyDataDecryptorFactory { private final PublicKeyDataDecryptorFactory mWrappedDecryptor; - private final Map mSessionKeyCache; + private final HashMap mSessionKeyCache; private OperatorHelper mOperatorHelper; - public CachingDataDecryptorFactory(String providerName, - final Map sessionKeyCache) + public CachingDataDecryptorFactory(String providerName, Map sessionKeyCache) { - mWrappedDecryptor = null; - mSessionKeyCache = sessionKeyCache; + this((PublicKeyDataDecryptorFactory) null, sessionKeyCache); mOperatorHelper = new OperatorHelper(new NamedJcaJceHelper(providerName)); } public CachingDataDecryptorFactory(PublicKeyDataDecryptorFactory wrapped, - final Map sessionKeyCache) + Map sessionKeyCache) { - mWrappedDecryptor = wrapped; - mSessionKeyCache = sessionKeyCache; + mSessionKeyCache = new HashMap<>(); + if (sessionKeyCache != null) + { + mSessionKeyCache.putAll(sessionKeyCache); + } + mWrappedDecryptor = wrapped; } public boolean hasCachedSessionData(PGPPublicKeyEncryptedData encData) throws PGPException { @@ -46,7 +51,7 @@ public class CachingDataDecryptorFactory implements PublicKeyDataDecryptorFactor } public Map getCachedSessionKeys() { - return mSessionKeyCache; + return Collections.unmodifiableMap(mSessionKeyCache); } public boolean canDecrypt() {