From 97ac237ac3ed4a3030e080cbc39a937dbc4677cd Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 15 May 2017 15:52:08 +0200 Subject: [PATCH 01/23] add google autovalue --- OpenKeychain/build.gradle | 5 +++++ build.gradle | 2 ++ 2 files changed, 7 insertions(+) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index c82dc1469..0bcf7b249 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'com.android.application' apply plugin: 'witness' apply plugin: 'jacoco' apply plugin: 'com.github.kt3k.coveralls' +apply plugin: 'com.neenbedankt.android-apt' dependencies { // NOTE: Always use fixed version codes not dynamic ones, e.g. 0.7.3 instead of 0.7.+, see README for more information @@ -87,6 +88,10 @@ dependencies { exclude module: 'recyclerview-v7' } + compile 'org.glassfish:javax.annotation:10.0-b28' + 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" } // Output of ./gradlew -q calculateChecksums diff --git a/build.gradle b/build.gradle index e1c3772a6..b05a07426 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,8 @@ buildscript { // allows to check for lib updates with "./gradlew dependencyUpdates -Drevision=release" classpath 'com.github.ben-manes:gradle-versions-plugin:0.13.0' + + classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } From 368528e9ddfff0b458b1f7f3c80126be9b8721cc Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 15 May 2017 15:52:18 +0200 Subject: [PATCH 02/23] use autovalue for PgpSignEncryptData class --- .../keychain/operations/BackupOperation.java | 4 +- .../operations/BenchmarkOperation.java | 4 +- .../operations/SignEncryptOperation.java | 12 - .../keychain/pgp/PgpSignEncryptData.java | 267 ++++-------------- .../keychain/pgp/PgpSignEncryptOperation.java | 111 ++++---- .../keychain/remote/OpenPgpService.java | 11 +- .../keychain/ui/EncryptFilesFragment.java | 4 +- .../keychain/ui/EncryptTextFragment.java | 4 +- .../keychain/pgp/PgpEncryptDecryptTest.java | 44 +-- 9 files changed, 150 insertions(+), 311 deletions(-) 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 ab8a4fee8..f5b4ad1fc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java @@ -170,11 +170,11 @@ public class BackupOperation extends BaseOperation { throws FileNotFoundException { PgpSignEncryptOperation signEncryptOperation = new PgpSignEncryptOperation(mContext, mKeyRepository, mProgressable, mCancelled); - PgpSignEncryptData data = new PgpSignEncryptData(); + PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); data.setSymmetricPassphrase(cryptoInput.getPassphrase()); data.setEnableAsciiArmorOutput(backupInput.mEnableAsciiArmorOutput); data.setAddBackupHeader(true); - PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(data); + PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(data.build()); InputStream inStream = mContext.getContentResolver().openInputStream(plainUri); 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 1b857bb2a..6c8f3e276 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java @@ -83,10 +83,10 @@ public class BenchmarkOperation extends BaseOperation { SignEncryptOperation op = new SignEncryptOperation(mContext, mKeyRepository, new ProgressScaler(mProgressable, i*(50/numRepeats), (i+1)*(50/numRepeats), 100), mCancelled); - PgpSignEncryptData data = new PgpSignEncryptData(); + PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); data.setSymmetricPassphrase(passphrase); data.setSymmetricEncryptionAlgorithm(OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - SignEncryptParcel input = new SignEncryptParcel(data); + SignEncryptParcel input = new SignEncryptParcel(data.build()); input.setBytes(buf); encryptResult = op.execute(input, new CryptoInputParcel()); log.add(encryptResult, 1); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java index 41118535e..d0ab2a117 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java @@ -77,18 +77,6 @@ public class SignEncryptOperation extends BaseOperation { SecurityTokenSignOperationsBuilder pendingInputBuilder = null; PgpSignEncryptData data = input.getData(); - // if signing subkey has not explicitly been set, get first usable subkey capable of signing - if (data.getSignatureMasterKeyId() != Constants.key.none - && data.getSignatureSubKeyId() == null) { - try { - long signKeyId = mKeyRepository.getCachedPublicKeyRing( - data.getSignatureMasterKeyId()).getSecretSignId(); - data.setSignatureSubKeyId(signKeyId); - } catch (PgpKeyNotFoundException e) { - Log.e(Constants.TAG, "Key not found", e); - return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results); - } - } do { if (checkCancelled()) { 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 74052e300..aba9f3c01 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java @@ -18,226 +18,73 @@ package org.sufficientlysecure.keychain.pgp; -import android.os.Parcel; -import android.os.Parcelable; +import android.os.Parcelable; +import android.support.annotation.Nullable; + +import com.google.auto.value.AutoValue; import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.util.Passphrase; +@AutoValue +public abstract class PgpSignEncryptData implements Parcelable { + @Nullable + public abstract String getCharset(); + abstract long getAdditionalEncryptId(); + abstract int getSignatureHashAlgorithm(); + @Nullable + public abstract Long getSignatureSubKeyId(); + public abstract long getSignatureMasterKeyId(); + public abstract int getSymmetricEncryptionAlgorithm(); + @Nullable + public abstract Passphrase getSymmetricPassphrase(); + @Nullable + public abstract long[] getEncryptionMasterKeyIds(); + public abstract int getCompressionAlgorithm(); + @Nullable + public abstract String getVersionHeader(); -public class PgpSignEncryptData implements Parcelable { - private String mVersionHeader = null; - private boolean mEnableAsciiArmorOutput = false; - private int mCompressionAlgorithm = CompressionAlgorithmTags.UNCOMPRESSED; - private long[] mEncryptionMasterKeyIds = null; - private Passphrase mSymmetricPassphrase = null; - private int mSymmetricEncryptionAlgorithm = PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT; - private long mSignatureMasterKeyId = Constants.key.none; - private Long mSignatureSubKeyId = null; - private int mSignatureHashAlgorithm = PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT; - private long mAdditionalEncryptId = Constants.key.none; - private String mCharset; - private boolean mCleartextSignature; - private boolean mDetachedSignature = false; - private boolean mHiddenRecipients = false; - private boolean mAddBackupHeader = false; + public abstract boolean isEnableAsciiArmorOutput(); + public abstract boolean isCleartextSignature(); + public abstract boolean isDetachedSignature(); + public abstract boolean isAddBackupHeader(); + public abstract boolean isHiddenRecipients(); - public PgpSignEncryptData(){ + public static Builder builder() { + return new AutoValue_PgpSignEncryptData.Builder() + .setCompressionAlgorithm(CompressionAlgorithmTags.UNCOMPRESSED) + .setSymmetricEncryptionAlgorithm(PgpSecurityConstants.DEFAULT_SYMMETRIC_ALGORITHM) + .setSignatureMasterKeyId(Constants.key.none) + .setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM) + .setAdditionalEncryptId(Constants.key.none) + .setEnableAsciiArmorOutput(false) + .setCleartextSignature(false) + .setDetachedSignature(false) + .setAddBackupHeader(false) + .setHiddenRecipients(false); } - private PgpSignEncryptData(Parcel source) { - ClassLoader loader = getClass().getClassLoader(); + @AutoValue.Builder + public abstract static class Builder { + public abstract PgpSignEncryptData build(); - mVersionHeader = source.readString(); - mEnableAsciiArmorOutput = source.readInt() == 1; - mCompressionAlgorithm = source.readInt(); - mEncryptionMasterKeyIds = source.createLongArray(); - mSymmetricPassphrase = source.readParcelable(loader); - mSymmetricEncryptionAlgorithm = source.readInt(); - mSignatureMasterKeyId = source.readLong(); - mSignatureSubKeyId = source.readInt() == 1 ? source.readLong() : null; - mSignatureHashAlgorithm = source.readInt(); - mAdditionalEncryptId = source.readLong(); - mCharset = source.readString(); - mCleartextSignature = source.readInt() == 1; - mDetachedSignature = source.readInt() == 1; - mHiddenRecipients = source.readInt() == 1; - mAddBackupHeader = source.readInt() == 1; + public abstract Builder setCharset(String charset); + public abstract Builder setAdditionalEncryptId(long additionalEncryptId); + public abstract Builder setSignatureHashAlgorithm(int signatureHashAlgorithm); + public abstract Builder setSignatureSubKeyId(Long signatureSubKeyId); + public abstract Builder setSignatureMasterKeyId(long signatureMasterKeyId); + public abstract Builder setSymmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm); + public abstract Builder setSymmetricPassphrase(Passphrase symmetricPassphrase); + public abstract Builder setEncryptionMasterKeyIds(long[] encryptionMasterKeyIds); + public abstract Builder setCompressionAlgorithm(int compressionAlgorithm); + public abstract Builder setVersionHeader(String versionHeader); + + public abstract Builder setAddBackupHeader(boolean isAddBackupHeader); + public abstract Builder setEnableAsciiArmorOutput(boolean enableAsciiArmorOutput); + public abstract Builder setCleartextSignature(boolean isCleartextSignature); + public abstract Builder setDetachedSignature(boolean isDetachedSignature); + public abstract Builder setHiddenRecipients(boolean isHiddenRecipients); } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mVersionHeader); - dest.writeInt(mEnableAsciiArmorOutput ? 1 : 0); - dest.writeInt(mCompressionAlgorithm); - dest.writeLongArray(mEncryptionMasterKeyIds); - dest.writeParcelable(mSymmetricPassphrase, 0); - dest.writeInt(mSymmetricEncryptionAlgorithm); - dest.writeLong(mSignatureMasterKeyId); - if (mSignatureSubKeyId != null) { - dest.writeInt(1); - dest.writeLong(mSignatureSubKeyId); - } else { - dest.writeInt(0); - } - dest.writeInt(mSignatureHashAlgorithm); - dest.writeLong(mAdditionalEncryptId); - dest.writeString(mCharset); - dest.writeInt(mCleartextSignature ? 1 : 0); - dest.writeInt(mDetachedSignature ? 1 : 0); - dest.writeInt(mHiddenRecipients ? 1 : 0); - dest.writeInt(mAddBackupHeader ? 1 : 0); - } - - public String getCharset() { - return mCharset; - } - - public void setCharset(String mCharset) { - this.mCharset = mCharset; - } - - public long getAdditionalEncryptId() { - return mAdditionalEncryptId; - } - - public PgpSignEncryptData setAdditionalEncryptId(long additionalEncryptId) { - mAdditionalEncryptId = additionalEncryptId; - return this; - } - - public int getSignatureHashAlgorithm() { - return mSignatureHashAlgorithm; - } - - public PgpSignEncryptData setSignatureHashAlgorithm(int signatureHashAlgorithm) { - mSignatureHashAlgorithm = signatureHashAlgorithm; - return this; - } - - public Long getSignatureSubKeyId() { - return mSignatureSubKeyId; - } - - public PgpSignEncryptData setSignatureSubKeyId(long signatureSubKeyId) { - mSignatureSubKeyId = signatureSubKeyId; - return this; - } - - public long getSignatureMasterKeyId() { - return mSignatureMasterKeyId; - } - - public PgpSignEncryptData setSignatureMasterKeyId(long signatureMasterKeyId) { - mSignatureMasterKeyId = signatureMasterKeyId; - return this; - } - - public int getSymmetricEncryptionAlgorithm() { - return mSymmetricEncryptionAlgorithm; - } - - public PgpSignEncryptData setSymmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) { - mSymmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; - return this; - } - - public Passphrase getSymmetricPassphrase() { - return mSymmetricPassphrase; - } - - public PgpSignEncryptData setSymmetricPassphrase(Passphrase symmetricPassphrase) { - mSymmetricPassphrase = symmetricPassphrase; - return this; - } - - public long[] getEncryptionMasterKeyIds() { - return mEncryptionMasterKeyIds; - } - - public PgpSignEncryptData setEncryptionMasterKeyIds(long[] encryptionMasterKeyIds) { - mEncryptionMasterKeyIds = encryptionMasterKeyIds; - return this; - } - - public int getCompressionAlgorithm() { - return mCompressionAlgorithm; - } - - public PgpSignEncryptData setCompressionAlgorithm(int compressionAlgorithm) { - mCompressionAlgorithm = compressionAlgorithm; - return this; - } - - public boolean isEnableAsciiArmorOutput() { - return mEnableAsciiArmorOutput; - } - - public String getVersionHeader() { - return mVersionHeader; - } - - public PgpSignEncryptData setVersionHeader(String versionHeader) { - mVersionHeader = versionHeader; - return this; - } - - public PgpSignEncryptData setEnableAsciiArmorOutput(boolean enableAsciiArmorOutput) { - mEnableAsciiArmorOutput = enableAsciiArmorOutput; - return this; - } - - public PgpSignEncryptData setCleartextSignature(boolean cleartextSignature) { - this.mCleartextSignature = cleartextSignature; - return this; - } - - public boolean isCleartextSignature() { - return mCleartextSignature; - } - - public PgpSignEncryptData setDetachedSignature(boolean detachedSignature) { - this.mDetachedSignature = detachedSignature; - return this; - } - - public boolean isDetachedSignature() { - return mDetachedSignature; - } - - public PgpSignEncryptData setHiddenRecipients(boolean hiddenRecipients) { - this.mHiddenRecipients = hiddenRecipients; - return this; - } - - public PgpSignEncryptData setAddBackupHeader(boolean addBackupHeader) { - this.mAddBackupHeader = addBackupHeader; - return this; - } - - public boolean isAddBackupHeader() { - return mAddBackupHeader; - } - - public boolean isHiddenRecipients() { - return mHiddenRecipients; - } - - public static final Creator CREATOR = new Creator() { - public PgpSignEncryptData createFromParcel(final Parcel source) { - return new PgpSignEncryptData(source); - } - - public PgpSignEncryptData[] newArray(final int size) { - return new PgpSignEncryptData[size]; - } - }; - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index 3082ee605..bb022699e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -19,6 +19,23 @@ package org.sufficientlysecure.keychain.pgp; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.security.SignatureException; +import java.util.Date; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; @@ -56,23 +73,6 @@ import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ProgressScaler; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.security.SignatureException; -import java.util.Arrays; -import java.util.Date; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - /** * This class supports a single, low-level, sign/encrypt operation. *

@@ -187,12 +187,6 @@ public class PgpSignEncryptOperation extends BaseOperation encryptSubKeyIds = keyRing.getEncryptIds(); - for (Long subKeyId : encryptSubKeyIds) { - CanonicalizedPublicKey key = keyRing.getPublicKey(subKeyId); - cPk.addMethod(key.getPubKeyEncryptionGenerator(data.isHiddenRecipients())); - log.add(LogType.MSG_PSE_KEY_OK, indent + 1, - KeyFormattingUtils.convertKeyIdToHex(subKeyId)); - } - if (encryptSubKeyIds.isEmpty()) { - log.add(LogType.MSG_PSE_KEY_WARN, indent + 1, - KeyFormattingUtils.convertKeyIdToHex(id)); - return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); - } - // Make sure key is not expired or revoked - if (keyRing.isExpired() || keyRing.isRevoked()) { - log.add(LogType.MSG_PSE_ERROR_REVOKED_OR_EXPIRED, indent); - return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); - } - } catch (KeyWritableRepository.NotFoundException e) { - log.add(LogType.MSG_PSE_KEY_UNKNOWN, indent + 1, - KeyFormattingUtils.convertKeyIdToHex(id)); + for (long encryptMasterKeyId : data.getEncryptionMasterKeyIds()) { + boolean success = processEncryptionMasterKeyId(indent, log, data, cPk, encryptMasterKeyId); + if (!success) { + return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); + } + } + + long additionalEncryptId = data.getAdditionalEncryptId(); + if (additionalEncryptId != Constants.key.none) { + boolean success = processEncryptionMasterKeyId(indent, log, data, cPk, additionalEncryptId); + if (!success) { return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); } } @@ -663,6 +638,36 @@ public class PgpSignEncryptOperation extends BaseOperation encryptSubKeyIds = keyRing.getEncryptIds(); + for (Long subKeyId : encryptSubKeyIds) { + CanonicalizedPublicKey key = keyRing.getPublicKey(subKeyId); + cPk.addMethod(key.getPubKeyEncryptionGenerator(data.isHiddenRecipients())); + log.add(LogType.MSG_PSE_KEY_OK, indent + 1, + KeyFormattingUtils.convertKeyIdToHex(subKeyId)); + } + if (encryptSubKeyIds.isEmpty()) { + log.add(LogType.MSG_PSE_KEY_WARN, indent + 1, + KeyFormattingUtils.convertKeyIdToHex(encryptMasterKeyId)); + return false; + } + // Make sure key is not expired or revoked + if (keyRing.isExpired() || keyRing.isRevoked()) { + log.add(LogType.MSG_PSE_ERROR_REVOKED_OR_EXPIRED, indent); + return false; + } + } catch (KeyWritableRepository.NotFoundException e) { + log.add(LogType.MSG_PSE_KEY_UNKNOWN, indent + 1, + KeyFormattingUtils.convertKeyIdToHex(encryptMasterKeyId)); + return false; + } + return true; + } + /** * Remove whitespaces on line endings */ 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 1f788a6ec..aa59d6a26 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -109,7 +109,7 @@ public class OpenPgpService extends Service { boolean asciiArmor = cleartextSign || data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); // sign-only - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEnableAsciiArmorOutput(asciiArmor) .setCleartextSignature(cleartextSign) .setDetachedSignature(!cleartextSign) @@ -132,8 +132,7 @@ public class OpenPgpService extends Service { // get first usable subkey capable of signing try { - long signSubKeyId = mKeyRepository.getCachedPublicKeyRing( - pgpData.getSignatureMasterKeyId()).getSecretSignId(); + long signSubKeyId = mKeyRepository.getCachedPublicKeyRing(signKeyId).getSecretSignId(); pgpData.setSignatureSubKeyId(signSubKeyId); } catch (PgpKeyNotFoundException e) { throw new Exception("signing subkey not found!", e); @@ -141,7 +140,7 @@ public class OpenPgpService extends Service { } - PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData.build()); pseInput.setAllowedKeyIds(getAllowedKeyIds()); // Get Input- and OutputStream from ParcelFileDescriptor @@ -213,7 +212,7 @@ public class OpenPgpService extends Service { compressionId = PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED; } - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEnableAsciiArmorOutput(asciiArmor) .setVersionHeader(null) .setCompressionAlgorithm(compressionId); @@ -261,7 +260,7 @@ public class OpenPgpService extends Service { } pgpData.setEncryptionMasterKeyIds(keyIdResult.getKeyIds()); - PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData.build()); pseInput.setAllowedKeyIds(getAllowedKeyIds()); CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index 3cbb5e25c..4f1edea80 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -623,7 +623,7 @@ public class EncryptFilesFragment } // fill values for this action - PgpSignEncryptData data = new PgpSignEncryptData(); + PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); if (mUseCompression) { data.setCompressionAlgorithm( @@ -675,7 +675,7 @@ public class EncryptFilesFragment } - SignEncryptParcel parcel = new SignEncryptParcel(data); + SignEncryptParcel parcel = new SignEncryptParcel(data.build()); parcel.addInputUris(mFilesAdapter.getAsArrayList()); return parcel; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index 1939ea20a..3c970ef72 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -233,7 +233,7 @@ public class EncryptTextFragment } // fill values for this action - PgpSignEncryptData data = new PgpSignEncryptData(); + PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); data.setCleartextSignature(true); @@ -286,7 +286,7 @@ public class EncryptTextFragment data.setSymmetricPassphrase(passphrase); } - SignEncryptParcel parcel = new SignEncryptParcel(data); + SignEncryptParcel parcel = new SignEncryptParcel(data.build()); parcel.setBytes(mMessage.getBytes()); return parcel; 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 2536a5280..d058aa988 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -178,12 +178,12 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setSymmetricPassphrase(mSymmetricPassphrase); pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()), data, out); @@ -303,14 +303,14 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); // only sign, and not as cleartext pgpData.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); pgpData.setCleartextSignature(false); pgpData.setDetachedSignature(false); - PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("signing must succeed", result.success()); @@ -359,7 +359,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); // only sign, as cleartext pgpData.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); @@ -367,7 +367,7 @@ public class PgpEncryptDecryptTest { pgpData.setEnableAsciiArmorOutput(true); pgpData.setDetachedSignature(false); - PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("signing must succeed", result.success()); @@ -421,13 +421,13 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); // only sign, as cleartext pgpData.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); pgpData.setDetachedSignature(true); - PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("signing must succeed", result.success()); @@ -478,12 +478,12 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), data, out); @@ -581,12 +581,12 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), data, out); @@ -694,12 +694,12 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), data, out); @@ -739,7 +739,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId(), mStaticRing2.getMasterKeyId() @@ -747,7 +747,7 @@ public class PgpEncryptDecryptTest { pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()), data, out); @@ -868,7 +868,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId(), mStaticRing2.getMasterKeyId() @@ -878,7 +878,7 @@ public class PgpEncryptDecryptTest { pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date(), mKeyPhrase1), data, out); @@ -955,7 +955,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); @@ -963,7 +963,7 @@ public class PgpEncryptDecryptTest { pgpData.setEnableAsciiArmorOutput(true); pgpData.setCharset("iso-2022-jp"); - PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData); + PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build()); PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()), data, out); @@ -1106,7 +1106,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); - PgpSignEncryptData pgpData = new PgpSignEncryptData(); + PgpSignEncryptData.Builder pgpData = PgpSignEncryptData.builder(); pgpData.setEncryptionMasterKeyIds(new long[]{ mStaticRingInsecure.getMasterKeyId()}); PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); @@ -1120,4 +1120,4 @@ public class PgpEncryptDecryptTest { armoredOutputStream.close(); } */ -} \ No newline at end of file +} From 63774a063212cccb1e4b1476f79a5ff21582cd62 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 15 May 2017 16:22:03 +0200 Subject: [PATCH 03/23] 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() { From 53dcb4102ddb329635e28e3f8b22f9fa577bfd59 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 11:25:52 +0200 Subject: [PATCH 04/23] use autovalue for CertifyActionsParcel --- .../keychain/operations/CertifyOperation.java | 16 +-- .../keychain/pgp/PgpCertifyOperation.java | 19 +-- .../service/CertifyActionsParcel.java | 131 ++++++++---------- .../keychain/ui/CertifyKeyFragment.java | 15 +- .../ui/adapter/MultiUserIdsAdapter.java | 12 +- .../ui/keyview/LinkedIdViewFragment.java | 8 +- .../operations/CertifyOperationTest.java | 36 ++--- .../pgp/UncachedKeyringMergeTest.java | 11 +- .../remote/KeychainExternalProviderTest.java | 7 +- 9 files changed, 125 insertions(+), 130 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java index a21e36771..a7b2bf59e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java @@ -76,7 +76,7 @@ public class CertifyOperation extends BaseReadWriteOperation userIds = action.getUserIds(); + if (userIds != null && !userIds.isEmpty()) { + log.add(LogType.MSG_CRT_CERTIFY_UIDS, 2, userIds.size(), + KeyFormattingUtils.convertKeyIdToHex(action.getMasterKeyId())); // fetch public key ring, add the certification and return it - for (String userId : action.mUserIds) { + for (String userId : userIds) { try { PGPSignature sig = signatureGenerator.generateCertification(userId, publicKey); publicKey = PGPPublicKey.addCertification(publicKey, userId, sig); @@ -96,12 +98,13 @@ public class PgpCertifyOperation { } - if (action.mUserAttributes != null) { - log.add(LogType.MSG_CRT_CERTIFY_UATS, 2, action.mUserAttributes.size(), - KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId)); + ArrayList userAttributes = action.getUserAttributes(); + if (userAttributes != null && !userAttributes.isEmpty()) { + log.add(LogType.MSG_CRT_CERTIFY_UATS, 2, userAttributes.size(), + KeyFormattingUtils.convertKeyIdToHex(action.getMasterKeyId())); // fetch public key ring, add the certification and return it - for (WrappedUserAttribute userAttribute : action.mUserAttributes) { + for (WrappedUserAttribute userAttribute : userAttributes) { PGPUserAttributeSubpacketVector vector = userAttribute.getVector(); try { PGPSignature sig = signatureGenerator.generateCertification(vector, publicKey); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java index b7cc470e3..54a2c5fd5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java @@ -18,99 +18,80 @@ package org.sufficientlysecure.keychain.service; -import android.os.Parcel; -import android.os.Parcelable; -import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.List; -import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; +import android.os.Parcelable; +import android.support.annotation.CheckResult; +import android.support.annotation.Nullable; + +import com.google.auto.value.AutoValue; import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; +import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; -/** - * This class is a a transferable representation for a number of keyrings to - * be certified. - */ -public class CertifyActionsParcel implements Parcelable { +@AutoValue +public abstract class CertifyActionsParcel implements Parcelable { + public abstract long getMasterKeyId(); + public abstract ArrayList getCertifyActions(); + @Nullable + public abstract ParcelableHkpKeyserver getParcelableKeyServer(); - // the master key id to certify with - final public long mMasterKeyId; - public CertifyLevel mLevel; - - public ArrayList mCertifyActions = new ArrayList<>(); - - public ParcelableHkpKeyserver keyServerUri; - - public CertifyActionsParcel(long masterKeyId) { - mMasterKeyId = masterKeyId; - mLevel = CertifyLevel.DEFAULT; + public static Builder builder(long masterKeyId) { + return new AutoValue_CertifyActionsParcel.Builder() + .setMasterKeyId(masterKeyId) + .setCertifyActions(new ArrayList()); } - public CertifyActionsParcel(Parcel source) { - mMasterKeyId = source.readLong(); - // just like parcelables, this is meant for ad-hoc IPC only and is NOT portable! - mLevel = CertifyLevel.values()[source.readInt()]; - keyServerUri = source.readParcelable(ParcelableHkpKeyserver.class.getClassLoader()); + @AutoValue.Builder + public abstract static class Builder { + abstract Builder setMasterKeyId(long masterKeyId); + public abstract Builder setCertifyActions(ArrayList certifyActions); + public abstract Builder setParcelableKeyServer(ParcelableHkpKeyserver uri); - mCertifyActions = (ArrayList) source.readSerializable(); - } + abstract ArrayList getCertifyActions(); - public void add(CertifyAction action) { - mCertifyActions.add(action); - } - - @Override - public void writeToParcel(Parcel destination, int flags) { - destination.writeLong(mMasterKeyId); - destination.writeInt(mLevel.ordinal()); - destination.writeParcelable(keyServerUri, flags); - - destination.writeSerializable(mCertifyActions); - } - - public static final Creator CREATOR = new Creator() { - public CertifyActionsParcel createFromParcel(final Parcel source) { - return new CertifyActionsParcel(source); + public void addAction(CertifyAction action) { + getCertifyActions().add(action); + } + public void addActions(Collection certifyActions) { + getCertifyActions().addAll(certifyActions); } - public CertifyActionsParcel[] newArray(final int size) { - return new CertifyActionsParcel[size]; + public abstract CertifyActionsParcel build(); + } + + @AutoValue + public abstract static class CertifyAction implements Parcelable { + public abstract long getMasterKeyId(); + @Nullable + public abstract ArrayList getUserIds(); + @Nullable + public abstract ArrayList getUserAttributes(); + + public static CertifyAction createForUserIds(long masterKeyId, List userIds) { + return new AutoValue_CertifyActionsParcel_CertifyAction(masterKeyId, new ArrayList<>(userIds), null); } - }; - // TODO make this parcelable - public static class CertifyAction implements Serializable { - final public long mMasterKeyId; + public static CertifyAction createForUserAttributes(long masterKeyId, List attributes) { + return new AutoValue_CertifyActionsParcel_CertifyAction(masterKeyId, null, new ArrayList<>(attributes)); + } - final public ArrayList mUserIds; - final public ArrayList mUserAttributes; + @CheckResult + public CertifyAction withAddedUserIds(ArrayList addedUserIds) { + if (getUserAttributes() != null) { + throw new IllegalStateException("Can't add user ids to user attribute certification parcel!"); + } + ArrayList prevUserIds = getUserIds(); + if (prevUserIds == null) { + throw new IllegalStateException("Can't add user ids to user attribute certification parcel!"); + } - public CertifyAction(long masterKeyId, List userIds, List attributes) { - mMasterKeyId = masterKeyId; - mUserIds = userIds == null ? null : new ArrayList<>(userIds); - mUserAttributes = attributes == null ? null : new ArrayList<>(attributes); + ArrayList userIds = new ArrayList<>(prevUserIds); + userIds.addAll(addedUserIds); + return new AutoValue_CertifyActionsParcel_CertifyAction(getMasterKeyId(), userIds, null); } } - - @Override - public int describeContents() { - return 0; - } - - @Override - public String toString() { - String out = "mMasterKeyId: " + mMasterKeyId + "\n"; - out += "mLevel: " + mLevel + "\n"; - out += "mCertifyActions: " + mCertifyActions + "\n"; - - return out; - } - - // All supported algorithms - public enum CertifyLevel { - DEFAULT, NONE, CASUAL, POSITIVE - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index c343ab4a3..f08ffe8ad 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -140,18 +140,17 @@ public class CertifyKeyFragment long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId(); // fill values for this action - CertifyActionsParcel actionsParcel = new CertifyActionsParcel(selectedKeyId); - actionsParcel.mCertifyActions.addAll(certifyActions); + CertifyActionsParcel.Builder actionsParcel = CertifyActionsParcel.builder(selectedKeyId); + actionsParcel.addActions(certifyActions); if (mUploadKeyCheckbox.isChecked()) { - actionsParcel.keyServerUri = Preferences.getPreferences(getActivity()) - .getPreferredKeyserver(); + actionsParcel.setParcelableKeyServer(Preferences.getPreferences(getActivity()).getPreferredKeyserver()); } - // cached for next cryptoOperation loop - cacheActionsParcel(actionsParcel); - - return actionsParcel; + // cache for next cryptoOperation loop + CertifyActionsParcel certifyActionsParcel = actionsParcel.build(); + cacheActionsParcel(certifyActionsParcel); + return certifyActionsParcel; } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java index b6da1eddf..304b0d72f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java @@ -17,6 +17,9 @@ package org.sufficientlysecure.keychain.ui.adapter; + +import java.util.ArrayList; + import android.content.Context; import android.database.Cursor; import android.os.Parcel; @@ -35,8 +38,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; -import java.util.ArrayList; - public class MultiUserIdsAdapter extends CursorAdapter { private LayoutInflater mInflater; private final ArrayList mCheckStates; @@ -178,11 +179,12 @@ public class MultiUserIdsAdapter extends CursorAdapter { p.recycle(); CertifyAction action = actions.get(keyId); - if (actions.get(keyId) == null) { - actions.put(keyId, new CertifyAction(keyId, uids, null)); + if (action == null) { + action = CertifyAction.createForUserIds(keyId, uids); } else { - action.mUserIds.addAll(uids); + action = action.withAddedUserIds(uids); } + actions.put(keyId, action); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/LinkedIdViewFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/LinkedIdViewFragment.java index 5cb0bc42f..12f54b238 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/LinkedIdViewFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/LinkedIdViewFragment.java @@ -542,14 +542,14 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements @Nullable @Override public Parcelable createOperationInput() { - CertifyAction action = new CertifyAction(mMasterKeyId, null, + CertifyAction action = CertifyAction.createForUserAttributes(mMasterKeyId, Collections.singletonList(mLinkedId.toUserAttribute())); // fill values for this action - CertifyActionsParcel parcel = new CertifyActionsParcel(mCertifyKeyId); - parcel.mCertifyActions.addAll(Collections.singletonList(action)); + CertifyActionsParcel.Builder builder = CertifyActionsParcel.builder(mCertifyKeyId); + builder.addActions(Collections.singletonList(action)); - return parcel; + return builder.build(); } @Override 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 0423a83b9..46d95188c 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java @@ -153,10 +153,10 @@ public class CertifyOperationTest { Certs.UNVERIFIED, ring.getVerified()); } - CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); - actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(), - mStaticRing2.getPublicKey().getUnorderedUserIds(), null)); - CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); + CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId()); + actions.addAction(CertifyAction.createForUserIds(mStaticRing2.getMasterKeyId(), + mStaticRing2.getPublicKey().getUnorderedUserIds())); + CertifyResult result = op.execute(actions.build(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertTrue("certification must succeed", result.success()); @@ -181,10 +181,10 @@ public class CertifyOperationTest { Certs.UNVERIFIED, ring.getVerified()); } - CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); - actions.add(new CertifyAction(mStaticRing2.getMasterKeyId(), null, + CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId()); + actions.addAction(CertifyAction.createForUserAttributes(mStaticRing2.getMasterKeyId(), mStaticRing2.getPublicKey().getUnorderedUserAttributes())); - CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); + CertifyResult result = op.execute(actions.build(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertTrue("certification must succeed", result.success()); @@ -203,11 +203,11 @@ public class CertifyOperationTest { CertifyOperation op = new CertifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null); - CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); - actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(), - mStaticRing2.getPublicKey().getUnorderedUserIds(), null)); + CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId()); + actions.addAction(CertifyAction.createForUserIds(mStaticRing1.getMasterKeyId(), + mStaticRing2.getPublicKey().getUnorderedUserIds())); - CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); + CertifyResult result = op.execute(actions.build(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertFalse("certification with itself must fail!", result.success()); Assert.assertTrue("error msg must be about self certification", @@ -221,12 +221,12 @@ public class CertifyOperationTest { KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null); { - CertifyActionsParcel actions = new CertifyActionsParcel(mStaticRing1.getMasterKeyId()); + CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId()); ArrayList uids = new ArrayList(); uids.add("nonexistent"); - actions.add(new CertifyAction(1234L, uids, null)); + actions.addAction(CertifyAction.createForUserIds(1234L, uids)); - CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), + CertifyResult result = op.execute(actions.build(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); Assert.assertFalse("certification of nonexistent key must fail", result.success()); @@ -235,11 +235,11 @@ public class CertifyOperationTest { } { - CertifyActionsParcel actions = new CertifyActionsParcel(1234L); - actions.add(new CertifyAction(mStaticRing1.getMasterKeyId(), - mStaticRing2.getPublicKey().getUnorderedUserIds(), null)); + CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(1234L); + actions.addAction(CertifyAction.createForUserIds(mStaticRing1.getMasterKeyId(), + mStaticRing2.getPublicKey().getUnorderedUserIds())); - CertifyResult result = op.execute(actions, CryptoInputParcel.createCryptoInputParcel(new Date(), + CertifyResult result = op.execute(actions.build(), 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/UncachedKeyringMergeTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java index b8a1e3525..0a7a1c20d 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -18,6 +18,14 @@ package org.sufficientlysecure.keychain.pgp; + +import java.io.ByteArrayInputStream; +import java.security.Security; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.Random; + import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.PacketTags; import org.bouncycastle.bcpg.S2K; @@ -304,7 +312,8 @@ public class UncachedKeyringMergeTest { ringB.getEncoded(), 0).getSecretKey(); secretKey.unlock(new Passphrase()); PgpCertifyOperation op = new PgpCertifyOperation(); - CertifyAction action = new CertifyAction(pubRing.getMasterKeyId(), publicRing.getPublicKey().getUnorderedUserIds(), null); + CertifyAction action = CertifyAction.createForUserIds( + pubRing.getMasterKeyId(), publicRing.getPublicKey().getUnorderedUserIds()); // sign all user ids PgpCertifyResult result = op.certify(secretKey, publicRing, new OperationLog(), 0, action, null, new Date()); Assert.assertTrue("certification must succeed", result.success()); 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 deb94f439..98623da74 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java @@ -194,11 +194,12 @@ public class KeychainExternalProviderTest { } private void certifyKey(long secretMasterKeyId, long publicMasterKeyId, String userId) { - CertifyActionsParcel certifyActionsParcel = new CertifyActionsParcel(secretMasterKeyId); - certifyActionsParcel.add(new CertifyAction(publicMasterKeyId, Collections.singletonList(userId), null)); + CertifyActionsParcel.Builder certifyActionsParcel = CertifyActionsParcel.builder(secretMasterKeyId); + certifyActionsParcel.addAction( + CertifyAction.createForUserIds(publicMasterKeyId, Collections.singletonList(userId))); CertifyOperation op = new CertifyOperation( RuntimeEnvironment.application, databaseInteractor, new ProgressScaler(), null); - CertifyResult certifyResult = op.execute(certifyActionsParcel, CryptoInputParcel.createCryptoInputParcel()); + CertifyResult certifyResult = op.execute(certifyActionsParcel.build(), CryptoInputParcel.createCryptoInputParcel()); assertTrue(certifyResult.success()); } From f1cf759e0a7c807f91b1afc060b0be1a8deeb4ef Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 11:26:38 +0200 Subject: [PATCH 05/23] use autovalue for UploadKeyringParcel --- .../keychain/operations/EditKeyOperation.java | 2 +- .../keychain/operations/UploadOperation.java | 19 ++---- .../keychain/service/UploadKeyringParcel.java | 64 +++++-------------- .../keychain/ui/CreateKeyFinalFragment.java | 2 +- .../keychain/ui/EditIdentitiesFragment.java | 2 +- .../keychain/ui/UploadKeyActivity.java | 2 +- 6 files changed, 25 insertions(+), 66 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java index da09ad9e0..57161b61b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java @@ -144,7 +144,7 @@ public class EditKeyOperation extends BaseReadWriteOperation } UploadKeyringParcel exportKeyringParcel = - new UploadKeyringParcel(saveParcel.getUploadKeyserver(), keyringBytes); + UploadKeyringParcel.createWithKeyringBytes(saveParcel.getUploadKeyserver(), keyringBytes); UploadResult uploadResult = new UploadOperation( mContext, mKeyRepository, new ProgressScaler(mProgressable, 60, 80, 100), mCancelled) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java index 27265461b..7e54afd70 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/UploadOperation.java @@ -96,7 +96,7 @@ public class UploadOperation extends BaseOperation { ParcelableHkpKeyserver hkpKeyserver; { - hkpKeyserver = uploadInput.mKeyserver; + hkpKeyserver = uploadInput.getKeyserver(); log.add(LogType.MSG_UPLOAD_SERVER, 1, hkpKeyserver.toString()); } @@ -110,22 +110,15 @@ public class UploadOperation extends BaseOperation { @Nullable private CanonicalizedPublicKeyRing getPublicKeyringFromInput(OperationLog log, UploadKeyringParcel uploadInput) { - - boolean hasMasterKeyId = uploadInput.mMasterKeyId != null; - boolean hasKeyringBytes = uploadInput.mUncachedKeyringBytes != null; - if (hasMasterKeyId == hasKeyringBytes) { - throw new IllegalArgumentException("either keyid xor bytes must be non-null for this method call!"); - } - try { - - if (hasMasterKeyId) { - log.add(LogType.MSG_UPLOAD_KEY, 0, KeyFormattingUtils.convertKeyIdToHex(uploadInput.mMasterKeyId)); - return mKeyRepository.getCanonicalizedPublicKeyRing(uploadInput.mMasterKeyId); + Long masterKeyId = uploadInput.getMasterKeyId(); + if (masterKeyId != null) { + log.add(LogType.MSG_UPLOAD_KEY, 0, KeyFormattingUtils.convertKeyIdToHex(masterKeyId)); + return mKeyRepository.getCanonicalizedPublicKeyRing(masterKeyId); } CanonicalizedKeyRing canonicalizedRing = - UncachedKeyRing.decodeFromData(uploadInput.mUncachedKeyringBytes) + UncachedKeyRing.decodeFromData(uploadInput.getUncachedKeyringBytes()) .canonicalize(new OperationLog(), 0, true); if (!CanonicalizedPublicKeyRing.class.isInstance(canonicalizedRing)) { throw new IllegalArgumentException("keyring bytes must contain public key ring!"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java index 2db386afa..d33e18d86 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java @@ -20,62 +20,28 @@ package org.sufficientlysecure.keychain.service; -import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.google.auto.value.AutoValue; import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; +@AutoValue +public abstract class UploadKeyringParcel implements Parcelable { + public abstract ParcelableHkpKeyserver getKeyserver(); + @Nullable + public abstract Long getMasterKeyId(); + @Nullable + public abstract byte[] getUncachedKeyringBytes(); -public class UploadKeyringParcel implements Parcelable { - public ParcelableHkpKeyserver mKeyserver; - public final Long mMasterKeyId; - public final byte[] mUncachedKeyringBytes; - - public UploadKeyringParcel(ParcelableHkpKeyserver keyserver, long masterKeyId) { - mKeyserver = keyserver; - mMasterKeyId = masterKeyId; - mUncachedKeyringBytes = null; + public static UploadKeyringParcel createWithKeyId(ParcelableHkpKeyserver keyserver, long masterKeyId) { + return new AutoValue_UploadKeyringParcel(keyserver, masterKeyId, null); } - public UploadKeyringParcel(ParcelableHkpKeyserver keyserver, byte[] uncachedKeyringBytes) { - mKeyserver = keyserver; - mMasterKeyId = null; - mUncachedKeyringBytes = uncachedKeyringBytes; + public static UploadKeyringParcel createWithKeyringBytes(ParcelableHkpKeyserver keyserver, + @NonNull byte[] uncachedKeyringBytes) { + return new AutoValue_UploadKeyringParcel(keyserver, null, uncachedKeyringBytes); } - - protected UploadKeyringParcel(Parcel in) { - mKeyserver = in.readParcelable(ParcelableHkpKeyserver.class.getClassLoader()); - mMasterKeyId = in.readInt() != 0 ? in.readLong() : null; - mUncachedKeyringBytes = in.createByteArray(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mKeyserver, flags); - if (mMasterKeyId != null) { - dest.writeInt(1); - dest.writeLong(mMasterKeyId); - } else { - dest.writeInt(0); - } - dest.writeByteArray(mUncachedKeyringBytes); - } - - public static final Creator CREATOR = new Creator() { - @Override - public UploadKeyringParcel createFromParcel(Parcel in) { - return new UploadKeyringParcel(in); - } - - @Override - public UploadKeyringParcel[] newArray(int size) { - return new UploadKeyringParcel[size]; - } - }; } \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 78bbbe58c..53956119d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -520,7 +520,7 @@ public class CreateKeyFinalFragment extends Fragment { @Override public UploadKeyringParcel createOperationInput() { - return new UploadKeyringParcel(keyserver, masterKeyId); + return UploadKeyringParcel.createWithKeyId(keyserver, masterKeyId); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java index b6a6658e9..e7944f41a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java @@ -395,7 +395,7 @@ public class EditIdentitiesFragment extends Fragment @Override public UploadKeyringParcel createOperationInput() { - return new UploadKeyringParcel(keyserver, masterKeyId); + return UploadKeyringParcel.createWithKeyId(keyserver, masterKeyId); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index 1f60092e8..a990d2a4c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -144,7 +144,7 @@ public class UploadKeyActivity extends BaseActivity public UploadKeyringParcel createOperationInput() { long[] masterKeyIds = getIntent().getLongArrayExtra(MultiUserIdsFragment.EXTRA_KEY_IDS); - return new UploadKeyringParcel(mKeyserver, masterKeyIds[0]); + return UploadKeyringParcel.createWithKeyId(mKeyserver, masterKeyIds[0]); } @Override From 81bceb9e1642be160a5ec01ea4e6ae7902afb60b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 11:26:54 +0200 Subject: [PATCH 06/23] use autovalue for BenchmarkInputParcel --- .../service/BenchmarkInputParcel.java | 34 ++++--------------- .../keychain/ui/KeyListFragment.java | 2 +- .../operations/BenchmarkOperationTest.java | 2 +- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BenchmarkInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BenchmarkInputParcel.java index cfbdfefff..47bdc9b1e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BenchmarkInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BenchmarkInputParcel.java @@ -19,36 +19,16 @@ package org.sufficientlysecure.keychain.service; -import android.os.Parcel; + import android.os.Parcelable; +import com.google.auto.value.AutoValue; -public class BenchmarkInputParcel implements Parcelable { - public BenchmarkInputParcel() { +@AutoValue +public abstract class BenchmarkInputParcel implements Parcelable { + + public static BenchmarkInputParcel newInstance() { + return new AutoValue_BenchmarkInputParcel(); } - - protected BenchmarkInputParcel(Parcel in) { - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - } - - public static final Creator CREATOR = new Creator() { - @Override - public BenchmarkInputParcel createFromParcel(Parcel in) { - return new BenchmarkInputParcel(in); - } - - @Override - public BenchmarkInputParcel[] newArray(int size) { - return new BenchmarkInputParcel[size]; - } - }; } \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 9b6b3ab73..62ba0e872 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -586,7 +586,7 @@ public class KeyListFragment extends RecyclerFragment @Override public BenchmarkInputParcel createOperationInput() { - return new BenchmarkInputParcel(); // we want to perform a full consolidate + return BenchmarkInputParcel.newInstance(); // we want to perform a full consolidate } @Override diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BenchmarkOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BenchmarkOperationTest.java index c3aba0289..20a0a9d4d 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BenchmarkOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BenchmarkOperationTest.java @@ -49,7 +49,7 @@ public class BenchmarkOperationTest { BenchmarkOperation op = new BenchmarkOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - op.execute(new BenchmarkInputParcel(), null); + op.execute(BenchmarkInputParcel.newInstance(), null); } } From 820a308ba00d94a4ae066ecc00646f27ecf8c9d7 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 12:17:59 +0200 Subject: [PATCH 07/23] use autovalue for RevokeKeyringParcel --- .../keychain/operations/RevokeOperation.java | 6 +-- .../keychain/service/RevokeKeyringParcel.java | 54 +++++-------------- .../keychain/ui/DeleteKeyDialogActivity.java | 2 +- 3 files changed, 17 insertions(+), 45 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java index 19eb0160a..197842ed9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java @@ -53,7 +53,7 @@ public class RevokeOperation extends BaseReadWriteOperation // we don't cache passphrases during revocation cryptoInputParcel = cryptoInputParcel.withNoCachePassphrase(); - long masterKeyId = revokeKeyringParcel.mMasterKeyId; + long masterKeyId = revokeKeyringParcel.getMasterKeyId(); OperationResult.OperationLog log = new OperationResult.OperationLog(); log.add(OperationResult.LogType.MSG_REVOKE, 0, @@ -75,8 +75,8 @@ public class RevokeOperation extends BaseReadWriteOperation new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint()); // all revoke operations are made atomic as of now - saveKeyringParcel.setUpdateOptions(revokeKeyringParcel.mUpload, true, - revokeKeyringParcel.mKeyserver); + saveKeyringParcel.setUpdateOptions(revokeKeyringParcel.isShouldUpload(), true, + revokeKeyringParcel.getKeyserver()); saveKeyringParcel.mRevokeSubKeys.add(masterKeyId); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/RevokeKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/RevokeKeyringParcel.java index fb5de2713..bd5596771 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/RevokeKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/RevokeKeyringParcel.java @@ -19,50 +19,22 @@ package org.sufficientlysecure.keychain.service; -import android.os.Parcel; -import android.os.Parcelable; +import android.os.Parcelable; +import android.support.annotation.Nullable; + +import com.google.auto.value.AutoValue; import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; -public class RevokeKeyringParcel implements Parcelable { +@AutoValue +public abstract class RevokeKeyringParcel implements Parcelable { + public abstract long getMasterKeyId(); + public abstract boolean isShouldUpload(); + @Nullable + public abstract ParcelableHkpKeyserver getKeyserver(); - final public long mMasterKeyId; - final public boolean mUpload; - final public ParcelableHkpKeyserver mKeyserver; - - public RevokeKeyringParcel(long masterKeyId, boolean upload, ParcelableHkpKeyserver keyserver) { - mMasterKeyId = masterKeyId; - mUpload = upload; - mKeyserver = keyserver; + public static RevokeKeyringParcel createRevokeKeyringParcel(long masterKeyId, boolean upload, + ParcelableHkpKeyserver keyserver) { + return new AutoValue_RevokeKeyringParcel(masterKeyId, upload, keyserver); } - - protected RevokeKeyringParcel(Parcel in) { - mMasterKeyId = in.readLong(); - mUpload = in.readByte() != 0x00; - mKeyserver = in.readParcelable(ParcelableHkpKeyserver.class.getClassLoader()); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(mMasterKeyId); - dest.writeByte((byte) (mUpload ? 0x01 : 0x00)); - dest.writeParcelable(mKeyserver, flags); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public RevokeKeyringParcel createFromParcel(Parcel in) { - return new RevokeKeyringParcel(in); - } - - @Override - public RevokeKeyringParcel[] newArray(int size) { - return new RevokeKeyringParcel[size]; - } - }; } \ No newline at end of file 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 c1c865312..6ae40e880 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java @@ -151,7 +151,7 @@ public class DeleteKeyDialogActivity extends FragmentActivity { return new CryptoOperationHelper.Callback() { @Override public RevokeKeyringParcel createOperationInput() { - return new RevokeKeyringParcel(mMasterKeyIds[0], true, + return RevokeKeyringParcel.createRevokeKeyringParcel(mMasterKeyIds[0], true, (ParcelableHkpKeyserver) getIntent().getParcelableExtra(EXTRA_KEYSERVER)); } From 0095df6d8997b911c8dd3608ff8596f4ed1f2d41 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 12:24:38 +0200 Subject: [PATCH 08/23] use autovalue for PromoteKeyringParcel --- .../operations/PromoteKeyOperation.java | 13 +++-- .../service/PromoteKeyringParcel.java | 53 +++++-------------- .../ui/ViewKeySecurityTokenFragment.java | 2 +- .../operations/PromoteKeyOperationTest.java | 13 +++-- 4 files changed, 29 insertions(+), 52 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java index 80a787859..22b96db6a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java @@ -38,7 +38,6 @@ import org.sufficientlysecure.keychain.provider.KeyWritableRepository; import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.ProgressScaler; /** An operation which promotes a public key ring to a secret one. * @@ -67,17 +66,18 @@ public class PromoteKeyOperation extends BaseReadWriteOperation CREATOR = new Parcelable.Creator() { - @Override - public PromoteKeyringParcel createFromParcel(Parcel in) { - return new PromoteKeyringParcel(in); - } - - @Override - public PromoteKeyringParcel[] newArray(int size) { - return new PromoteKeyringParcel[size]; - } - }; } \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java index 4a7f4861d..bbea3973b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java @@ -213,7 +213,7 @@ public class ViewKeySecurityTokenFragment @Override public PromoteKeyringParcel createOperationInput() { - return new PromoteKeyringParcel(mMasterKeyId, mCardAid, mSubKeyIds); + return PromoteKeyringParcel.createPromoteKeyringParcel(mMasterKeyId, mCardAid, mSubKeyIds); } @Override diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java index 9b58ab511..00e6bc94e 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java @@ -106,7 +106,8 @@ public class PromoteKeyOperationTest { PromoteKeyOperation op = new PromoteKeyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null, null); - PromoteKeyResult result = op.execute(new PromoteKeyringParcel(mStaticRing.getMasterKeyId(), null, null), null); + PromoteKeyResult result = op.execute( + PromoteKeyringParcel.createPromoteKeyringParcel(mStaticRing.getMasterKeyId(), null, null), null); Assert.assertTrue("promotion must succeed", result.success()); @@ -132,7 +133,8 @@ public class PromoteKeyOperationTest { byte[] aid = Hex.decode("D2760001240102000000012345670000"); - PromoteKeyResult result = op.execute(new PromoteKeyringParcel(mStaticRing.getMasterKeyId(), aid, null), null); + PromoteKeyResult result = op.execute( + PromoteKeyringParcel.createPromoteKeyringParcel(mStaticRing.getMasterKeyId(), aid, null), null); Assert.assertTrue("promotion must succeed", result.success()); @@ -160,9 +162,10 @@ public class PromoteKeyOperationTest { // only promote the first, rest stays dummy long keyId = KeyringTestingHelper.getSubkeyId(mStaticRing, 1); - PromoteKeyResult result = op.execute(new PromoteKeyringParcel(mStaticRing.getMasterKeyId(), aid, new long[] { - keyId - }), null); + PromoteKeyResult result = op.execute( + PromoteKeyringParcel.createPromoteKeyringParcel(mStaticRing.getMasterKeyId(), aid, new long[] { + keyId + }), null); Assert.assertTrue("promotion must succeed", result.success()); From ef366173d0b942e4c9b9879d2a166bb42d33567b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 12:28:59 +0200 Subject: [PATCH 09/23] use autovalue for ImportKeyringParcel --- .../keychain/operations/ImportOperation.java | 8 +- .../keychain/service/ImportKeyringParcel.java | 76 +++++-------------- .../service/KeyserverSyncAdapterService.java | 4 +- ...reateSecurityTokenImportResetFragment.java | 2 +- .../keychain/ui/DecryptFragment.java | 2 +- .../keychain/ui/DecryptListFragment.java | 2 +- .../keychain/ui/ImportKeysActivity.java | 2 +- .../keychain/ui/ImportKeysProxyActivity.java | 2 +- .../keychain/ui/KeyListFragment.java | 2 +- .../keychain/ui/SafeSlingerActivity.java | 2 +- .../ui/adapter/ImportKeysAdapter.java | 6 +- .../keychain/ui/keyview/ViewKeyActivity.java | 2 +- .../keychain/util/EmailKeyHelper.java | 2 +- 13 files changed, 39 insertions(+), 73 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java index 25fb4cdbb..2ebcd1e6d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java @@ -469,9 +469,9 @@ public class ImportOperation extends BaseReadWriteOperation @NonNull @Override public ImportKeyResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) { - ArrayList keyList = importInput.mKeyList; - ParcelableHkpKeyserver keyServer = importInput.mKeyserver; - boolean skipSave = importInput.mSkipSave; + ArrayList keyList = importInput.getKeyList(); + ParcelableHkpKeyserver keyServer = importInput.getKeyserver(); + boolean skipSave = importInput.isSkipSave(); ImportKeyResult result; if (keyList == null) {// import from file, do serially @@ -495,7 +495,7 @@ public class ImportOperation extends BaseReadWriteOperation result = multiThreadedKeyImport(keyList, keyServer, proxy, skipSave); } - if (!importInput.mSkipSave) { + if (!skipSave) { ContactSyncAdapterService.requestContactsSync(); } return result; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java index 050e126a9..663013ac2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ImportKeyringParcel.java @@ -18,69 +18,31 @@ package org.sufficientlysecure.keychain.service; -import android.os.Parcel; -import android.os.Parcelable; - -import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; -import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; import java.util.ArrayList; -public class ImportKeyringParcel implements Parcelable { - // If null, keys are expected to be read from a cache file in ImportExportOperations - public ArrayList mKeyList; - public ParcelableHkpKeyserver mKeyserver; // must be set if keys are to be imported from a keyserver +import android.os.Parcelable; +import android.support.annotation.Nullable; - // If false, don't save the key, only return it as part of result - public boolean mSkipSave = false; +import com.google.auto.value.AutoValue; +import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; - public ImportKeyringParcel(ArrayList keyList, ParcelableHkpKeyserver keyserver) { - mKeyList = keyList; - mKeyserver = keyserver; +@AutoValue +public abstract class ImportKeyringParcel implements Parcelable { + @Nullable // If null, keys are expected to be read from a cache file in ImportExportOperations + public abstract ArrayList getKeyList(); + @Nullable // must be set if keys are to be imported from a keyserver + public abstract ParcelableHkpKeyserver getKeyserver(); + public abstract boolean isSkipSave(); + + public static ImportKeyringParcel createImportKeyringParcel(ArrayList keyList, + ParcelableHkpKeyserver keyserver) { + return new AutoValue_ImportKeyringParcel(keyList, keyserver, false); } - public ImportKeyringParcel(ArrayList keyList, ParcelableHkpKeyserver keyserver, boolean skipSave) { - this(keyList, keyserver); - mSkipSave = skipSave; + public static ImportKeyringParcel createWithSkipSave(ArrayList keyList, + ParcelableHkpKeyserver keyserver) { + return new AutoValue_ImportKeyringParcel(keyList, keyserver, true); } - - protected ImportKeyringParcel(Parcel in) { - if (in.readByte() == 0x01) { - mKeyList = new ArrayList<>(); - in.readList(mKeyList, ParcelableKeyRing.class.getClassLoader()); - } else { - mKeyList = null; - } - mKeyserver = in.readParcelable(ParcelableHkpKeyserver.class.getClassLoader()); - mSkipSave = in.readInt() != 0; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - if (mKeyList == null) { - dest.writeByte((byte) (0x00)); - } else { - dest.writeByte((byte) (0x01)); - dest.writeList(mKeyList); - } - dest.writeParcelable(mKeyserver, flags); - dest.writeInt(mSkipSave ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public ImportKeyringParcel createFromParcel(Parcel in) { - return new ImportKeyringParcel(in); - } - - @Override - public ImportKeyringParcel[] newArray(int size) { - return new ImportKeyringParcel[size]; - } - }; } \ No newline at end of file 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 9ff89df18..cdde34e87 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java @@ -324,7 +324,7 @@ public class KeyserverSyncAdapterService extends Service { ImportOperation importOp = new ImportOperation(context, KeyWritableRepository.createDatabaseReadWriteInteractor(context), null); return importOp.execute( - new ImportKeyringParcel(keyList, + ImportKeyringParcel.createImportKeyringParcel(keyList, Preferences.getPreferences(context).getPreferredKeyserver()), cryptoInputParcel ); @@ -384,7 +384,7 @@ public class KeyserverSyncAdapterService extends Service { ImportKeyResult result = new ImportOperation(context, KeyWritableRepository.createDatabaseReadWriteInteractor(context), null, mCancelled) .execute( - new ImportKeyringParcel( + ImportKeyringParcel.createImportKeyringParcel( keyWrapper, Preferences.getPreferences(context) .getPreferredKeyserver() 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 eab4525a0..d9b5ef62b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java @@ -271,7 +271,7 @@ public class CreateSecurityTokenImportResetFragment @Override public ImportKeyringParcel createOperationInput() { - return new ImportKeyringParcel(mKeyList, mKeyserver); + return ImportKeyringParcel.createImportKeyringParcel(mKeyList, mKeyserver); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 5c1627e1b..766432f56 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -159,7 +159,7 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager. @Override public ImportKeyringParcel createOperationInput() { - return new ImportKeyringParcel(keyList, keyserver); + return ImportKeyringParcel.createImportKeyringParcel(keyList, keyserver); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index ea1ce2a31..4a5e2563c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -779,7 +779,7 @@ public class DecryptListFragment @Override public ImportKeyringParcel createOperationInput() { - return new ImportKeyringParcel(keyList, keyserver); + return ImportKeyringParcel.createImportKeyringParcel(keyList, keyserver); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index a6bd1e552..e3764cde1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -357,7 +357,7 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen return; } - ImportKeyringParcel inputParcel = new ImportKeyringParcel(null, null); + ImportKeyringParcel inputParcel = ImportKeyringParcel.createImportKeyringParcel(null, null); ImportKeysOperationCallback callback = new ImportKeysOperationCallback(this, inputParcel, null); mOpHelper = new CryptoOperationHelper<>(1, this, callback, R.string.progress_importing); mOpHelper.cryptoOperation(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java index 440e74124..bbce27a21 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java @@ -223,7 +223,7 @@ public class ImportKeysProxyActivity extends FragmentActivity @Override public ImportKeyringParcel createOperationInput() { - return new ImportKeyringParcel(mKeyList, mKeyserver); + return ImportKeyringParcel.createImportKeyringParcel(mKeyList, mKeyserver); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 62ba0e872..cf7540d45 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -519,7 +519,7 @@ public class KeyListFragment extends RecyclerFragment @Override public ImportKeyringParcel createOperationInput() { - return new ImportKeyringParcel(mKeyList, mKeyserver); + return ImportKeyringParcel.createImportKeyringParcel(mKeyList, mKeyserver); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java index 5fdaefbcc..e5272ec02 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java @@ -185,7 +185,7 @@ public class SafeSlingerActivity extends BaseActivity @Override public ImportKeyringParcel createOperationInput() { - return new ImportKeyringParcel(mKeyList, mKeyserver); + return ImportKeyringParcel.createImportKeyringParcel(mKeyList, mKeyserver); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 2c6d37a07..3d97d17e4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -237,7 +237,11 @@ public class ImportKeysAdapter extends RecyclerView.Adapter Date: Mon, 22 May 2017 12:33:44 +0200 Subject: [PATCH 10/23] use autovalue for DeleteKeyringParcel --- .../keychain/operations/DeleteOperation.java | 4 +- .../keychain/service/DeleteKeyringParcel.java | 45 +++++-------------- .../keychain/ui/DeleteKeyDialogActivity.java | 7 ++- 3 files changed, 19 insertions(+), 37 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java index 94cf279bf..b111efa5b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/DeleteOperation.java @@ -52,8 +52,8 @@ public class DeleteOperation extends BaseReadWriteOperation public OperationResult execute(DeleteKeyringParcel deleteKeyringParcel, CryptoInputParcel cryptoInputParcel) { - long[] masterKeyIds = deleteKeyringParcel.mMasterKeyIds; - boolean isSecret = deleteKeyringParcel.mIsSecret; + long[] masterKeyIds = deleteKeyringParcel.getMasterKeyIds(); + boolean isSecret = deleteKeyringParcel.isDeleteSecret(); return onlyDeleteKey(masterKeyIds, isSecret); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java index b412a6e2b..ebc37bbc8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java @@ -19,45 +19,24 @@ package org.sufficientlysecure.keychain.service; -import android.os.Parcel; + import android.os.Parcelable; -public class DeleteKeyringParcel implements Parcelable { +import com.google.auto.value.AutoValue; - public long[] mMasterKeyIds; - public boolean mIsSecret; - public DeleteKeyringParcel(long[] masterKeyIds, boolean isSecret) { - mMasterKeyIds = masterKeyIds; - mIsSecret = isSecret; +@AutoValue +public abstract class DeleteKeyringParcel implements Parcelable { + public abstract long[] getMasterKeyIds(); + public abstract boolean isDeleteSecret(); + + + public static DeleteKeyringParcel createDeletePublicKeysParcel(long[] masterKeyIds) { + return new AutoValue_DeleteKeyringParcel(masterKeyIds, false); } - protected DeleteKeyringParcel(Parcel in) { - mIsSecret = in.readByte() != 0x00; - mMasterKeyIds = in.createLongArray(); + public static DeleteKeyringParcel createDeleteSingleSecretKeyParcel(long masterKeyId) { + return new AutoValue_DeleteKeyringParcel(new long[] { masterKeyId }, true); } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeByte((byte) (mIsSecret ? 0x01 : 0x00)); - dest.writeLongArray(mMasterKeyIds); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public DeleteKeyringParcel createFromParcel(Parcel in) { - return new DeleteKeyringParcel(in); - } - - @Override - public DeleteKeyringParcel[] newArray(int size) { - return new DeleteKeyringParcel[size]; - } - }; } 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 6ae40e880..a6b4db1af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java @@ -183,9 +183,12 @@ public class DeleteKeyDialogActivity extends FragmentActivity { return new CryptoOperationHelper.Callback() { @Override public DeleteKeyringParcel createOperationInput() { - return new DeleteKeyringParcel(mMasterKeyIds, mHasSecret); + if (mHasSecret) { + return DeleteKeyringParcel.createDeleteSingleSecretKeyParcel(mMasterKeyIds[0]); + } else { + return DeleteKeyringParcel.createDeletePublicKeysParcel(mMasterKeyIds); + } } - @Override public void onCryptoOperationSuccess(DeleteResult result) { returnResult(result); From c444ccb781b8f1fc5360e0aa0c53c7e2ae65790c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 12:35:54 +0200 Subject: [PATCH 11/23] use autovalue for ConsolidateInputParcel --- .../operations/ConsolidateOperation.java | 2 +- .../service/ConsolidateInputParcel.java | 39 ++++--------------- .../ui/ConsolidateDialogActivity.java | 2 +- .../keychain/ui/KeyListFragment.java | 2 +- 4 files changed, 11 insertions(+), 34 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java index 7c04e3442..da0d34b87 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ConsolidateOperation.java @@ -39,7 +39,7 @@ public class ConsolidateOperation extends BaseReadWriteOperation CREATOR = new Parcelable.Creator() { - @Override - public ConsolidateInputParcel createFromParcel(Parcel in) { - return new ConsolidateInputParcel(in); - } - - @Override - public ConsolidateInputParcel[] newArray(int size) { - return new ConsolidateInputParcel[size]; - } - }; } \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java index ff5fb7cca..cc2dd7131 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java @@ -67,7 +67,7 @@ public class ConsolidateDialogActivity extends FragmentActivity @Override public ConsolidateInputParcel createOperationInput() { - return new ConsolidateInputParcel(mRecovery); + return ConsolidateInputParcel.createConsolidateInputParcel(mRecovery); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index cf7540d45..d60f8da32 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -553,7 +553,7 @@ public class KeyListFragment extends RecyclerFragment @Override public ConsolidateInputParcel createOperationInput() { - return new ConsolidateInputParcel(false); // we want to perform a full consolidate + return ConsolidateInputParcel.createConsolidateInputParcel(false); // we want to perform a full consolidate } @Override From d3357ccf5ca4132c4059a9ecb3772d727c93f0ec Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 12:43:30 +0200 Subject: [PATCH 12/23] use autovalue for ChangeUnlockParcel --- .../operations/ChangeUnlockOperation.java | 6 +- .../keychain/pgp/PgpKeyOperation.java | 9 ++- .../keychain/service/ChangeUnlockParcel.java | 74 ++++--------------- .../keychain/service/SaveKeyringParcel.java | 4 - .../keychain/ui/CreateKeyFinalFragment.java | 5 +- .../keychain/ui/EditKeyFragment.java | 3 +- .../keychain/ui/keyview/ViewKeyActivity.java | 5 +- .../operations/BackupOperationTest.java | 4 +- .../operations/CertifyOperationTest.java | 4 +- .../operations/PromoteKeyOperationTest.java | 2 +- .../keychain/pgp/PgpKeyOperationTest.java | 22 +++--- .../pgp/UncachedKeyringCanonicalizeTest.java | 2 +- .../pgp/UncachedKeyringMergeTest.java | 10 +-- .../keychain/pgp/UncachedKeyringTest.java | 2 +- 14 files changed, 51 insertions(+), 101 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ChangeUnlockOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ChangeUnlockOperation.java index 6e4b72f00..ddd6fd182 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ChangeUnlockOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ChangeUnlockOperation.java @@ -47,7 +47,7 @@ public class ChangeUnlockOperation extends BaseReadWriteOperation CREATOR = new Creator() { - public ChangeUnlockParcel createFromParcel(final Parcel source) { - return new ChangeUnlockParcel(source); - } - - public ChangeUnlockParcel[] newArray(final int size) { - return new ChangeUnlockParcel[size]; - } - }; - - public String toString() { - String out = "mMasterKeyId: " + mMasterKeyId + "\n"; - out += "passphrase (" + mNewPassphrase + ")"; - - return out; - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index fe0f14598..9c0648bc6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -109,10 +109,6 @@ public class SaveKeyringParcel implements Parcelable { } public ChangeUnlockParcel getChangeUnlockParcel() { - if(mNewUnlock != null) { - mNewUnlock.mMasterKeyId = mMasterKeyId; - mNewUnlock.mFingerprint = mFingerprint; - } return mNewUnlock; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 53956119d..35998e620 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -307,12 +307,13 @@ public class CreateKeyFinalFragment extends Fragment { createKeyActivity.mSecurityTokenAuth.addToSaveKeyringParcel(saveKeyringParcel, KeyFlags.AUTHENTICATION); // use empty passphrase - saveKeyringParcel.setNewUnlock(new ChangeUnlockParcel(new Passphrase())); + saveKeyringParcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); } else { Constants.addDefaultSubkeys(saveKeyringParcel); if (createKeyActivity.mPassphrase != null) { - saveKeyringParcel.setNewUnlock(new ChangeUnlockParcel(createKeyActivity.mPassphrase)); + saveKeyringParcel.setNewUnlock( + ChangeUnlockParcel.createUnLockParcelForNewKey(createKeyActivity.mPassphrase)); } else { saveKeyringParcel.setNewUnlock(null); } 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 336916e3e..dfe1d98e5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -341,7 +341,8 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment Date: Mon, 22 May 2017 12:55:31 +0200 Subject: [PATCH 13/23] use autovalue for ParcelableS2K --- .../keychain/pgp/ComparableS2K.java | 121 ------------------ .../keychain/pgp/ParcelableS2K.java | 57 +++++++++ .../keychain/util/Passphrase.java | 12 +- 3 files changed, 63 insertions(+), 127 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ComparableS2K.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ComparableS2K.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ComparableS2K.java deleted file mode 100644 index 99b9cdab2..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ComparableS2K.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2016 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 - * 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.pgp; - - -import java.util.Arrays; - -import android.os.Parcel; -import android.os.Parcelable; - -import org.bouncycastle.bcpg.S2K; - - -/** This is an immutable and parcelable class which stores the full s2k parametrization - * of an encrypted secret key, i.e. all fields of the {@link S2K} class (type, hash algo, - * iteration count, iv) plus the encryptionAlgorithm. This class is intended to be used - * as key in a HashMap for session key caching purposes, and overrides the - * {@link #hashCode} and {@link #equals} methods in a suitable way. - * - * Note that although it is a rather unlikely scenario that secret keys of the same key - * are encrypted with different ciphers, the encryption algorithm still determines the - * length of the specific session key and thus needs to be considered for purposes of - * session key caching. - * - * @see org.bouncycastle.bcpg.S2K - */ -public class ComparableS2K implements Parcelable { - - private final int encryptionAlgorithm; - private final int s2kType; - private final int s2kHashAlgo; - private final long s2kItCount; - private final byte[] s2kIV; - - Integer cachedHashCode; - - public ComparableS2K(int encryptionAlgorithm, S2K s2k) { - this.encryptionAlgorithm = encryptionAlgorithm; - this.s2kType = s2k.getType(); - this.s2kHashAlgo = s2k.getHashAlgorithm(); - this.s2kItCount = s2k.getIterationCount(); - this.s2kIV = s2k.getIV(); - } - - protected ComparableS2K(Parcel in) { - encryptionAlgorithm = in.readInt(); - s2kType = in.readInt(); - s2kHashAlgo = in.readInt(); - s2kItCount = in.readLong(); - s2kIV = in.createByteArray(); - } - - @Override - public int hashCode() { - if (cachedHashCode == null) { - cachedHashCode = encryptionAlgorithm; - cachedHashCode = 31 * cachedHashCode + s2kType; - cachedHashCode = 31 * cachedHashCode + s2kHashAlgo; - cachedHashCode = 31 * cachedHashCode + (int) (s2kItCount ^ (s2kItCount >>> 32)); - cachedHashCode = 31 * cachedHashCode + Arrays.hashCode(s2kIV); - } - - return cachedHashCode; - } - - @Override - public boolean equals(Object o) { - boolean isComparableS2K = o instanceof ComparableS2K; - if (!isComparableS2K) { - return false; - } - ComparableS2K other = (ComparableS2K) o; - return encryptionAlgorithm == other.encryptionAlgorithm - && s2kType == other.s2kType - && s2kHashAlgo == other.s2kHashAlgo - && s2kItCount == other.s2kItCount - && Arrays.equals(s2kIV, other.s2kIV); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(encryptionAlgorithm); - dest.writeInt(s2kType); - dest.writeInt(s2kHashAlgo); - dest.writeLong(s2kItCount); - dest.writeByteArray(s2kIV); - } - - public static final Creator CREATOR = new Creator() { - @Override - public ComparableS2K createFromParcel(Parcel in) { - return new ComparableS2K(in); - } - - @Override - public ComparableS2K[] newArray(int size) { - return new ComparableS2K[size]; - } - }; - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java new file mode 100644 index 000000000..78b72e90b --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 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 + * 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.pgp; + + +import android.os.Parcelable; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import org.bouncycastle.bcpg.S2K; + + +/** This is an immutable and parcelable class which stores the full s2k parametrization + * of an encrypted secret key, i.e. all fields of the {@link S2K} class (type, hash algo, + * iteration count, iv) plus the encryptionAlgorithm. This class is intended to be used + * as key in a HashMap for session key caching purposes, and overrides the + * {@link #hashCode} and {@link #equals} methods in a suitable way. + * + * Note that although it is a rather unlikely scenario that secret keys of the same key + * are encrypted with different ciphers, the encryption algorithm still determines the + * length of the specific session key and thus needs to be considered for purposes of + * session key caching. + * + * @see org.bouncycastle.bcpg.S2K + */ +@AutoValue +public abstract class ParcelableS2K implements Parcelable { + abstract int getEncryptionAlgorithm(); + abstract int getS2kType(); + abstract int getS2kHashAlgo(); + abstract long getS2kItCount(); + abstract byte[] getS2kIV(); + + @Memoized + @Override + public abstract int hashCode(); + + public static ParcelableS2K fromS2K(int encryptionAlgorithm, S2K s2k) { + return new AutoValue_ParcelableS2K(encryptionAlgorithm, + s2k.getType(), s2k.getHashAlgorithm(), s2k.getIterationCount(), s2k.getIV()); + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java index b49b30d1d..b3f06b0f7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java @@ -25,7 +25,7 @@ import android.widget.EditText; import org.bouncycastle.bcpg.S2K; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.pgp.ComparableS2K; +import org.sufficientlysecure.keychain.pgp.ParcelableS2K; import java.util.Arrays; import java.util.HashMap; @@ -49,7 +49,7 @@ import java.util.Map.Entry; */ public class Passphrase implements Parcelable { private char[] mPassphrase; - private HashMap mCachedSessionKeys; + private HashMap mCachedSessionKeys; /** * According to http://stackoverflow.com/a/15844273 EditText is not using String internally @@ -104,7 +104,7 @@ public class Passphrase implements Parcelable { if (mCachedSessionKeys == null) { return null; } - return mCachedSessionKeys.get(new ComparableS2K(keyEncryptionAlgorithm, s2k)); + return mCachedSessionKeys.get(ParcelableS2K.fromS2K(keyEncryptionAlgorithm, s2k)); } /** Adds a session key for a set of s2k parameters to this Passphrase object's @@ -116,7 +116,7 @@ public class Passphrase implements Parcelable { if (mCachedSessionKeys == null) { mCachedSessionKeys = new HashMap<>(); } - mCachedSessionKeys.put(new ComparableS2K(keyEncryptionAlgorithm, s2k), sessionKey); + mCachedSessionKeys.put(ParcelableS2K.fromS2K(keyEncryptionAlgorithm, s2k), sessionKey); } /** @@ -184,7 +184,7 @@ public class Passphrase implements Parcelable { } mCachedSessionKeys = new HashMap<>(size); for (int i = 0; i < size; i++) { - ComparableS2K cachedS2K = source.readParcelable(getClass().getClassLoader()); + ParcelableS2K cachedS2K = source.readParcelable(getClass().getClassLoader()); byte[] cachedSessionKey = source.createByteArray(); mCachedSessionKeys.put(cachedS2K, cachedSessionKey); } @@ -197,7 +197,7 @@ public class Passphrase implements Parcelable { return; } dest.writeInt(mCachedSessionKeys.size()); - for (Entry entry : mCachedSessionKeys.entrySet()) { + for (Entry entry : mCachedSessionKeys.entrySet()) { dest.writeParcelable(entry.getKey(), 0); dest.writeByteArray(entry.getValue()); } From 147e4dbee74cba916ff6a87376df357bfdbcd988 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 22 May 2017 13:44:58 +0200 Subject: [PATCH 14/23] use autovalue for SubkeyAdd and SubkeyChange --- .../keychain/Constants.java | 7 +- .../keychain/pgp/PgpKeyOperation.java | 128 +++++++++--------- .../keychain/pgp/WrappedUserAttribute.java | 1 + .../keychain/securitytoken/ECKeyFormat.java | 4 +- .../keychain/securitytoken/RSAKeyFormat.java | 4 +- .../keychain/service/SaveKeyringParcel.java | 121 +++++++---------- .../keychain/ui/CreateKeyFinalFragment.java | 3 +- .../keychain/ui/EditKeyFragment.java | 38 ++---- .../ui/ViewKeyAdvSubkeysFragment.java | 39 ++---- .../keychain/ui/adapter/SubkeysAdapter.java | 10 +- .../ui/adapter/SubkeysAddedAdapter.java | 12 +- .../ui/dialog/AddSubkeyDialogFragment.java | 3 +- .../operations/BackupOperationTest.java | 13 +- .../operations/CertifyOperationTest.java | 13 +- .../operations/PromoteKeyOperationTest.java | 7 +- .../keychain/pgp/PgpEncryptDecryptTest.java | 4 +- .../keychain/pgp/PgpKeyOperationTest.java | 74 +++++----- .../pgp/UncachedKeyringCanonicalizeTest.java | 9 +- .../pgp/UncachedKeyringMergeTest.java | 9 +- .../keychain/pgp/UncachedKeyringTest.java | 7 +- 20 files changed, 239 insertions(+), 267 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 470620bf2..5e4fa5f80 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -24,6 +24,7 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.sufficientlysecure.keychain.securitytoken.KeyFormat; import org.sufficientlysecure.keychain.securitytoken.RSAKeyFormat; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import java.io.File; import java.net.Proxy; @@ -179,11 +180,11 @@ public final class Constants { * Default key configuration: 3072 bit RSA (certify, sign, encrypt) */ public static void addDefaultSubkeys(SaveKeyringParcel saveKeyringParcel) { - saveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, 3072, null, KeyFlags.CERTIFY_OTHER, 0L)); - saveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, 3072, null, KeyFlags.SIGN_DATA, 0L)); - saveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, 3072, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); } 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 8b2eb90ab..91dc06921 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -29,6 +29,7 @@ import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.ECGenParameterSpec; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Iterator; @@ -81,6 +82,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.SecurityTokenKeyToCardOperationsBuilder; @@ -166,17 +168,17 @@ public class PgpKeyOperation { try { // Some safety checks - if (add.mAlgorithm == Algorithm.ECDH || add.mAlgorithm == Algorithm.ECDSA) { - if (add.mCurve == null) { + if (add.getAlgorithm() == Algorithm.ECDH || add.getAlgorithm() == Algorithm.ECDSA) { + if (add.getCurve() == null) { log.add(LogType.MSG_CR_ERROR_NO_CURVE, indent); return null; } } else { - if (add.mKeySize == null) { + if (add.getKeySize() == null) { log.add(LogType.MSG_CR_ERROR_NO_KEYSIZE, indent); return null; } - if (add.mKeySize < 2048) { + if (add.getKeySize() < 2048) { log.add(LogType.MSG_CR_ERROR_KEYSIZE_2048, indent); return null; } @@ -185,27 +187,27 @@ public class PgpKeyOperation { int algorithm; KeyPairGenerator keyGen; - switch (add.mAlgorithm) { + switch (add.getAlgorithm()) { case DSA: { - if ((add.mFlags & (PGPKeyFlags.CAN_ENCRYPT_COMMS | PGPKeyFlags.CAN_ENCRYPT_STORAGE)) > 0) { + if ((add.getFlags() & (PGPKeyFlags.CAN_ENCRYPT_COMMS | PGPKeyFlags.CAN_ENCRYPT_STORAGE)) > 0) { log.add(LogType.MSG_CR_ERROR_FLAGS_DSA, indent); return null; } progress(R.string.progress_generating_dsa, 30); keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - keyGen.initialize(add.mKeySize, new SecureRandom()); + keyGen.initialize(add.getKeySize(), new SecureRandom()); algorithm = PGPPublicKey.DSA; break; } case ELGAMAL: { - if ((add.mFlags & (PGPKeyFlags.CAN_SIGN | PGPKeyFlags.CAN_CERTIFY)) > 0) { + if ((add.getFlags() & (PGPKeyFlags.CAN_SIGN | PGPKeyFlags.CAN_CERTIFY)) > 0) { log.add(LogType.MSG_CR_ERROR_FLAGS_ELGAMAL, indent); return null; } progress(R.string.progress_generating_elgamal, 30); keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - BigInteger p = Primes.getBestPrime(add.mKeySize); + BigInteger p = Primes.getBestPrime(add.getKeySize()); BigInteger g = new BigInteger("2"); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); @@ -218,19 +220,19 @@ public class PgpKeyOperation { case RSA: { progress(R.string.progress_generating_rsa, 30); keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); - keyGen.initialize(add.mKeySize, new SecureRandom()); + keyGen.initialize(add.getKeySize(), new SecureRandom()); algorithm = PGPPublicKey.RSA_GENERAL; break; } case ECDSA: { - if ((add.mFlags & (PGPKeyFlags.CAN_ENCRYPT_COMMS | PGPKeyFlags.CAN_ENCRYPT_STORAGE)) > 0) { + if ((add.getFlags() & (PGPKeyFlags.CAN_ENCRYPT_COMMS | PGPKeyFlags.CAN_ENCRYPT_STORAGE)) > 0) { log.add(LogType.MSG_CR_ERROR_FLAGS_ECDSA, indent); return null; } progress(R.string.progress_generating_ecdsa, 30); - ECGenParameterSpec ecParamSpec = getEccParameterSpec(add.mCurve); + ECGenParameterSpec ecParamSpec = getEccParameterSpec(add.getCurve()); keyGen = KeyPairGenerator.getInstance("ECDSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); keyGen.initialize(ecParamSpec, new SecureRandom()); @@ -240,12 +242,12 @@ public class PgpKeyOperation { case ECDH: { // make sure there are no sign or certify flags set - if ((add.mFlags & (PGPKeyFlags.CAN_SIGN | PGPKeyFlags.CAN_CERTIFY)) > 0) { + if ((add.getFlags() & (PGPKeyFlags.CAN_SIGN | PGPKeyFlags.CAN_CERTIFY)) > 0) { log.add(LogType.MSG_CR_ERROR_FLAGS_ECDH, indent); return null; } progress(R.string.progress_generating_ecdh, 30); - ECGenParameterSpec ecParamSpec = getEccParameterSpec(add.mCurve); + ECGenParameterSpec ecParamSpec = getEccParameterSpec(add.getCurve()); keyGen = KeyPairGenerator.getInstance("ECDH", Constants.BOUNCY_CASTLE_PROVIDER_NAME); keyGen.initialize(ecParamSpec, new SecureRandom()); @@ -296,12 +298,12 @@ public class PgpKeyOperation { } SubkeyAdd add = saveParcel.mAddSubKeys.remove(0); - if ((add.mFlags & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) { + if ((add.getFlags() & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) { log.add(LogType.MSG_CR_ERROR_NO_CERTIFY, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (add.mExpiry == null) { + if (add.getExpiry() == null) { log.add(LogType.MSG_CR_ERROR_NULL_EXPIRY, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } @@ -337,7 +339,7 @@ public class PgpKeyOperation { subProgressPush(50, 100); CryptoInputParcel cryptoInput = CryptoInputParcel.createCryptoInputParcel(creationTime, new Passphrase("")); - return internal(sKR, masterSecretKey, add.mFlags, add.mExpiry, cryptoInput, saveParcel, log, indent); + return internal(sKR, masterSecretKey, add.getFlags(), add.getExpiry(), cryptoInput, saveParcel, log, indent); } catch (PGPException e) { log.add(LogType.MSG_CR_ERROR_INTERNAL_PGP, indent); @@ -417,25 +419,25 @@ public class PgpKeyOperation { boolean hasSign = false; boolean hasEncrypt = false; boolean hasAuth = false; - for(SaveKeyringParcel.SubkeyChange change : saveParcel.mChangeSubKeys) { - if (change.mMoveKeyToSecurityToken) { + for (SaveKeyringParcel.SubkeyChange change : new ArrayList<>(saveParcel.mChangeSubKeys)) { + if (change.getMoveKeyToSecurityToken()) { // If this is a moveKeyToSecurityToken operation, see if it was completed: look for a hash // matching the given subkey ID in cryptoData. byte[] subKeyId = new byte[8]; ByteBuffer buf = ByteBuffer.wrap(subKeyId); - buf.putLong(change.mKeyId).rewind(); + buf.putLong(change.getSubKeyId()).rewind(); byte[] serialNumber = cryptoInput.getCryptoData().get(buf); if (serialNumber != null) { - change.mMoveKeyToSecurityToken = false; - change.mSecurityTokenSerialNo = serialNumber; + saveParcel.addOrReplaceSubkeyChange( + SubkeyChange.createSecurityTokenSerialNo(change.getSubKeyId(), serialNumber)); } } - if (change.mMoveKeyToSecurityToken) { + if (change.getMoveKeyToSecurityToken()) { // Pending moveKeyToSecurityToken operation. Need to make sure that we don't have multiple // subkeys pending for the same slot. - CanonicalizedSecretKey wsK = wsKR.getSecretKey(change.mKeyId); + CanonicalizedSecretKey wsK = wsKR.getSecretKey(change.getSubKeyId()); if ((wsK.canSign() || wsK.canCertify())) { if (hasSign) { @@ -806,62 +808,62 @@ public class PgpKeyOperation { progress(R.string.progress_modify_subkeychange, (i-1) * (100 / saveParcel.mChangeSubKeys.size())); SaveKeyringParcel.SubkeyChange change = saveParcel.mChangeSubKeys.get(i); log.add(LogType.MSG_MF_SUBKEY_CHANGE, - indent, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); - PGPSecretKey sKey = sKR.getSecretKey(change.mKeyId); + PGPSecretKey sKey = sKR.getSecretKey(change.getSubKeyId()); if (sKey == null) { log.add(LogType.MSG_MF_ERROR_SUBKEY_MISSING, - indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (change.mDummyStrip) { + if (change.getDummyStrip()) { // IT'S DANGEROUS~ // no really, it is. this operation irrevocably removes the private key data from the key sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey()); sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey); - } else if (change.mMoveKeyToSecurityToken) { + } else if (change.getMoveKeyToSecurityToken()) { if (checkSecurityTokenCompatibility(sKey, log, indent + 1)) { log.add(LogType.MSG_MF_KEYTOCARD_START, indent + 1, - KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); - nfcKeyToCardOps.addSubkey(change.mKeyId); + KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); + nfcKeyToCardOps.addSubkey(change.getSubKeyId()); } else { // Appropriate log message already set by checkSecurityTokenCompatibility return new PgpEditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } - } else if (change.mSecurityTokenSerialNo != null) { + } else if (change.getSecurityTokenSerialNo() != null) { // NOTE: Does this code get executed? Or always handled in internalRestricted? - if (change.mSecurityTokenSerialNo.length != 16) { + if (change.getSecurityTokenSerialNo().length != 16) { log.add(LogType.MSG_MF_ERROR_DIVERT_SERIAL, - indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } log.add(LogType.MSG_MF_KEYTOCARD_FINISH, indent + 1, - KeyFormattingUtils.convertKeyIdToHex(change.mKeyId), - Hex.toHexString(change.mSecurityTokenSerialNo, 8, 6)); - sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey(), change.mSecurityTokenSerialNo); + KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId()), + Hex.toHexString(change.getSecurityTokenSerialNo(), 8, 6)); + sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey(), change.getSecurityTokenSerialNo()); sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey); } // This doesn't concern us any further - if (!change.mRecertify && (change.mExpiry == null && change.mFlags == null)) { + if (!change.getRecertify() && (change.getExpiry() == null && change.getFlags() == null)) { continue; } // expiry must not be in the past - if (change.mExpiry != null && change.mExpiry != 0 && - new Date(change.mExpiry*1000).before(new Date())) { + if (change.getExpiry() != null && change.getExpiry() != 0 && + new Date(change.getExpiry() * 1000).before(new Date())) { log.add(LogType.MSG_MF_ERROR_PAST_EXPIRY, - indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } // if this is the master key, update uid certificates instead - if (change.mKeyId == masterPublicKey.getKeyID()) { - int flags = change.mFlags == null ? masterKeyFlags : change.mFlags; - long expiry = change.mExpiry == null ? masterKeyExpiry : change.mExpiry; + if (change.getSubKeyId() == masterPublicKey.getKeyID()) { + int flags = change.getFlags() == null ? masterKeyFlags : change.getFlags(); + long expiry = change.getExpiry() == null ? masterKeyExpiry : change.getExpiry(); if ((flags & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) { log.add(LogType.MSG_MF_ERROR_NO_CERTIFY, indent + 1); @@ -886,22 +888,22 @@ public class PgpKeyOperation { PGPPublicKey pKey = sKey.getPublicKey(); // keep old flags, or replace with new ones - int flags = change.mFlags == null ? readKeyFlags(pKey) : change.mFlags; + int flags = change.getFlags() == null ? readKeyFlags(pKey) : change.getFlags(); long expiry; - if (change.mExpiry == null) { + if (change.getExpiry() == null) { long valid = pKey.getValidSeconds(); expiry = valid == 0 ? 0 : pKey.getCreationTime().getTime() / 1000 + pKey.getValidSeconds(); } else { - expiry = change.mExpiry; + expiry = change.getExpiry(); } // drop all old signatures, they will be superseded by the new one //noinspection unchecked for (PGPSignature sig : new IterableIterator(pKey.getSignatures())) { // special case: if there is a revocation, don't use expiry from before - if ( (change.mExpiry == null || change.mExpiry == 0L) + if ( (change.getExpiry() == null || change.getExpiry() == 0L) && sig.getSignatureType() == PGPSignature.SUBKEY_REVOCATION) { expiry = 0; } @@ -917,7 +919,7 @@ public class PgpKeyOperation { // super special case: subkey is allowed to sign, but isn't available if (subPrivateKey == null) { log.add(LogType.MSG_MF_ERROR_SUB_STRIPPED, - indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } } else { @@ -985,19 +987,19 @@ public class PgpKeyOperation { progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size())); SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i); log.add(LogType.MSG_MF_SUBKEY_NEW, indent, - KeyFormattingUtils.getAlgorithmInfo(add.mAlgorithm, add.mKeySize, add.mCurve) ); + KeyFormattingUtils.getAlgorithmInfo(add.getAlgorithm(), add.getKeySize(), add.getCurve()) ); if (isDivertToCard(masterSecretKey)) { log.add(LogType.MSG_MF_ERROR_DIVERT_NEWSUB, indent +1); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (add.mExpiry == null) { + if (add.getExpiry() == null) { log.add(LogType.MSG_MF_ERROR_NULL_EXPIRY, indent +1); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (add.mExpiry > 0L && new Date(add.mExpiry*1000).before(new Date())) { + if (add.getExpiry() > 0L && new Date(add.getExpiry() * 1000).before(new Date())) { log.add(LogType.MSG_MF_ERROR_PAST_EXPIRY, indent +1); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } @@ -1022,7 +1024,7 @@ public class PgpKeyOperation { cryptoInput.getSignatureTime(), masterPublicKey, masterPrivateKey, getSignatureGenerator(pKey, cryptoInput, false), keyPair.getPrivateKey(), pKey, - add.mFlags, add.mExpiry); + add.getFlags(), add.getExpiry()); pKey = PGPPublicKey.addSubkeyBindingCertification(pKey, cert); } catch (NfcInteractionNeeded e) { nfcSignOps.addHash(e.hashToSign, e.hashAlgo); @@ -1158,31 +1160,31 @@ public class PgpKeyOperation { progress(R.string.progress_modify_subkeychange, (i - 1) * (100 / saveParcel.mChangeSubKeys.size())); SaveKeyringParcel.SubkeyChange change = saveParcel.mChangeSubKeys.get(i); log.add(LogType.MSG_MF_SUBKEY_CHANGE, - indent, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); - PGPSecretKey sKey = sKR.getSecretKey(change.mKeyId); + PGPSecretKey sKey = sKR.getSecretKey(change.getSubKeyId()); if (sKey == null) { log.add(LogType.MSG_MF_ERROR_SUBKEY_MISSING, - indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (change.mDummyStrip || change.mSecurityTokenSerialNo != null) { + if (change.getDummyStrip() || change.getSecurityTokenSerialNo() != null) { // IT'S DANGEROUS~ // no really, it is. this operation irrevocably removes the private key data from the key - if (change.mDummyStrip) { + if (change.getDummyStrip()) { sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey()); } else { // the serial number must be 16 bytes in length - if (change.mSecurityTokenSerialNo.length != 16) { + if (change.getSecurityTokenSerialNo().length != 16) { log.add(LogType.MSG_MF_ERROR_DIVERT_SERIAL, - indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.mKeyId)); + indent + 1, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } log.add(LogType.MSG_MF_KEYTOCARD_FINISH, indent + 1, - KeyFormattingUtils.convertKeyIdToHex(change.mKeyId), - Hex.toHexString(change.mSecurityTokenSerialNo, 8, 6)); - sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey(), change.mSecurityTokenSerialNo); + KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId()), + Hex.toHexString(change.getSecurityTokenSerialNo(), 8, 6)); + sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey(), change.getSecurityTokenSerialNo()); } sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java index e1f903345..2a73cc93a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedUserAttribute.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.pgp; +import com.google.auto.value.AutoValue; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.Packet; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java index 2e77b97ae..744de6e3d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java @@ -24,6 +24,8 @@ import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.math.ec.ECCurve; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; + // 4.3.3.6 Algorithm Attributes public class ECKeyFormat extends KeyFormat { @@ -105,7 +107,7 @@ public class ECKeyFormat extends KeyFormat { throw new IllegalArgumentException("Unsupported curve " + mECCurveOID); } - keyring.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(algo, + keyring.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(algo, curve.getFieldSize(), scurve, keyFlags, 0L)); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java index 5087ec99b..f1d5d9e74 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java @@ -18,6 +18,8 @@ package org.sufficientlysecure.keychain.securitytoken; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; + // 4.3.3.6 Algorithm Attributes public class RSAKeyFormat extends KeyFormat { @@ -85,7 +87,7 @@ public class RSAKeyFormat extends KeyFormat { } public void addToSaveKeyringParcel(SaveKeyringParcel keyring, int keyFlags) { - keyring.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + keyring.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, mModulusLength, null, keyFlags, 0L)); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 9c0648bc6..6ff7f5c75 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -20,7 +20,9 @@ package org.sufficientlysecure.keychain.service; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.Nullable; +import com.google.auto.value.AutoValue; import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; import org.sufficientlysecure.keychain.util.Passphrase; @@ -137,8 +139,8 @@ public class SaveKeyringParcel implements Parcelable { } for (SubkeyChange change : mChangeSubKeys) { - if (change.mRecertify || change.mFlags != null || change.mExpiry != null - || change.mMoveKeyToSecurityToken) { + if (change.getRecertify() || change.getFlags() != null || change.getExpiry() != null + || change.getMoveKeyToSecurityToken()) { return false; } } @@ -148,109 +150,84 @@ public class SaveKeyringParcel implements Parcelable { // performance gain for using Parcelable here would probably be negligible, // use Serializable instead. - public static class SubkeyAdd implements Serializable { - public Algorithm mAlgorithm; - public Integer mKeySize; - public Curve mCurve; - public int mFlags; - public Long mExpiry; + @AutoValue + public abstract static class SubkeyAdd implements Serializable { + public abstract Algorithm getAlgorithm(); + @Nullable + public abstract Integer getKeySize(); + @Nullable + public abstract Curve getCurve(); + public abstract int getFlags(); + @Nullable + public abstract Long getExpiry(); - public SubkeyAdd(Algorithm algorithm, Integer keySize, Curve curve, int flags, Long expiry) { - mAlgorithm = algorithm; - mKeySize = keySize; - mCurve = curve; - mFlags = flags; - mExpiry = expiry; - } - - @Override - public String toString() { - String out = "mAlgorithm: " + mAlgorithm + ", "; - out += "mKeySize: " + mKeySize + ", "; - out += "mCurve: " + mCurve + ", "; - out += "mFlags: " + mFlags; - out += "mExpiry: " + mExpiry; - - return out; + public static SubkeyAdd createSubkeyAdd(Algorithm algorithm, Integer keySize, Curve curve, int flags, + Long expiry) { + return new AutoValue_SaveKeyringParcel_SubkeyAdd(algorithm, keySize, curve, flags, expiry); } } - public static class SubkeyChange implements Serializable { - public final long mKeyId; - public Integer mFlags; + @AutoValue + public abstract static class SubkeyChange implements Serializable { + public abstract long getSubKeyId(); + @Nullable + public abstract Integer getFlags(); // this is a long unix timestamp, in seconds (NOT MILLISECONDS!) - public Long mExpiry; + @Nullable + public abstract Long getExpiry(); // if this flag is true, the key will be recertified even if all above // values are no-ops - public boolean mRecertify; + public abstract boolean getRecertify(); // if this flag is true, the subkey should be changed to a stripped key - public boolean mDummyStrip; + public abstract boolean getDummyStrip(); // if this flag is true, the subkey should be moved to a security token - public boolean mMoveKeyToSecurityToken; + public abstract boolean getMoveKeyToSecurityToken(); // if this is non-null, the subkey will be changed to a divert-to-card // (security token) key for the given serial number - public byte[] mSecurityTokenSerialNo; + @Nullable + public abstract byte[] getSecurityTokenSerialNo(); - public SubkeyChange(long keyId) { - mKeyId = keyId; + public static SubkeyChange createRecertifyChange(long keyId, boolean recertify) { + return new AutoValue_SaveKeyringParcel_SubkeyChange(keyId, null, null, recertify, false, false, null); } - public SubkeyChange(long keyId, boolean recertify) { - mKeyId = keyId; - mRecertify = recertify; + public static SubkeyChange createFlagsOrExpiryChange(long keyId, Integer flags, Long expiry) { + return new AutoValue_SaveKeyringParcel_SubkeyChange(keyId, flags, expiry, false, false, false, null); } - public SubkeyChange(long keyId, Integer flags, Long expiry) { - mKeyId = keyId; - mFlags = flags; - mExpiry = expiry; + public static SubkeyChange createStripChange(long keyId) { + return new AutoValue_SaveKeyringParcel_SubkeyChange(keyId, null, null, false, true, false, null); } - public SubkeyChange(long keyId, boolean dummyStrip, boolean moveKeyToSecurityToken) { - this(keyId, null, null); - - // these flags are mutually exclusive! - if (dummyStrip && moveKeyToSecurityToken) { - throw new AssertionError( - "cannot set strip and moveKeyToSecurityToken" + - " flags at the same time - this is a bug!"); - } - mDummyStrip = dummyStrip; - mMoveKeyToSecurityToken = moveKeyToSecurityToken; + public static SubkeyChange createMoveToSecurityTokenChange(long keyId) { + return new AutoValue_SaveKeyringParcel_SubkeyChange(keyId, null, null, false, false, true, null); } - @Override - public String toString() { - String out = "mKeyId: " + mKeyId + ", "; - out += "mFlags: " + mFlags + ", "; - out += "mExpiry: " + mExpiry + ", "; - out += "mDummyStrip: " + mDummyStrip + ", "; - out += "mMoveKeyToSecurityToken: " + mMoveKeyToSecurityToken + ", "; - out += "mSecurityTokenSerialNo: [" + (mSecurityTokenSerialNo == null ? 0 : mSecurityTokenSerialNo.length) + " bytes]"; - - return out; + public static SubkeyChange createSecurityTokenSerialNo(long keyId, byte[] securityTokenSerialNo) { + return new AutoValue_SaveKeyringParcel_SubkeyChange(keyId, null, null, false, false, false, securityTokenSerialNo); } } public SubkeyChange getSubkeyChange(long keyId) { for (SubkeyChange subkeyChange : mChangeSubKeys) { - if (subkeyChange.mKeyId == keyId) { + if (subkeyChange.getSubKeyId() == keyId) { return subkeyChange; } } return null; } - public SubkeyChange getOrCreateSubkeyChange(long keyId) { - SubkeyChange foundSubkeyChange = getSubkeyChange(keyId); + public void addOrReplaceSubkeyChange(SubkeyChange change) { + SubkeyChange foundSubkeyChange = getSubkeyChange(change.getSubKeyId()); if (foundSubkeyChange != null) { - return foundSubkeyChange; - } else { - // else, create a new one - SubkeyChange newSubkeyChange = new SubkeyChange(keyId); - mChangeSubKeys.add(newSubkeyChange); - return newSubkeyChange; + mChangeSubKeys.remove(foundSubkeyChange); } + + mChangeSubKeys.add(change); + } + + public void removeSubkeyChange(SubkeyChange change) { + mChangeSubKeys.remove(change); } @SuppressWarnings("unchecked") // we verify the reads against writes in writeToParcel diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 35998e620..26db42c63 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -47,6 +47,7 @@ import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; import org.sufficientlysecure.keychain.service.UploadKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; @@ -444,7 +445,7 @@ public class CreateKeyFinalFragment extends Fragment { try { while (cursor != null && cursor.moveToNext()) { long subkeyId = cursor.getLong(0); - changeKeyringParcel.getOrCreateSubkeyChange(subkeyId).mMoveKeyToSecurityToken = true; + changeKeyringParcel.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(subkeyId)); } } finally { if (cursor != null) { 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 dfe1d98e5..65ef848d9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -431,15 +431,10 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment 0) { holder.vCertifyIcon.setVisibility(View.VISIBLE); } else { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java index ce1665382..bf1b2f378 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddSubkeyDialogFragment.java @@ -47,6 +47,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.util.Choice; import java.util.ArrayList; @@ -304,7 +305,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { expiry = selectedCal.getTime().getTime() / 1000; } - SaveKeyringParcel.SubkeyAdd newSubkey = new SaveKeyringParcel.SubkeyAdd( + SaveKeyringParcel.SubkeyAdd newSubkey = SubkeyAdd.createSubkeyAdd( algorithm, keySize, curve, flags, expiry ); mAlgorithmSelectedListener.onAlgorithmSelected(newSubkey); 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 15399c225..2deed1e2e 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java @@ -58,6 +58,7 @@ import org.sufficientlysecure.keychain.service.BackupKeyringParcel; import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Passphrase; @@ -95,11 +96,11 @@ public class BackupOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("snips"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1)); @@ -113,11 +114,11 @@ public class BackupOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("snails"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase("1234"))); 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 b681171ef..4a831cc91 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java @@ -48,6 +48,7 @@ import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyActio import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.TestingUtils; @@ -73,11 +74,11 @@ public class CertifyOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("derp"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1)); @@ -91,11 +92,11 @@ public class CertifyOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("ditz"); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java index 24f475d3b..75f70f710 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperationTest.java @@ -47,6 +47,7 @@ import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.PromoteKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.TestingUtils; @@ -69,11 +70,11 @@ public class PromoteKeyOperationTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("derp"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1)); 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 32b239595..722317458 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -623,7 +623,7 @@ public class PgpEncryptDecryptTest { SaveKeyringParcel parcel = new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); - parcel.mChangeSubKeys.add(new SubkeyChange(encKeyId1, true, false)); + parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(encKeyId1)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList(), new ArrayList(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); @@ -646,7 +646,7 @@ public class PgpEncryptDecryptTest { SaveKeyringParcel parcel = new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); - parcel.mChangeSubKeys.add(new SubkeyChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList(), new ArrayList(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); 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 793ba1939..843fe87ca 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -89,11 +89,11 @@ public class PgpKeyOperationTest { ShadowLog.stream = System.out; SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); @@ -143,7 +143,7 @@ public class PgpKeyOperationTest { { parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.RSA, new Random().nextInt(256)+255, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); @@ -154,7 +154,7 @@ public class PgpKeyOperationTest { { parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ELGAMAL, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); @@ -165,7 +165,7 @@ public class PgpKeyOperationTest { { parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, null)); parcel.mAddUserIds.add("lotus"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); @@ -176,7 +176,7 @@ public class PgpKeyOperationTest { { parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("shy"); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); @@ -187,7 +187,7 @@ public class PgpKeyOperationTest { { parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); @@ -211,7 +211,7 @@ public class PgpKeyOperationTest { // subkey binding certificates public void testMasterFlags() throws Exception { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("luna"); ring = assertCreateSuccess("creating ring with master key flags must succeed", parcel); @@ -343,7 +343,7 @@ public class PgpKeyOperationTest { long expiry = new Date().getTime() / 1000 + 159; int flags = KeyFlags.SIGN_DATA; - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, flags, expiry)); UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); @@ -382,7 +382,7 @@ public class PgpKeyOperationTest { { // bad keysize should fail parcel.reset(); - parcel.mAddSubKeys.add(new SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.RSA, new Random().nextInt(512), null, KeyFlags.SIGN_DATA, 0L)); assertModifyFailure("creating a subkey with keysize < 2048 should fail", ring, parcel, LogType.MSG_CR_ERROR_KEYSIZE_2048); @@ -390,7 +390,7 @@ public class PgpKeyOperationTest { { // null expiry should fail parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, null)); assertModifyFailure("creating master key with null expiry should fail", ring, parcel, LogType.MSG_MF_ERROR_NULL_EXPIRY); @@ -398,7 +398,7 @@ public class PgpKeyOperationTest { { // a past expiry should fail parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, new Date().getTime()/1000-10)); assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel, LogType.MSG_MF_ERROR_PAST_EXPIRY); @@ -414,7 +414,7 @@ public class PgpKeyOperationTest { UncachedKeyRing modified = ring; { - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("one extra packet in original", 1, onlyA.size()); @@ -441,7 +441,7 @@ public class PgpKeyOperationTest { { // change expiry expiry += 60*60*24; - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertNotNull("modified key must have an expiry date", @@ -455,7 +455,7 @@ public class PgpKeyOperationTest { { int flags = KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS; parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, flags, null)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, flags, null)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("old packet must be signature", @@ -478,7 +478,7 @@ public class PgpKeyOperationTest { { // expiry of 0 should be "no expiry" parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, 0L)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, 0L)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("old packet must be signature", @@ -496,7 +496,7 @@ public class PgpKeyOperationTest { { // a past expiry should fail parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, new Date().getTime()/1000-10)); assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel, LogType.MSG_MF_ERROR_PAST_EXPIRY); @@ -504,7 +504,7 @@ public class PgpKeyOperationTest { { // modifying nonexistent subkey should fail parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(123, null, null)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(123, null, null)); assertModifyFailure("modifying non-existent subkey should fail", ring, parcel, LogType.MSG_MF_ERROR_SUBKEY_MISSING); @@ -528,7 +528,7 @@ public class PgpKeyOperationTest { { parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); // this implies that only the two non-revoked signatures were changed! @@ -555,7 +555,7 @@ public class PgpKeyOperationTest { { // change expiry expiry += 60*60*24; - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertNotNull("modified key must have an expiry date", @@ -575,7 +575,7 @@ public class PgpKeyOperationTest { { int flags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA; parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, flags, null)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, flags, null)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("modified key must have expected flags", @@ -595,7 +595,7 @@ public class PgpKeyOperationTest { modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, 0L)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, 0L)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); // for this check, it is relevant that we DON'T use the unsafe one! @@ -610,7 +610,7 @@ public class PgpKeyOperationTest { parcel.reset(); parcel.mRevokeUserIds.add("twi"); parcel.mRevokeUserIds.add("pink"); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, KeyFlags.CERTIFY_OTHER, null)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, KeyFlags.CERTIFY_OTHER, null)); assertModifyFailure("master key modification with all user ids revoked should fail", ring, parcel, LogType.MSG_MF_ERROR_MASTER_NONE); @@ -618,7 +618,7 @@ public class PgpKeyOperationTest { { // any flag not including CERTIFY_OTHER should fail parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, KeyFlags.SIGN_DATA, null)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, KeyFlags.SIGN_DATA, null)); assertModifyFailure("setting master key flags without certify should fail", ring, parcel, LogType.MSG_MF_ERROR_NO_CERTIFY); @@ -626,7 +626,7 @@ public class PgpKeyOperationTest { { // a past expiry should fail parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime()/1000-10)); + parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, new Date().getTime()/1000-10)); assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel, LogType.MSG_MF_ERROR_PAST_EXPIRY); @@ -707,7 +707,7 @@ public class PgpKeyOperationTest { parcel.reset(); // re-certify the revoked subkey - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true)); + parcel.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); @@ -749,7 +749,7 @@ public class PgpKeyOperationTest { public void testSubkeyStrip() throws Exception { long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false)); + parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId)); applyModificationWithChecks(parcel, ring, onlyA, onlyB); Assert.assertEquals("one extra packet in original", 1, onlyA.size()); @@ -775,7 +775,7 @@ public class PgpKeyOperationTest { public void testMasterStrip() throws Exception { long keyId = ring.getMasterKeyId(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false)); + parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId)); applyModificationWithChecks(parcel, ring, onlyA, onlyB); Assert.assertEquals("one extra packet in original", 1, onlyA.size()); @@ -804,7 +804,7 @@ 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)); + parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId)); modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, CryptoInputParcel.createCryptoInputParcel()); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); @@ -817,7 +817,7 @@ public class PgpKeyOperationTest { { // trying to edit a subkey with signing capability should fail parcel.reset(); - parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true)); + parcel.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true)); assertModifyFailure("subkey modification for signing-enabled but stripped subkey should fail", modified, parcel, LogType.MSG_MF_ERROR_SUB_STRIPPED); @@ -830,11 +830,11 @@ public class PgpKeyOperationTest { // Special keyring for security token tests with 2048 bit RSA as a subkey SaveKeyringParcel parcelKey = new SaveKeyringParcel(); - parcelKey.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.DSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); - parcelKey.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); - parcelKey.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.RSA, 3072, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcelKey.mAddUserIds.add("yubikey"); @@ -857,7 +857,7 @@ public class PgpKeyOperationTest { { // moveKeyToSecurityToken should fail with BAD_NFC_ALGO when presented with the DSA-1024 key long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 0); parcelSecurityToken.reset(); - parcelSecurityToken.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); + parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(keyId)); assertModifyFailure("moveKeyToSecurityToken operation should fail on invalid key algorithm", ringSecurityToken, parcelSecurityToken, cryptoInput, LogType.MSG_MF_ERROR_BAD_SECURITY_TOKEN_ALGO); @@ -868,7 +868,7 @@ public class PgpKeyOperationTest { { // moveKeyToSecurityToken should return a pending SECURITY_TOKEN_MOVE_KEY_TO_CARD result when presented with the RSA-2048 // key, and then make key divert-to-card when it gets a serial in the cryptoInputParcel. parcelSecurityToken.reset(); - parcelSecurityToken.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); + parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(keyId)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringSecurityToken.getEncoded(), 0); @@ -902,7 +902,7 @@ public class PgpKeyOperationTest { { // editing a signing subkey requires a primary key binding sig -> pendinginput parcelSecurityToken.reset(); - parcelSecurityToken.mChangeSubKeys.add(new SubkeyChange(keyId, true)); + parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0); 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 de56cb9c8..c9de64f30 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -59,6 +59,7 @@ import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket; @@ -96,11 +97,11 @@ public class UncachedKeyringCanonicalizeTest { ShadowLog.stream = System.out; SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); @@ -352,7 +353,7 @@ public class UncachedKeyringCanonicalizeTest { @Test public void testForeignSignature() throws Exception { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("trix"); PgpKeyOperation op = new PgpKeyOperation(null); 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 ed78dc8a3..4b9ed015d 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -48,6 +48,7 @@ import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyActio import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.support.KeyringTestingHelper; import org.sufficientlysecure.keychain.support.KeyringTestingHelper.RawPacket; @@ -97,9 +98,9 @@ public class UncachedKeyringMergeTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); parcel.mAddUserIds.add("twi"); @@ -123,7 +124,7 @@ public class UncachedKeyringMergeTest { { SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); parcel.mAddUserIds.add("shy"); @@ -232,7 +233,7 @@ public class UncachedKeyringMergeTest { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringA.getEncoded(), 0); parcel.reset(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); modifiedA = op.modifySecretKeyRing(secretRing, CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java index cd550998a..88b60e5e4 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java @@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.util.Passphrase; import java.io.ByteArrayInputStream; @@ -54,11 +55,11 @@ public class UncachedKeyringTest { ShadowLog.stream = System.out; SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( + parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); parcel.mAddUserIds.add("twi"); From d58f1bd2259aaf540e2b6173e3bb32e28794601d Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 23 May 2017 02:23:03 +0200 Subject: [PATCH 15/23] use autovalue for SaveKeyringParcel --- .../keychain/Constants.java | 8 +- .../keychain/operations/EditKeyOperation.java | 10 +- .../keychain/operations/RevokeOperation.java | 9 +- .../keychain/pgp/PgpKeyOperation.java | 261 ++++++---- .../keychain/securitytoken/ECKeyFormat.java | 5 +- .../keychain/securitytoken/KeyFormat.java | 2 +- .../keychain/securitytoken/RSAKeyFormat.java | 4 +- .../keychain/service/SaveKeyringParcel.java | 347 ++++++------- .../keychain/ui/CreateKeyFinalFragment.java | 42 +- .../keychain/ui/EditIdentitiesFragment.java | 30 +- .../keychain/ui/EditKeyFragment.java | 76 +-- .../ui/ViewKeyAdvSubkeysFragment.java | 34 +- .../ui/ViewKeyAdvUserIdsFragment.java | 34 +- .../keychain/ui/adapter/SubkeysAdapter.java | 32 +- .../keychain/ui/adapter/UserIdsAdapter.java | 28 +- .../keychain/ui/keyview/ViewKeyFragment.java | 2 +- .../linked/LinkedIdCreateFinalFragment.java | 14 +- .../linked/LinkedIdCreateGithubFragment.java | 11 +- .../operations/BackupOperationTest.java | 28 +- .../operations/CertifyOperationTest.java | 31 +- .../operations/PromoteKeyOperationTest.java | 14 +- .../keychain/pgp/PgpEncryptDecryptTest.java | 23 +- .../keychain/pgp/PgpKeyOperationTest.java | 469 +++++++++--------- .../pgp/UncachedKeyringCanonicalizeTest.java | 26 +- .../pgp/UncachedKeyringMergeTest.java | 70 +-- .../keychain/pgp/UncachedKeyringTest.java | 18 +- 26 files changed, 816 insertions(+), 812 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 5e4fa5f80..ffdbe950e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -179,12 +179,12 @@ public final class Constants { /** * Default key configuration: 3072 bit RSA (certify, sign, encrypt) */ - public static void addDefaultSubkeys(SaveKeyringParcel saveKeyringParcel) { - saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + public static void addDefaultSubkeys(SaveKeyringParcel.Builder builder) { + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, 3072, null, KeyFlags.CERTIFY_OTHER, 0L)); - saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, 3072, null, KeyFlags.SIGN_DATA, 0L)); - saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, 3072, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java index 57161b61b..f7d2d86c6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java @@ -88,13 +88,13 @@ public class EditKeyOperation extends BaseReadWriteOperation new PgpKeyOperation(new ProgressScaler(mProgressable, 10, 60, 100), mCancelled); // If a key id is specified, fetch and edit - if (saveParcel.mMasterKeyId != null) { + if (saveParcel.getMasterKeyId() != null) { try { log.add(LogType.MSG_ED_FETCHING, 1, - KeyFormattingUtils.convertKeyIdToHex(saveParcel.mMasterKeyId)); + KeyFormattingUtils.convertKeyIdToHex(saveParcel.getMasterKeyId())); CanonicalizedSecretKeyRing secRing = - mKeyRepository.getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId); + mKeyRepository.getCanonicalizedSecretKeyRing(saveParcel.getMasterKeyId()); modifyResult = keyOperations.modifySecretKeyRing(secRing, cryptoInput, saveParcel); if (modifyResult.isPending()) { @@ -133,7 +133,7 @@ public class EditKeyOperation extends BaseReadWriteOperation // It's a success, so this must be non-null now UncachedKeyRing ring = modifyResult.getRing(); - if (saveParcel.isUpload()) { + if (saveParcel.isShouldUpload()) { byte[] keyringBytes; try { UncachedKeyRing publicKeyRing = ring.extractPublicKeyRing(); @@ -154,7 +154,7 @@ public class EditKeyOperation extends BaseReadWriteOperation if (uploadResult.isPending()) { return new EditKeyResult(log, uploadResult); - } else if (!uploadResult.success() && saveParcel.isUploadAtomic()) { + } else if (!uploadResult.success() && saveParcel.isShouldUploadAtomic()) { // if atomic, update fail implies edit operation should also fail and not save return new EditKeyResult(log, RequiredInputParcel.createRetryUploadOperation(), cryptoInput); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java index 197842ed9..d0808f4db 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/RevokeOperation.java @@ -71,17 +71,18 @@ public class RevokeOperation extends BaseReadWriteOperation return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId); } - SaveKeyringParcel saveKeyringParcel = - new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint()); + SaveKeyringParcel.Builder saveKeyringParcel = + SaveKeyringParcel.buildChangeKeyringParcel(masterKeyId, keyRing.getFingerprint()); // all revoke operations are made atomic as of now saveKeyringParcel.setUpdateOptions(revokeKeyringParcel.isShouldUpload(), true, revokeKeyringParcel.getKeyserver()); - saveKeyringParcel.mRevokeSubKeys.add(masterKeyId); + saveKeyringParcel.addRevokeSubkey(masterKeyId); EditKeyResult revokeAndUploadResult = new EditKeyOperation(mContext, - mKeyWritableRepository, mProgressable, mCancelled).execute(saveKeyringParcel, cryptoInputParcel); + mKeyWritableRepository, mProgressable, mCancelled).execute( + saveKeyringParcel.build(), cryptoInputParcel); if (revokeAndUploadResult.isPending()) { return revokeAndUploadResult; 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 91dc06921..011657a95 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -29,10 +29,10 @@ import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.SignatureException; import java.security.spec.ECGenParameterSpec; -import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Iterator; +import java.util.List; import java.util.Stack; import java.util.concurrent.atomic.AtomicBoolean; @@ -80,6 +80,7 @@ import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Builder; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; @@ -287,23 +288,23 @@ public class PgpKeyOperation { progress(R.string.progress_building_key, 0); indent += 1; - if (saveParcel.mAddSubKeys.isEmpty()) { + if (saveParcel.getAddSubKeys().isEmpty()) { log.add(LogType.MSG_CR_ERROR_NO_MASTER, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (saveParcel.mAddUserIds.isEmpty()) { + if (saveParcel.getAddUserIds().isEmpty()) { log.add(LogType.MSG_CR_ERROR_NO_USER_ID, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - SubkeyAdd add = saveParcel.mAddSubKeys.remove(0); - if ((add.getFlags() & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) { + SubkeyAdd certificationKey = saveParcel.getAddSubKeys().get(0); + if ((certificationKey.getFlags() & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) { log.add(LogType.MSG_CR_ERROR_NO_CERTIFY, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (add.getExpiry() == null) { + if (certificationKey.getExpiry() == null) { log.add(LogType.MSG_CR_ERROR_NULL_EXPIRY, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } @@ -311,7 +312,7 @@ public class PgpKeyOperation { Date creationTime = new Date(); subProgressPush(10, 30); - PGPKeyPair keyPair = createKey(add, creationTime, log, indent); + PGPKeyPair keyPair = createKey(certificationKey, creationTime, log, indent); subProgressPop(); // return null if this failed (an error will already have been logged by createKey) @@ -337,9 +338,14 @@ public class PgpKeyOperation { PGPSecretKeyRing sKR = new PGPSecretKeyRing( masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator()); + // Remove certification key from remaining SaveKeyringParcel + Builder builder = SaveKeyringParcel.buildUpon(saveParcel); + builder.getMutableAddSubKeys().remove(certificationKey); + saveParcel = builder.build(); + subProgressPush(50, 100); CryptoInputParcel cryptoInput = CryptoInputParcel.createCryptoInputParcel(creationTime, new Passphrase("")); - return internal(sKR, masterSecretKey, add.getFlags(), add.getExpiry(), cryptoInput, saveParcel, log, indent); + return internal(sKR, masterSecretKey, certificationKey.getFlags(), certificationKey.getExpiry(), cryptoInput, saveParcel, log, indent); } catch (PGPException e) { log.add(LogType.MSG_CR_ERROR_INTERNAL_PGP, indent); @@ -394,7 +400,7 @@ public class PgpKeyOperation { progress(R.string.progress_building_key, 0); // Make sure this is called with a proper SaveKeyringParcel - if (saveParcel.mMasterKeyId == null || saveParcel.mMasterKeyId != wsKR.getMasterKeyId()) { + if (saveParcel.getMasterKeyId() == null || saveParcel.getMasterKeyId() != wsKR.getMasterKeyId()) { log.add(LogType.MSG_MF_ERROR_KEYID, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } @@ -404,75 +410,29 @@ public class PgpKeyOperation { PGPSecretKey masterSecretKey = sKR.getSecretKey(); // Make sure the fingerprint matches - if (saveParcel.mFingerprint == null || !Arrays.equals(saveParcel.mFingerprint, + if (saveParcel.getFingerprint() == null || !Arrays.equals(saveParcel.getFingerprint(), masterSecretKey.getPublicKey().getFingerprint())) { log.add(LogType.MSG_MF_ERROR_FINGERPRINT, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (saveParcel.isEmpty()) { + if (isParcelEmpty(saveParcel)) { log.add(LogType.MSG_MF_ERROR_NOOP, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - // Ensure we don't have multiple keys for the same slot. - boolean hasSign = false; - boolean hasEncrypt = false; - boolean hasAuth = false; - for (SaveKeyringParcel.SubkeyChange change : new ArrayList<>(saveParcel.mChangeSubKeys)) { - if (change.getMoveKeyToSecurityToken()) { - // If this is a moveKeyToSecurityToken operation, see if it was completed: look for a hash - // matching the given subkey ID in cryptoData. - byte[] subKeyId = new byte[8]; - ByteBuffer buf = ByteBuffer.wrap(subKeyId); - buf.putLong(change.getSubKeyId()).rewind(); + saveParcel = parseSecurityTokenSerialNumberIntoSubkeyChanges(cryptoInput, saveParcel); - byte[] serialNumber = cryptoInput.getCryptoData().get(buf); - if (serialNumber != null) { - saveParcel.addOrReplaceSubkeyChange( - SubkeyChange.createSecurityTokenSerialNo(change.getSubKeyId(), serialNumber)); - } - } - - if (change.getMoveKeyToSecurityToken()) { - // Pending moveKeyToSecurityToken operation. Need to make sure that we don't have multiple - // subkeys pending for the same slot. - CanonicalizedSecretKey wsK = wsKR.getSecretKey(change.getSubKeyId()); - - if ((wsK.canSign() || wsK.canCertify())) { - if (hasSign) { - log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1); - return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); - } else { - hasSign = true; - } - } else if ((wsK.canEncrypt())) { - if (hasEncrypt) { - log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1); - return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); - } else { - hasEncrypt = true; - } - } else if ((wsK.canAuthenticate())) { - if (hasAuth) { - log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1); - return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); - } else { - hasAuth = true; - } - } else { - log.add(LogType.MSG_MF_ERROR_INVALID_FLAGS_FOR_KEYTOCARD, indent + 1); - return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); - } - } + if (!checkCapabilitiesAreUnique(wsKR, saveParcel, log, indent)) { + return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (isDummy(masterSecretKey) && ! saveParcel.isRestrictedOnly()) { + if (isDummy(masterSecretKey) && ! isParcelRestrictedOnly(saveParcel)) { log.add(LogType.MSG_EK_ERROR_DUMMY, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } - if (isDummy(masterSecretKey) || saveParcel.isRestrictedOnly()) { + if (isDummy(masterSecretKey) || isParcelRestrictedOnly(saveParcel)) { log.add(LogType.MSG_MF_RESTRICTED_MODE, indent); return internalRestricted(sKR, saveParcel, log, indent + 1); } @@ -496,6 +456,70 @@ public class PgpKeyOperation { } + private SaveKeyringParcel parseSecurityTokenSerialNumberIntoSubkeyChanges(CryptoInputParcel cryptoInput, + SaveKeyringParcel saveParcel) { + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildUpon(saveParcel); + for (SubkeyChange change : saveParcel.getChangeSubKeys()) { + if (change.getMoveKeyToSecurityToken()) { + // If this is a moveKeyToSecurityToken operation, see if it was completed: look for a hash + // matching the given subkey ID in cryptoData. + byte[] subKeyId = new byte[8]; + ByteBuffer buf = ByteBuffer.wrap(subKeyId); + buf.putLong(change.getSubKeyId()).rewind(); + + byte[] serialNumber = cryptoInput.getCryptoData().get(buf); + if (serialNumber != null) { + builder.addOrReplaceSubkeyChange( + SubkeyChange.createSecurityTokenSerialNo(change.getSubKeyId(), serialNumber)); + } + } + } + saveParcel = builder.build(); + return saveParcel; + } + + private boolean checkCapabilitiesAreUnique(CanonicalizedSecretKeyRing wsKR, SaveKeyringParcel saveParcel, + OperationLog log, int indent) { + boolean hasSign = false; + boolean hasEncrypt = false; + boolean hasAuth = false; + + for (SubkeyChange change : saveParcel.getChangeSubKeys()) { + if (change.getMoveKeyToSecurityToken()) { + // Pending moveKeyToSecurityToken operation. Need to make sure that we don't have multiple + // subkeys pending for the same slot. + CanonicalizedSecretKey wsK = wsKR.getSecretKey(change.getSubKeyId()); + + if ((wsK.canSign() || wsK.canCertify())) { + if (hasSign) { + log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1); + return false; + } else { + hasSign = true; + } + } else if ((wsK.canEncrypt())) { + if (hasEncrypt) { + log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1); + return false; + } else { + hasEncrypt = true; + } + } else if ((wsK.canAuthenticate())) { + if (hasAuth) { + log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1); + return false; + } else { + hasAuth = true; + } + } else { + log.add(LogType.MSG_MF_ERROR_INVALID_FLAGS_FOR_KEYTOCARD, indent + 1); + return false; + } + } + } + return true; + } + private PgpEditKeyResult internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey, int masterKeyFlags, long masterKeyExpiry, CryptoInputParcel cryptoInput, @@ -549,10 +573,11 @@ public class PgpKeyOperation { // 2a. Add certificates for new user ids subProgressPush(15, 23); - for (int i = 0; i < saveParcel.mAddUserIds.size(); i++) { + String changePrimaryUserId = saveParcel.getChangePrimaryUserId(); + for (int i = 0; i < saveParcel.getAddUserIds().size(); i++) { - progress(R.string.progress_modify_adduid, (i - 1) * (100 / saveParcel.mAddUserIds.size())); - String userId = saveParcel.mAddUserIds.get(i); + progress(R.string.progress_modify_adduid, (i - 1) * (100 / saveParcel.getAddUserIds().size())); + String userId = saveParcel.getAddUserIds().get(i); log.add(LogType.MSG_MF_UID_ADD, indent, userId); if ("".equals(userId)) { @@ -583,8 +608,8 @@ public class PgpKeyOperation { } // if it's supposed to be primary, we can do that here as well - boolean isPrimary = saveParcel.mChangePrimaryUserId != null - && userId.equals(saveParcel.mChangePrimaryUserId); + boolean isPrimary = changePrimaryUserId != null + && userId.equals(changePrimaryUserId); // generate and add new certificate try { PGPSignature cert = generateUserIdSignature( @@ -601,10 +626,10 @@ public class PgpKeyOperation { // 2b. Add certificates for new user ids subProgressPush(23, 32); - for (int i = 0; i < saveParcel.mAddUserAttribute.size(); i++) { - - progress(R.string.progress_modify_adduat, (i - 1) * (100 / saveParcel.mAddUserAttribute.size())); - WrappedUserAttribute attribute = saveParcel.mAddUserAttribute.get(i); + List addUserAttributes = saveParcel.getAddUserAttribute(); + for (int i = 0; i < addUserAttributes.size(); i++) { + progress(R.string.progress_modify_adduat, (i - 1) * (100 / addUserAttributes.size())); + WrappedUserAttribute attribute = addUserAttributes.get(i); switch (attribute.getType()) { // the 'none' type must not succeed @@ -637,10 +662,10 @@ public class PgpKeyOperation { // 2c. Add revocations for revoked user ids subProgressPush(32, 40); - for (int i = 0; i < saveParcel.mRevokeUserIds.size(); i++) { - - progress(R.string.progress_modify_revokeuid, (i - 1) * (100 / saveParcel.mRevokeUserIds.size())); - String userId = saveParcel.mRevokeUserIds.get(i); + List revokeUserIds = saveParcel.getRevokeUserIds(); + for (int i = 0, j = revokeUserIds.size(); i < j; i++) { + progress(R.string.progress_modify_revokeuid, (i - 1) * (100 / revokeUserIds.size())); + String userId = revokeUserIds.get(i); log.add(LogType.MSG_MF_UID_REVOKE, indent, userId); // Make sure the user id exists (yes these are 10 LoC in Java!) @@ -672,12 +697,12 @@ public class PgpKeyOperation { subProgressPop(); // 3. If primary user id changed, generate new certificates for both old and new - if (saveParcel.mChangePrimaryUserId != null) { + if (changePrimaryUserId != null) { progress(R.string.progress_modify_primaryuid, 40); // keep track if we actually changed one boolean ok = false; - log.add(LogType.MSG_MF_UID_PRIMARY, indent, saveParcel.mChangePrimaryUserId); + log.add(LogType.MSG_MF_UID_PRIMARY, indent, changePrimaryUserId); indent += 1; // we work on the modifiedPublicKey here, to respect new or newly revoked uids @@ -718,7 +743,7 @@ public class PgpKeyOperation { // we definitely should not update certifications of revoked keys, so just leave it. if (isRevoked) { // revoked user ids cannot be primary! - if (userId.equals(saveParcel.mChangePrimaryUserId)) { + if (userId.equals(changePrimaryUserId)) { log.add(LogType.MSG_MF_ERROR_REVOKED_PRIMARY, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } @@ -729,7 +754,7 @@ public class PgpKeyOperation { if (currentCert.getHashedSubPackets() != null && currentCert.getHashedSubPackets().isPrimaryUserID()) { // if it's the one we want, just leave it as is - if (userId.equals(saveParcel.mChangePrimaryUserId)) { + if (userId.equals(changePrimaryUserId)) { ok = true; continue; } @@ -755,7 +780,7 @@ public class PgpKeyOperation { // if we are here, this is not currently a primary user id // if it should be - if (userId.equals(saveParcel.mChangePrimaryUserId)) { + if (userId.equals(changePrimaryUserId)) { // add shiny new primary user id certificate log.add(LogType.MSG_MF_PRIMARY_NEW, indent); modifiedPublicKey = PGPPublicKey.removeCertification( @@ -803,10 +828,11 @@ public class PgpKeyOperation { // 4a. For each subkey change, generate new subkey binding certificate subProgressPush(50, 60); - for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) { + List changeSubKeys = saveParcel.getChangeSubKeys(); + for (int i = 0, j = changeSubKeys.size(); i < j; i++) { - progress(R.string.progress_modify_subkeychange, (i-1) * (100 / saveParcel.mChangeSubKeys.size())); - SaveKeyringParcel.SubkeyChange change = saveParcel.mChangeSubKeys.get(i); + progress(R.string.progress_modify_subkeychange, (i-1) * (100 / changeSubKeys.size())); + SaveKeyringParcel.SubkeyChange change = changeSubKeys.get(i); log.add(LogType.MSG_MF_SUBKEY_CHANGE, indent, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); @@ -944,10 +970,10 @@ public class PgpKeyOperation { // 4b. For each subkey revocation, generate new subkey revocation certificate subProgressPush(60, 65); - for (int i = 0; i < saveParcel.mRevokeSubKeys.size(); i++) { - - progress(R.string.progress_modify_subkeyrevoke, (i-1) * (100 / saveParcel.mRevokeSubKeys.size())); - long revocation = saveParcel.mRevokeSubKeys.get(i); + List revokeSubKeys = saveParcel.getRevokeSubKeys(); + for (int i = 0, j = revokeSubKeys.size(); i < j; i++) { + progress(R.string.progress_modify_subkeyrevoke, (i-1) * (100 / revokeSubKeys.size())); + long revocation = revokeSubKeys.get(i); log.add(LogType.MSG_MF_SUBKEY_REVOKE, indent, KeyFormattingUtils.convertKeyIdToHex(revocation)); @@ -976,16 +1002,16 @@ public class PgpKeyOperation { // 5. Generate and add new subkeys subProgressPush(70, 90); - for (int i = 0; i < saveParcel.mAddSubKeys.size(); i++) { - + List addSubKeys = saveParcel.getAddSubKeys(); + for (int i = 0, j = addSubKeys.size(); i < j; i++) { // Check if we were cancelled - again. This operation is expensive so we do it each loop. if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null); } - progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size())); - SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i); + progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / addSubKeys.size())); + SaveKeyringParcel.SubkeyAdd add = addSubKeys.get(i); log.add(LogType.MSG_MF_SUBKEY_NEW, indent, KeyFormattingUtils.getAlgorithmInfo(add.getAlgorithm(), add.getKeySize(), add.getCurve()) ); @@ -1006,8 +1032,8 @@ public class PgpKeyOperation { // generate a new secret key (privkey only for now) subProgressPush( - (i-1) * (100 / saveParcel.mAddSubKeys.size()), - i * (100 / saveParcel.mAddSubKeys.size()) + (i-1) * (100 / addSubKeys.size()), + i * (100 / addSubKeys.size()) ); PGPKeyPair keyPair = createKey(add, cryptoInput.getSignatureTime(), log, indent); subProgressPop(); @@ -1060,13 +1086,13 @@ public class PgpKeyOperation { } // 6. If requested, change passphrase - if (saveParcel.getChangeUnlockParcel() != null) { + if (saveParcel.getNewUnlock() != null) { progress(R.string.progress_modify_passphrase, 90); log.add(LogType.MSG_MF_PASSPHRASE, indent); indent += 1; sKR = applyNewPassphrase(sKR, masterPublicKey, cryptoInput.getPassphrase(), - saveParcel.getChangeUnlockParcel().getNewPassphrase(), log, indent); + saveParcel.getNewUnlock().getNewPassphrase(), log, indent); if (sKR == null) { // The error has been logged above, just return a bad state return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); @@ -1076,21 +1102,21 @@ public class PgpKeyOperation { } // 7. if requested, change PIN and/or Admin PIN on security token - if (saveParcel.mSecurityTokenPin != null) { + if (saveParcel.getSecurityTokenPin() != null) { progress(R.string.progress_modify_pin, 90); log.add(LogType.MSG_MF_PIN, indent); indent += 1; - nfcKeyToCardOps.setPin(saveParcel.mSecurityTokenPin); + nfcKeyToCardOps.setPin(saveParcel.getSecurityTokenPin()); indent -= 1; } - if (saveParcel.mSecurityTokenAdminPin != null) { + if (saveParcel.getSecurityTokenAdminPin() != null) { progress(R.string.progress_modify_admin_pin, 90); log.add(LogType.MSG_MF_ADMIN_PIN, indent); indent += 1; - nfcKeyToCardOps.setAdminPin(saveParcel.mSecurityTokenAdminPin); + nfcKeyToCardOps.setAdminPin(saveParcel.getSecurityTokenAdminPin()); indent -= 1; } @@ -1141,7 +1167,7 @@ public class PgpKeyOperation { progress(R.string.progress_modify, 0); // Make sure the saveParcel includes only operations available without passphrase! - if (!saveParcel.isRestrictedOnly()) { + if (!isParcelRestrictedOnly(saveParcel)) { log.add(LogType.MSG_MF_ERROR_RESTRICTED, indent); return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); } @@ -1155,10 +1181,10 @@ public class PgpKeyOperation { // The only operation we can do here: // 4a. Strip secret keys, or change their protection mode (stripped/divert-to-card) subProgressPush(50, 60); - for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) { - - progress(R.string.progress_modify_subkeychange, (i - 1) * (100 / saveParcel.mChangeSubKeys.size())); - SaveKeyringParcel.SubkeyChange change = saveParcel.mChangeSubKeys.get(i); + List changeSubKeys = saveParcel.getChangeSubKeys(); + for (int i = 0, j = changeSubKeys.size(); i < j; i++) { + progress(R.string.progress_modify_subkeychange, (i - 1) * (100 / changeSubKeys.size())); + SaveKeyringParcel.SubkeyChange change = changeSubKeys.get(i); log.add(LogType.MSG_MF_SUBKEY_CHANGE, indent, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId())); @@ -1700,4 +1726,31 @@ public class PgpKeyOperation { return true; } + + /** Returns true iff this parcel does not contain any operations which require a passphrase. */ + private static boolean isParcelRestrictedOnly(SaveKeyringParcel saveKeyringParcel) { + if (saveKeyringParcel.getNewUnlock() != null + || !saveKeyringParcel.getAddUserIds().isEmpty() + || !saveKeyringParcel.getAddUserAttribute().isEmpty() + || !saveKeyringParcel.getAddSubKeys().isEmpty() + || saveKeyringParcel.getChangePrimaryUserId() != null + || !saveKeyringParcel.getRevokeUserIds().isEmpty() + || !saveKeyringParcel.getRevokeSubKeys().isEmpty()) { + return false; + } + + for (SubkeyChange change : saveKeyringParcel.getChangeSubKeys()) { + if (change.getRecertify() || change.getFlags() != null || change.getExpiry() != null + || change.getMoveKeyToSecurityToken()) { + return false; + } + } + + return true; + } + + private static boolean isParcelEmpty(SaveKeyringParcel saveKeyringParcel) { + return isParcelRestrictedOnly(saveKeyringParcel) && saveKeyringParcel.getChangeSubKeys().isEmpty(); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java index 744de6e3d..278b510b3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/ECKeyFormat.java @@ -86,7 +86,7 @@ public class ECKeyFormat extends KeyFormat { } } - public void addToSaveKeyringParcel(SaveKeyringParcel keyring, int keyFlags) { + public void addToSaveKeyringParcel(SaveKeyringParcel.Builder builder, int keyFlags) { final X9ECParameters params = NISTNamedCurves.getByOID(mECCurveOID); final ECCurve curve = params.getCurve(); @@ -107,7 +107,6 @@ public class ECKeyFormat extends KeyFormat { throw new IllegalArgumentException("Unsupported curve " + mECCurveOID); } - keyring.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(algo, - curve.getFieldSize(), scurve, keyFlags, 0L)); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(algo, curve.getFieldSize(), scurve, keyFlags, 0L)); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java index 6fdd91daa..9d612517b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/KeyFormat.java @@ -94,6 +94,6 @@ public abstract class KeyFormat { throw new IllegalArgumentException("Unsupported Algorithm id " + t); } - public abstract void addToSaveKeyringParcel(SaveKeyringParcel keyring, int keyFlags); + public abstract void addToSaveKeyringParcel(SaveKeyringParcel.Builder builder, int keyFlags); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java index f1d5d9e74..cbba61781 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/RSAKeyFormat.java @@ -86,8 +86,8 @@ public class RSAKeyFormat extends KeyFormat { } } - public void addToSaveKeyringParcel(SaveKeyringParcel keyring, int keyFlags) { - keyring.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, + public void addToSaveKeyringParcel(SaveKeyringParcel.Builder builder, int keyFlags) { + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA, mModulusLength, null, keyFlags, 0L)); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 6ff7f5c75..2f667f7a3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -18,18 +18,20 @@ package org.sufficientlysecure.keychain.service; -import android.os.Parcel; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import android.os.Parcelable; import android.support.annotation.Nullable; import com.google.auto.value.AutoValue; -import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; +import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.util.Passphrase; -import java.io.Serializable; -import java.util.ArrayList; - /** * This class is a a transferable representation for a collection of changes * to be done on a keyring. @@ -45,107 +47,183 @@ import java.util.ArrayList; * error in any included operation (for example revocation of a non-existent * subkey) will cause the operation as a whole to fail. */ -public class SaveKeyringParcel implements Parcelable { +@AutoValue +public abstract class SaveKeyringParcel implements Parcelable { // the master key id to be edited. if this is null, a new one will be created - public Long mMasterKeyId; + @Nullable + public abstract Long getMasterKeyId(); // the key fingerprint, for safety. MUST be null for a new key. - public byte[] mFingerprint; + @Nullable + public abstract byte[] getFingerprint(); - public ArrayList mAddUserIds; - public ArrayList mAddUserAttribute; - public ArrayList mAddSubKeys; + public abstract List getAddUserIds(); + public abstract List getAddUserAttribute(); + public abstract List getAddSubKeys(); - public ArrayList mChangeSubKeys; - public String mChangePrimaryUserId; + public abstract List getChangeSubKeys(); + @Nullable + public abstract String getChangePrimaryUserId(); - public ArrayList mRevokeUserIds; - public ArrayList mRevokeSubKeys; + public abstract List getRevokeUserIds(); + public abstract List getRevokeSubKeys(); // if these are non-null, PINs will be changed on the token - public Passphrase mSecurityTokenPin; - public Passphrase mSecurityTokenAdminPin; + @Nullable + public abstract Passphrase getSecurityTokenPin(); + @Nullable + public abstract Passphrase getSecurityTokenAdminPin(); - // private because they have to be set together with setUpdateOptions - private boolean mUpload; - private boolean mUploadAtomic; - private ParcelableHkpKeyserver mKeyserver; + public abstract boolean isShouldUpload(); + public abstract boolean isShouldUploadAtomic(); + @Nullable + public abstract ParcelableHkpKeyserver getUploadKeyserver(); - // private because we have to set other details like key id - private ChangeUnlockParcel mNewUnlock; + @Nullable + public abstract ChangeUnlockParcel getNewUnlock(); - public SaveKeyringParcel() { - reset(); + public static Builder buildNewKeyringParcel() { + return new AutoValue_SaveKeyringParcel.Builder() + .setShouldUpload(false) + .setShouldUploadAtomic(false); } - public SaveKeyringParcel(long masterKeyId, byte[] fingerprint) { - this(); - mMasterKeyId = masterKeyId; - mFingerprint = fingerprint; + public static Builder buildChangeKeyringParcel(long masterKeyId, byte[] fingerprint) { + return buildNewKeyringParcel() + .setMasterKeyId(masterKeyId) + .setFingerprint(fingerprint); } - public void reset() { - mNewUnlock = null; - mAddUserIds = new ArrayList<>(); - mAddUserAttribute = new ArrayList<>(); - mAddSubKeys = new ArrayList<>(); - mChangePrimaryUserId = null; - mChangeSubKeys = new ArrayList<>(); - mRevokeUserIds = new ArrayList<>(); - mRevokeSubKeys = new ArrayList<>(); - mSecurityTokenPin = null; - mSecurityTokenAdminPin = null; - mUpload = false; - mUploadAtomic = false; - mKeyserver = null; + abstract Builder toBuilder(); + + public static Builder buildUpon(SaveKeyringParcel saveKeyringParcel) { + SaveKeyringParcel.Builder builder = saveKeyringParcel.toBuilder(); + builder.addUserIds.addAll(saveKeyringParcel.getAddUserIds()); + builder.revokeUserIds.addAll(saveKeyringParcel.getRevokeUserIds()); + builder.addUserAttribute.addAll(saveKeyringParcel.getAddUserAttribute()); + builder.addSubKeys.addAll(saveKeyringParcel.getAddSubKeys()); + builder.changeSubKeys.addAll(saveKeyringParcel.getChangeSubKeys()); + builder.revokeSubKeys.addAll(saveKeyringParcel.getRevokeSubKeys()); + return builder; } - public void setUpdateOptions(boolean upload, boolean uploadAtomic, ParcelableHkpKeyserver keyserver) { - mUpload = upload; - mUploadAtomic = uploadAtomic; - mKeyserver = keyserver; - } + @AutoValue.Builder + public static abstract class Builder { + private ArrayList addUserIds = new ArrayList<>(); + private ArrayList revokeUserIds = new ArrayList<>(); + private ArrayList addUserAttribute = new ArrayList<>(); + private ArrayList addSubKeys = new ArrayList<>(); + private ArrayList changeSubKeys = new ArrayList<>(); + private ArrayList revokeSubKeys = new ArrayList<>(); - public void setNewUnlock(ChangeUnlockParcel parcel) { - mNewUnlock = parcel; - } - public ChangeUnlockParcel getChangeUnlockParcel() { - return mNewUnlock; - } + public abstract Builder setChangePrimaryUserId(String changePrimaryUserId); + public abstract Builder setSecurityTokenPin(Passphrase securityTokenPin); + public abstract Builder setSecurityTokenAdminPin(Passphrase securityTokenAdminPin); + public abstract Builder setNewUnlock(ChangeUnlockParcel newUnlock); - public boolean isUpload() { - return mUpload; - } + public abstract Long getMasterKeyId(); + public abstract byte[] getFingerprint(); + public abstract String getChangePrimaryUserId(); - public boolean isUploadAtomic() { - return mUploadAtomic; - } - public ParcelableHkpKeyserver getUploadKeyserver() { - return mKeyserver; - } - - public boolean isEmpty() { - return isRestrictedOnly() && mChangeSubKeys.isEmpty(); - } - - /** Returns true iff this parcel does not contain any operations which require a passphrase. */ - public boolean isRestrictedOnly() { - if (mNewUnlock != null || !mAddUserIds.isEmpty() || !mAddUserAttribute.isEmpty() - || !mAddSubKeys.isEmpty() || mChangePrimaryUserId != null || !mRevokeUserIds.isEmpty() - || !mRevokeSubKeys.isEmpty()) { - return false; + public ArrayList getMutableAddSubKeys() { + return addSubKeys; + } + public ArrayList getMutableAddUserIds() { + return addUserIds; + } + public ArrayList getMutableRevokeSubKeys() { + return revokeSubKeys; + } + public ArrayList getMutableRevokeUserIds() { + return revokeUserIds; } - for (SubkeyChange change : mChangeSubKeys) { - if (change.getRecertify() || change.getFlags() != null || change.getExpiry() != null - || change.getMoveKeyToSecurityToken()) { - return false; + abstract Builder setMasterKeyId(Long masterKeyId); + abstract Builder setFingerprint(byte[] fingerprint); + abstract Builder setAddUserIds(List addUserIds); + abstract Builder setAddUserAttribute(List addUserAttribute); + abstract Builder setAddSubKeys(List addSubKeys); + abstract Builder setChangeSubKeys(List changeSubKeys); + abstract Builder setRevokeUserIds(List revokeUserIds); + abstract Builder setRevokeSubKeys(List revokeSubKeys); + abstract Builder setShouldUpload(boolean upload); + abstract Builder setShouldUploadAtomic(boolean uploadAtomic); + abstract Builder setUploadKeyserver(ParcelableHkpKeyserver keyserver); + + public void setUpdateOptions(boolean upload, boolean uploadAtomic, ParcelableHkpKeyserver keyserver) { + setShouldUpload(upload); + setShouldUploadAtomic(uploadAtomic); + setUploadKeyserver(keyserver); + } + + public void addSubkeyAdd(SubkeyAdd subkeyAdd) { + addSubKeys.add(subkeyAdd); + } + + public void addUserId(String userId) { + addUserIds.add(userId); + } + + public void addRevokeSubkey(long masterKeyId) { + revokeSubKeys.add(masterKeyId); + } + + public void removeRevokeSubkey(long keyId) { + revokeSubKeys.remove(keyId); + } + + public void addRevokeUserId(String userId) { + revokeUserIds.add(userId); + } + + public void removeRevokeUserId(String userId) { + revokeUserIds.remove(userId); + } + + public void addOrReplaceSubkeyChange(SubkeyChange newChange) { + SubkeyChange foundSubkeyChange = getSubkeyChange(newChange.getSubKeyId()); + + if (foundSubkeyChange != null) { + changeSubKeys.remove(foundSubkeyChange); } + changeSubKeys.add(newChange); } - return true; + public void removeSubkeyChange(SubkeyChange change) { + changeSubKeys.remove(change); + } + + public SubkeyChange getSubkeyChange(long keyId) { + if (changeSubKeys == null) { + return null; + } + + for (SubkeyChange subkeyChange : changeSubKeys) { + if (subkeyChange.getSubKeyId() == keyId) { + return subkeyChange; + } + } + return null; + } + + public void addUserAttribute(WrappedUserAttribute ua) { + addUserAttribute.add(ua); + } + + abstract SaveKeyringParcel autoBuild(); + + public SaveKeyringParcel build() { + setAddUserAttribute(Collections.unmodifiableList(addUserAttribute)); + setRevokeSubKeys(Collections.unmodifiableList(revokeSubKeys)); + setRevokeUserIds(Collections.unmodifiableList(revokeUserIds)); + setAddSubKeys(Collections.unmodifiableList(addSubKeys)); + setAddUserIds(Collections.unmodifiableList(addUserIds)); + setChangeSubKeys(Collections.unmodifiableList(changeSubKeys)); + + return autoBuild(); + } } // performance gain for using Parcelable here would probably be negligible, @@ -208,114 +286,6 @@ public class SaveKeyringParcel implements Parcelable { } } - public SubkeyChange getSubkeyChange(long keyId) { - for (SubkeyChange subkeyChange : mChangeSubKeys) { - if (subkeyChange.getSubKeyId() == keyId) { - return subkeyChange; - } - } - return null; - } - - public void addOrReplaceSubkeyChange(SubkeyChange change) { - SubkeyChange foundSubkeyChange = getSubkeyChange(change.getSubKeyId()); - if (foundSubkeyChange != null) { - mChangeSubKeys.remove(foundSubkeyChange); - } - - mChangeSubKeys.add(change); - } - - public void removeSubkeyChange(SubkeyChange change) { - mChangeSubKeys.remove(change); - } - - @SuppressWarnings("unchecked") // we verify the reads against writes in writeToParcel - public SaveKeyringParcel(Parcel source) { - mMasterKeyId = source.readInt() != 0 ? source.readLong() : null; - mFingerprint = source.createByteArray(); - - mNewUnlock = source.readParcelable(getClass().getClassLoader()); - - mAddUserIds = source.createStringArrayList(); - mAddUserAttribute = (ArrayList) source.readSerializable(); - mAddSubKeys = (ArrayList) source.readSerializable(); - - mChangeSubKeys = (ArrayList) source.readSerializable(); - mChangePrimaryUserId = source.readString(); - - mRevokeUserIds = source.createStringArrayList(); - mRevokeSubKeys = (ArrayList) source.readSerializable(); - - mSecurityTokenPin = source.readParcelable(Passphrase.class.getClassLoader()); - mSecurityTokenAdminPin = source.readParcelable(Passphrase.class.getClassLoader()); - - mUpload = source.readByte() != 0; - mUploadAtomic = source.readByte() != 0; - mKeyserver = source.readParcelable(ParcelableHkpKeyserver.class.getClassLoader()); - } - - @Override - public void writeToParcel(Parcel destination, int flags) { - destination.writeInt(mMasterKeyId == null ? 0 : 1); - if (mMasterKeyId != null) { - destination.writeLong(mMasterKeyId); - } - destination.writeByteArray(mFingerprint); - - // yes, null values are ok for parcelables - destination.writeParcelable(mNewUnlock, flags); - - destination.writeStringList(mAddUserIds); - destination.writeSerializable(mAddUserAttribute); - destination.writeSerializable(mAddSubKeys); - - destination.writeSerializable(mChangeSubKeys); - destination.writeString(mChangePrimaryUserId); - - destination.writeStringList(mRevokeUserIds); - destination.writeSerializable(mRevokeSubKeys); - - destination.writeParcelable(mSecurityTokenPin, flags); - destination.writeParcelable(mSecurityTokenAdminPin, flags); - - destination.writeByte((byte) (mUpload ? 1 : 0)); - destination.writeByte((byte) (mUploadAtomic ? 1 : 0)); - destination.writeParcelable(mKeyserver, flags); - } - - public static final Creator CREATOR = new Creator() { - public SaveKeyringParcel createFromParcel(final Parcel source) { - return new SaveKeyringParcel(source); - } - - public SaveKeyringParcel[] newArray(final int size) { - return new SaveKeyringParcel[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public String toString() { - String out = "mMasterKeyId: " + mMasterKeyId + "\n"; - out += "mNewUnlock: " + mNewUnlock + "\n"; - out += "mAddUserIds: " + mAddUserIds + "\n"; - out += "mAddUserAttribute: " + mAddUserAttribute + "\n"; - out += "mAddSubKeys: " + mAddSubKeys + "\n"; - out += "mChangeSubKeys: " + mChangeSubKeys + "\n"; - out += "mChangePrimaryUserId: " + mChangePrimaryUserId + "\n"; - out += "mRevokeUserIds: " + mRevokeUserIds + "\n"; - out += "mRevokeSubKeys: " + mRevokeSubKeys + "\n"; - out += "mSecurityTokenPin: " + mSecurityTokenPin + "\n"; - out += "mSecurityTokenAdminPin: " + mSecurityTokenAdminPin; - - return out; - } - // All supported algorithms public enum Algorithm { RSA, DSA, ELGAMAL, ECDSA, ECDH @@ -330,7 +300,4 @@ public class SaveKeyringParcel implements Parcelable { // (adding support would be trivial though -> JcaPGPKeyConverter.java:190) // BRAINPOOL_P256, BRAINPOOL_P384, BRAINPOOL_P512 } - - - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 26db42c63..bbf4a906a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -295,7 +295,7 @@ public class CreateKeyFinalFragment extends Fragment { } private static SaveKeyringParcel createDefaultSaveKeyringParcel(CreateKeyActivity createKeyActivity) { - SaveKeyringParcel saveKeyringParcel = new SaveKeyringParcel(); + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); if (createKeyActivity.mCreateSecurityToken) { if (createKeyActivity.mSecurityTokenSign == null) { @@ -303,38 +303,40 @@ public class CreateKeyFinalFragment extends Fragment { createKeyActivity.mSecurityTokenDec = Constants.SECURITY_TOKEN_V2_DEC; createKeyActivity.mSecurityTokenAuth = Constants.SECURITY_TOKEN_V2_AUTH; } - createKeyActivity.mSecurityTokenSign.addToSaveKeyringParcel(saveKeyringParcel, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER); - createKeyActivity.mSecurityTokenDec.addToSaveKeyringParcel(saveKeyringParcel, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); - createKeyActivity.mSecurityTokenAuth.addToSaveKeyringParcel(saveKeyringParcel, KeyFlags.AUTHENTICATION); + createKeyActivity.mSecurityTokenSign.addToSaveKeyringParcel( + builder, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER); + createKeyActivity.mSecurityTokenDec.addToSaveKeyringParcel( + builder, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); + createKeyActivity.mSecurityTokenAuth.addToSaveKeyringParcel(builder, KeyFlags.AUTHENTICATION); // use empty passphrase - saveKeyringParcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); } else { - Constants.addDefaultSubkeys(saveKeyringParcel); + Constants.addDefaultSubkeys(builder); if (createKeyActivity.mPassphrase != null) { - saveKeyringParcel.setNewUnlock( + builder.setNewUnlock( ChangeUnlockParcel.createUnLockParcelForNewKey(createKeyActivity.mPassphrase)); } else { - saveKeyringParcel.setNewUnlock(null); + builder.setNewUnlock(null); } } String userId = KeyRing.createUserId( new OpenPgpUtils.UserId(createKeyActivity.mName, createKeyActivity.mEmail, null) ); - saveKeyringParcel.mAddUserIds.add(userId); - saveKeyringParcel.mChangePrimaryUserId = userId; + builder.addUserId(userId); + builder.setChangePrimaryUserId(userId); if (createKeyActivity.mAdditionalEmails != null && createKeyActivity.mAdditionalEmails.size() > 0) { for (String email : createKeyActivity.mAdditionalEmails) { String thisUserId = KeyRing.createUserId( new OpenPgpUtils.UserId(createKeyActivity.mName, email, null) ); - saveKeyringParcel.mAddUserIds.add(thisUserId); + builder.addUserId(thisUserId); } } - return saveKeyringParcel; + return builder.build(); } private void checkEmailValidity() { @@ -427,11 +429,11 @@ public class CreateKeyFinalFragment extends Fragment { private void moveToCard(final EditKeyResult saveKeyResult) { CreateKeyActivity activity = (CreateKeyActivity) getActivity(); - final SaveKeyringParcel changeKeyringParcel; + SaveKeyringParcel.Builder builder; CachedPublicKeyRing key = (KeyRepository.createDatabaseInteractor(getContext())) .getCachedPublicKeyRing(saveKeyResult.mMasterKeyId); try { - changeKeyringParcel = new SaveKeyringParcel(key.getMasterKeyId(), key.getFingerprint()); + builder = SaveKeyringParcel.buildChangeKeyringParcel(key.getMasterKeyId(), key.getFingerprint()); } catch (PgpKeyNotFoundException e) { Log.e(Constants.TAG, "Key that should be moved to Security Token not found in database!"); return; @@ -439,13 +441,13 @@ public class CreateKeyFinalFragment extends Fragment { // define subkeys that should be moved to the card Cursor cursor = activity.getContentResolver().query( - KeychainContract.Keys.buildKeysUri(changeKeyringParcel.mMasterKeyId), + KeychainContract.Keys.buildKeysUri(builder.getMasterKeyId()), new String[]{KeychainContract.Keys.KEY_ID,}, null, null, null ); try { while (cursor != null && cursor.moveToNext()) { long subkeyId = cursor.getLong(0); - changeKeyringParcel.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(subkeyId)); + builder.addOrReplaceSubkeyChange(SubkeyChange.createMoveToSecurityTokenChange(subkeyId)); } } finally { if (cursor != null) { @@ -454,15 +456,17 @@ public class CreateKeyFinalFragment extends Fragment { } // define new PIN and Admin PIN for the card - changeKeyringParcel.mSecurityTokenPin = activity.mSecurityTokenPin; - changeKeyringParcel.mSecurityTokenAdminPin = activity.mSecurityTokenAdminPin; + builder.setSecurityTokenPin(activity.mSecurityTokenPin); + builder.setSecurityTokenAdminPin(activity.mSecurityTokenAdminPin); + + final SaveKeyringParcel saveKeyringParcel = builder.build(); CryptoOperationHelper.Callback callback = new CryptoOperationHelper.Callback() { @Override public SaveKeyringParcel createOperationInput() { - return changeKeyringParcel; + return saveKeyringParcel; } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java index e7944f41a..ee3b9fa27 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditIdentitiesFragment.java @@ -82,7 +82,7 @@ public class EditIdentitiesFragment extends Fragment private Uri mDataUri; - private SaveKeyringParcel mSaveKeyringParcel; + private SaveKeyringParcel.Builder mSkpBuilder; private CryptoOperationHelper mEditOpHelper; private CryptoOperationHelper mUploadOpHelper; @@ -180,7 +180,7 @@ public class EditIdentitiesFragment extends Fragment return; } - mSaveKeyringParcel = new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint()); + mSkpBuilder = SaveKeyringParcel.buildChangeKeyringParcel(masterKeyId, keyRing.getFingerprint()); mPrimaryUserId = keyRing.getPrimaryUserIdWithFallback(); } catch (PgpKeyNotFoundException | NotFoundException e) { @@ -193,11 +193,11 @@ public class EditIdentitiesFragment extends Fragment getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, EditIdentitiesFragment.this); mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0); - mUserIdsAdapter.setEditMode(mSaveKeyringParcel); + mUserIdsAdapter.setEditMode(mSkpBuilder); mUserIdsList.setAdapter(mUserIdsAdapter); // TODO: SaveParcel from savedInstance?! - mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds, false); + mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSkpBuilder.getMutableAddUserIds(), false); mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter); } @@ -266,23 +266,23 @@ public class EditIdentitiesFragment extends Fragment switch (message.what) { case EditUserIdDialogFragment.MESSAGE_CHANGE_PRIMARY_USER_ID: // toggle - if (mSaveKeyringParcel.mChangePrimaryUserId != null - && mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) { - mSaveKeyringParcel.mChangePrimaryUserId = null; + if (mSkpBuilder.getChangePrimaryUserId() != null + && mSkpBuilder.getChangePrimaryUserId().equals(userId)) { + mSkpBuilder.setChangePrimaryUserId(null); } else { - mSaveKeyringParcel.mChangePrimaryUserId = userId; + mSkpBuilder.setChangePrimaryUserId(userId); } break; case EditUserIdDialogFragment.MESSAGE_REVOKE: // toggle - if (mSaveKeyringParcel.mRevokeUserIds.contains(userId)) { - mSaveKeyringParcel.mRevokeUserIds.remove(userId); + if (mSkpBuilder.getMutableRevokeUserIds().contains(userId)) { + mSkpBuilder.removeRevokeUserId(userId); } else { - mSaveKeyringParcel.mRevokeUserIds.add(userId); + mSkpBuilder.addRevokeUserId(userId); // not possible to revoke and change to primary user id - if (mSaveKeyringParcel.mChangePrimaryUserId != null - && mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) { - mSaveKeyringParcel.mChangePrimaryUserId = null; + if (mSkpBuilder.getChangePrimaryUserId() != null + && mSkpBuilder.getChangePrimaryUserId().equals(userId)) { + mSkpBuilder.setChangePrimaryUserId(null); } } break; @@ -339,7 +339,7 @@ public class EditIdentitiesFragment extends Fragment = new CryptoOperationHelper.Callback() { @Override public SaveKeyringParcel createOperationInput() { - return mSaveKeyringParcel; + return mSkpBuilder.build(); } @Override 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 65ef848d9..50e6b617f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -100,7 +100,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment 0; // for edit key - if (mSaveKeyringParcel != null) { - boolean changeAnyPrimaryUserId = (mSaveKeyringParcel.mChangePrimaryUserId != null); - boolean changeThisPrimaryUserId = (mSaveKeyringParcel.mChangePrimaryUserId != null - && mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)); - boolean revokeThisUserId = (mSaveKeyringParcel.mRevokeUserIds.contains(userId)); + if (mSkpBuilder != null) { + String changePrimaryUserId = mSkpBuilder.getChangePrimaryUserId(); + boolean changeAnyPrimaryUserId = (changePrimaryUserId != null); + boolean changeThisPrimaryUserId = (changeAnyPrimaryUserId && changePrimaryUserId.equals(userId)); + boolean revokeThisUserId = (mSkpBuilder.getMutableRevokeUserIds().contains(userId)); // only if primary user id will be changed // (this is not triggered if the user id is currently the primary one) @@ -161,8 +157,8 @@ public class UserIdsAdapter extends UserAttributesAdapter { String userId = mCursor.getString(INDEX_USER_ID); boolean isRevokedPending = false; - if (mSaveKeyringParcel != null) { - if (mSaveKeyringParcel.mRevokeUserIds.contains(userId)) { + if (mSkpBuilder != null) { + if (mSkpBuilder.getMutableRevokeUserIds().contains(userId)) { isRevokedPending = true; } @@ -181,8 +177,8 @@ public class UserIdsAdapter extends UserAttributesAdapter { * * @param saveKeyringParcel The parcel to get info from, or null to leave edit mode. */ - public void setEditMode(@Nullable SaveKeyringParcel saveKeyringParcel) { - mSaveKeyringParcel = saveKeyringParcel; + public void setEditMode(@Nullable SaveKeyringParcel.Builder saveKeyringParcel) { + mSkpBuilder = saveKeyringParcel; } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java index 13e46e8e7..d9139d09a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java @@ -143,7 +143,7 @@ public class ViewKeyFragment extends LoaderFragment implements LoaderManager.Loa mIsSecret = getArguments().getBoolean(ARG_IS_SECRET); // load user ids after we know if it's a secret key - mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, !mIsSecret, null); + mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, !mIsSecret); mUserIds.setAdapter(mUserIdsAdapter); // initialize loaders, which will take care of auto-refresh on change diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java index 6eb48ab7f..f8ff6421b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java @@ -210,15 +210,11 @@ public abstract class LinkedIdCreateFinalFragment extends CryptoOperationFragmen @Nullable @Override public Parcelable createOperationInput() { - SaveKeyringParcel skp = - new SaveKeyringParcel(mLinkedIdWizard.mMasterKeyId, mLinkedIdWizard.mFingerprint); - - WrappedUserAttribute ua = - LinkedAttribute.fromResource(mVerifiedResource).toUserAttribute(); - - skp.mAddUserAttribute.add(ua); - - return skp; + SaveKeyringParcel.Builder builder= + SaveKeyringParcel.buildChangeKeyringParcel(mLinkedIdWizard.mMasterKeyId, mLinkedIdWizard.mFingerprint); + WrappedUserAttribute ua = LinkedAttribute.fromResource(mVerifiedResource).toUserAttribute(); + builder.addUserAttribute(ua); + return builder.build(); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java index 30f217d50..efe610196 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java @@ -96,7 +96,7 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment(), new ArrayList(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); @@ -644,10 +644,10 @@ public class PgpEncryptDecryptTest { { // change flags of second encrypted subkey, decryption should skip it - SaveKeyringParcel parcel = - new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null)); - UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildChangeKeyringParcel( + mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); + builder.addOrReplaceSubkeyChange(SubkeyChange.createFlagsOrExpiryChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null)); + UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(builder.build(), mStaticRing1, new ArrayList(), new ArrayList(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); @@ -673,9 +673,10 @@ public class PgpEncryptDecryptTest { String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true); { // revoke first encryption subkey of keyring in database - SaveKeyringParcel parcel = new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); - parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(mStaticRing1, 2)); - UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildChangeKeyringParcel( + mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); + builder.addRevokeSubkey(KeyringTestingHelper.getSubkeyId(mStaticRing1, 2)); + UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(builder.build(), mStaticRing1, new ArrayList(), new ArrayList(), CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1)); 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 843fe87ca..06d112b6a 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperationTest.java @@ -18,8 +18,20 @@ package org.sufficientlysecure.keychain.pgp; -import junit.framework.AssertionFailedError; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.security.Security; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import junit.framework.AssertionFailedError; import org.bouncycastle.bcpg.BCPGInputStream; import org.bouncycastle.bcpg.Packet; import org.bouncycastle.bcpg.PacketTags; @@ -58,16 +70,18 @@ import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ProgressScaler; import org.sufficientlysecure.keychain.util.TestingUtils; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.security.Security; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Random; +import static org.bouncycastle.bcpg.sig.KeyFlags.CERTIFY_OTHER; +import static org.bouncycastle.bcpg.sig.KeyFlags.SIGN_DATA; +import static org.sufficientlysecure.keychain.operations.results.OperationResult.LogType.MSG_MF_ERROR_FINGERPRINT; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm.ECDSA; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm.RSA; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve.NIST_P256; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd.createSubkeyAdd; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange.createFlagsOrExpiryChange; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange.createRecertifyChange; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange.createStripChange; +import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.buildChangeKeyringParcel; + @RunWith(KeychainTestRunner.class) public class PgpKeyOperationTest { @@ -77,7 +91,7 @@ public class PgpKeyOperationTest { UncachedKeyRing ring; PgpKeyOperation op; - SaveKeyringParcel parcel; + SaveKeyringParcel.Builder builder; ArrayList onlyA = new ArrayList<>(); ArrayList onlyB = new ArrayList<>(); @@ -88,28 +102,28 @@ public class PgpKeyOperationTest { Security.insertProviderAt(new BouncyCastleProvider(), 1); ShadowLog.stream = System.out; - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); - parcel.mAddUserIds.add("twi"); - parcel.mAddUserIds.add("pink"); + builder.addUserId("twi"); + builder.addUserId("pink"); { int type = 42; byte[] data = new byte[] { 0, 1, 2, 3, 4 }; WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data); - parcel.mAddUserAttribute.add(uat); + builder.addUserAttribute(uat); } - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); PgpKeyOperation op = new PgpKeyOperation(null); - PgpEditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(builder.build()); Assert.assertTrue("initial test key creation must succeed", result.success()); Assert.assertNotNull("initial test key creation must succeed", result.getRing()); @@ -123,7 +137,8 @@ public class PgpKeyOperationTest { } - @Before public void setUp() throws Exception { + @Before + public void setUp() throws Exception { // show Log.x messages in system.out ShadowLog.stream = System.out; ring = staticRing; @@ -131,76 +146,76 @@ public class PgpKeyOperationTest { // setting up some parameters just to reduce code duplication op = new PgpKeyOperation(new ProgressScaler(null, 0, 100, 100)); - // set this up, gonna need it more than once - parcel = new SaveKeyringParcel(); - parcel.mMasterKeyId = ring.getMasterKeyId(); - parcel.mFingerprint = ring.getFingerprint(); + resetBuilder(); + } + private void resetBuilder() { + builder = SaveKeyringParcel.buildChangeKeyringParcel(ring.getMasterKeyId(), ring.getFingerprint()); } @Test public void createSecretKeyRingTests() { { - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + resetBuilder(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.RSA, new Random().nextInt(256)+255, null, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddUserIds.add("shy"); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + builder.addUserId("shy"); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); - assertFailure("creating ring with < 2048 bit keysize should fail", parcel, + assertFailure("creating ring with < 2048 bit keysize should fail", builder.build(), LogType.MSG_CR_ERROR_KEYSIZE_2048); } { - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + resetBuilder(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ELGAMAL, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddUserIds.add("shy"); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + builder.addUserId("shy"); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); - assertFailure("creating ring with ElGamal master key should fail", parcel, + assertFailure("creating ring with ElGamal master key should fail", builder.build(), LogType.MSG_CR_ERROR_FLAGS_ELGAMAL); } { - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + resetBuilder(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, null)); - parcel.mAddUserIds.add("lotus"); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + builder.addUserId("lotus"); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); - assertFailure("creating master key with null expiry should fail", parcel, + assertFailure("creating master key with null expiry should fail", builder.build(), LogType.MSG_CR_ERROR_NULL_EXPIRY); } { - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + resetBuilder(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddUserIds.add("shy"); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + builder.addUserId("shy"); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); - assertFailure("creating ring with non-certifying master key should fail", parcel, + assertFailure("creating ring with non-certifying master key should fail", builder.build(), LogType.MSG_CR_ERROR_NO_CERTIFY); } { - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + resetBuilder(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); - assertFailure("creating ring without user ids should fail", parcel, + assertFailure("creating ring without user ids should fail", builder.build(), LogType.MSG_CR_ERROR_NO_USER_ID); } { - parcel.reset(); - parcel.mAddUserIds.add("shy"); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + resetBuilder(); + builder.addUserId("shy"); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); - assertFailure("creating ring with no master key should fail", parcel, + assertFailure("creating ring with no master key should fail", builder.build(), LogType.MSG_CR_ERROR_NO_MASTER); } @@ -210,11 +225,11 @@ public class PgpKeyOperationTest { // this is a special case since the flags are in user id certificates rather than // subkey binding certificates public void testMasterFlags() throws Exception { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L)); - parcel.mAddUserIds.add("luna"); - ring = assertCreateSuccess("creating ring with master key flags must succeed", parcel); + builder.addUserId("luna"); + ring = assertCreateSuccess("creating ring with master key flags must succeed", builder.build()); Assert.assertEquals("the keyring should contain only the master key", 1, KeyringTestingHelper.itToList(ring.getPublicKeys()).size()); @@ -280,43 +295,27 @@ public class PgpKeyOperationTest { public void testBadKeyModification() throws Exception { { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - // off by one - parcel.mMasterKeyId = ring.getMasterKeyId() -1; - parcel.mFingerprint = ring.getFingerprint(); + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildChangeKeyringParcel( + ring.getMasterKeyId() -1, ring.getFingerprint()); assertModifyFailure("keyring modification with bad master key id should fail", - ring, parcel, LogType.MSG_MF_ERROR_KEYID); + ring, builder.build(), LogType.MSG_MF_ERROR_KEYID); } { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - // off by one - parcel.mMasterKeyId = null; - parcel.mFingerprint = ring.getFingerprint(); + byte[] fingerprint = Arrays.copyOf(ring.getFingerprint(), ring.getFingerprint().length); + fingerprint[5] += 1; - assertModifyFailure("keyring modification with null master key id should fail", - ring, parcel, LogType.MSG_MF_ERROR_KEYID); - } - - { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mMasterKeyId = ring.getMasterKeyId(); - parcel.mFingerprint = ring.getFingerprint(); - // some byte, off by one - parcel.mFingerprint[5] += 1; + SaveKeyringParcel.Builder builder = buildChangeKeyringParcel(ring.getMasterKeyId(), fingerprint); assertModifyFailure("keyring modification with bad fingerprint should fail", - ring, parcel, LogType.MSG_MF_ERROR_FINGERPRINT); + ring, builder.build(), MSG_MF_ERROR_FINGERPRINT); } { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mMasterKeyId = ring.getMasterKeyId(); - parcel.mFingerprint = null; - + SaveKeyringParcel.Builder builder = buildChangeKeyringParcel(ring.getMasterKeyId(), null); assertModifyFailure("keyring modification with null fingerprint should fail", - ring, parcel, LogType.MSG_MF_ERROR_FINGERPRINT); + ring, builder.build(), MSG_MF_ERROR_FINGERPRINT); } { @@ -324,16 +323,16 @@ public class PgpKeyOperationTest { if (badphrase.equals(passphrase)) { badphrase = new Passphrase("a"); } - parcel.mAddUserIds.add("allure"); + builder.addUserId("allure"); assertModifyFailure("keyring modification with bad passphrase should fail", - ring, parcel, CryptoInputParcel.createCryptoInputParcel(badphrase), LogType.MSG_MF_UNLOCK_ERROR); + ring, builder.build(), CryptoInputParcel.createCryptoInputParcel(badphrase), LogType.MSG_MF_UNLOCK_ERROR); } { - parcel.reset(); + resetBuilder(); assertModifyFailure("no-op should fail", - ring, parcel, cryptoInput, LogType.MSG_MF_ERROR_NOOP); + ring, builder.build(), cryptoInput, LogType.MSG_MF_ERROR_NOOP); } } @@ -343,10 +342,10 @@ public class PgpKeyOperationTest { long expiry = new Date().getTime() / 1000 + 159; int flags = KeyFlags.SIGN_DATA; - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, flags, expiry)); - UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); Assert.assertEquals("exactly two extra packets in modified", 2, onlyB.size()); @@ -381,26 +380,27 @@ public class PgpKeyOperationTest { flags, (long) newKey.getKeyUsage()); { // bad keysize should fail - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( - Algorithm.RSA, new Random().nextInt(512), null, KeyFlags.SIGN_DATA, 0L)); - assertModifyFailure("creating a subkey with keysize < 2048 should fail", ring, parcel, + resetBuilder(); + builder.addSubkeyAdd(createSubkeyAdd( + RSA, new Random().nextInt(512), null, SIGN_DATA, 0L)); + assertModifyFailure("creating a subkey with keysize < 2048 should fail", ring, builder.build(), LogType.MSG_CR_ERROR_KEYSIZE_2048); } { // null expiry should fail - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( - Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, null)); - assertModifyFailure("creating master key with null expiry should fail", ring, parcel, + resetBuilder(); + builder.addSubkeyAdd(createSubkeyAdd( + ECDSA, 0, NIST_P256, SIGN_DATA, null)); + assertModifyFailure("creating master key with null expiry should fail", ring, builder.build(), LogType.MSG_MF_ERROR_NULL_EXPIRY); } { // a past expiry should fail - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( - Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, new Date().getTime()/1000-10)); - assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel, + resetBuilder(); + builder.addSubkeyAdd(createSubkeyAdd( + ECDSA, 0, NIST_P256, SIGN_DATA, + new Date().getTime() / 1000 - 10)); + assertModifyFailure("creating subkey with past expiry date should fail", ring, builder.build(), LogType.MSG_MF_ERROR_PAST_EXPIRY); } @@ -414,8 +414,8 @@ public class PgpKeyOperationTest { UncachedKeyRing modified = ring; { - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("one extra packet in original", 1, onlyA.size()); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); @@ -441,8 +441,8 @@ public class PgpKeyOperationTest { { // change expiry expiry += 60*60*24; - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertNotNull("modified key must have an expiry date", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting()); @@ -454,9 +454,9 @@ public class PgpKeyOperationTest { { int flags = KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS; - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, flags, null)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, flags, null)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("old packet must be signature", PacketTags.SIGNATURE, onlyA.get(0).tag); @@ -477,9 +477,9 @@ public class PgpKeyOperationTest { } { // expiry of 0 should be "no expiry" - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, 0L)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, 0L)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("old packet must be signature", PacketTags.SIGNATURE, onlyA.get(0).tag); @@ -495,18 +495,18 @@ public class PgpKeyOperationTest { } { // a past expiry should fail - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, new Date().getTime()/1000-10)); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, new Date().getTime() / 1000 - 10)); - assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel, + assertModifyFailure("setting subkey expiry to a past date should fail", ring, builder.build(), LogType.MSG_MF_ERROR_PAST_EXPIRY); } { // modifying nonexistent subkey should fail - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(123, null, null)); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(123, null, null)); - assertModifyFailure("modifying non-existent subkey should fail", ring, parcel, + assertModifyFailure("modifying non-existent subkey should fail", ring, builder.build(), LogType.MSG_MF_ERROR_SUBKEY_MISSING); } @@ -521,15 +521,15 @@ public class PgpKeyOperationTest { UncachedKeyRing modified = ring; // to make this check less trivial, we add a user id, change the primary one and revoke one - parcel.mAddUserIds.add("aloe"); - parcel.mChangePrimaryUserId = "aloe"; - parcel.mRevokeUserIds.add("pink"); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + builder.addUserId("aloe"); + builder.setChangePrimaryUserId("aloe"); + builder.addRevokeUserId("pink"); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); { - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); // this implies that only the two non-revoked signatures were changed! Assert.assertEquals("two extra packets in original", 2, onlyA.size()); @@ -555,8 +555,8 @@ public class PgpKeyOperationTest { { // change expiry expiry += 60*60*24; - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertNotNull("modified key must have an expiry date", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting()); @@ -574,9 +574,9 @@ public class PgpKeyOperationTest { { int flags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA; - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, flags, null)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, flags, null)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("modified key must have expected flags", flags, (long) modified.getPublicKey(keyId).getKeyUsage()); @@ -590,13 +590,13 @@ public class PgpKeyOperationTest { // even if there is a non-expiring user id while all others are revoked, it doesn't count! // for this purpose we revoke one while they still have expiry times - parcel.reset(); - parcel.mRevokeUserIds.add("aloe"); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + resetBuilder(); + builder.addRevokeUserId("aloe"); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, 0L)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, 0L)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); // for this check, it is relevant that we DON'T use the unsafe one! Assert.assertNull("key must not expire anymore", @@ -607,28 +607,28 @@ public class PgpKeyOperationTest { } { // if we revoke everything, nothing is left to properly sign... - parcel.reset(); - parcel.mRevokeUserIds.add("twi"); - parcel.mRevokeUserIds.add("pink"); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, KeyFlags.CERTIFY_OTHER, null)); + resetBuilder(); + builder.addRevokeUserId("twi"); + builder.addRevokeUserId("pink"); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, CERTIFY_OTHER, null)); - assertModifyFailure("master key modification with all user ids revoked should fail", ring, parcel, + assertModifyFailure("master key modification with all user ids revoked should fail", ring, builder.build(), LogType.MSG_MF_ERROR_MASTER_NONE); } { // any flag not including CERTIFY_OTHER should fail - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, KeyFlags.SIGN_DATA, null)); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, SIGN_DATA, null)); - assertModifyFailure("setting master key flags without certify should fail", ring, parcel, + assertModifyFailure("setting master key flags without certify should fail", ring, builder.build(), LogType.MSG_MF_ERROR_NO_CERTIFY); } { // a past expiry should fail - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, new Date().getTime()/1000-10)); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, new Date().getTime() / 1000 - 10)); - assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel, + assertModifyFailure("setting subkey expiry to a past date should fail", ring, builder.build(), LogType.MSG_MF_ERROR_PAST_EXPIRY); } @@ -637,10 +637,10 @@ public class PgpKeyOperationTest { @Test public void testMasterRevoke() throws Exception { - parcel.reset(); - parcel.mRevokeSubKeys.add(ring.getMasterKeyId()); + resetBuilder(); + builder.addRevokeSubkey(ring.getMasterKeyId()); - UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); @@ -669,11 +669,11 @@ public class PgpKeyOperationTest { { - parcel.reset(); - parcel.mRevokeSubKeys.add(123L); + resetBuilder(); + builder.addRevokeSubkey(123L); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0); - UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, cryptoInput, parcel).getRing(); + UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, cryptoInput, builder.build()).getRing(); Assert.assertNull("revoking a nonexistent subkey should fail", otherModified); @@ -681,10 +681,10 @@ public class PgpKeyOperationTest { { // revoked second subkey - parcel.reset(); - parcel.mRevokeSubKeys.add(keyId); + resetBuilder(); + builder.addRevokeSubkey(keyId); - modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, + modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB, CryptoInputParcel.createCryptoInputParcel(new Date(), passphrase)); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); @@ -705,11 +705,11 @@ public class PgpKeyOperationTest { { // re-add second subkey - parcel.reset(); + resetBuilder(); // re-certify the revoked subkey - parcel.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true)); + builder.addOrReplaceSubkeyChange(createRecertifyChange(keyId, true)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("exactly two outdated packets in original", 2, onlyA.size()); Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); @@ -749,8 +749,8 @@ public class PgpKeyOperationTest { public void testSubkeyStrip() throws Exception { long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); - parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId)); - applyModificationWithChecks(parcel, ring, onlyA, onlyB); + builder.addOrReplaceSubkeyChange(createStripChange(keyId)); + applyModificationWithChecks(builder.build(), ring, onlyA, onlyB); Assert.assertEquals("one extra packet in original", 1, onlyA.size()); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); @@ -775,8 +775,8 @@ public class PgpKeyOperationTest { public void testMasterStrip() throws Exception { long keyId = ring.getMasterKeyId(); - parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId)); - applyModificationWithChecks(parcel, ring, onlyA, onlyB); + builder.addOrReplaceSubkeyChange(createStripChange(keyId)); + applyModificationWithChecks(builder.build(), ring, onlyA, onlyB); Assert.assertEquals("one extra packet in original", 1, onlyA.size()); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); @@ -803,9 +803,9 @@ public class PgpKeyOperationTest { UncachedKeyRing modified; { // we should be able to change the stripped status of subkeys without passphrase - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId)); - modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, + resetBuilder(); + builder.addOrReplaceSubkeyChange(createStripChange(keyId)); + modified = applyModificationWithChecks(builder.build(), 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(); @@ -816,11 +816,11 @@ public class PgpKeyOperationTest { } { // trying to edit a subkey with signing capability should fail - parcel.reset(); - parcel.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true)); + resetBuilder(); + builder.addOrReplaceSubkeyChange(createRecertifyChange(keyId, true)); assertModifyFailure("subkey modification for signing-enabled but stripped subkey should fail", - modified, parcel, LogType.MSG_MF_ERROR_SUB_STRIPPED); + modified, builder.build(), LogType.MSG_MF_ERROR_SUB_STRIPPED); } } @@ -829,51 +829,49 @@ public class PgpKeyOperationTest { public void testKeyToSecurityToken() throws Exception { // Special keyring for security token tests with 2048 bit RSA as a subkey - SaveKeyringParcel parcelKey = new SaveKeyringParcel(); - parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder keyBuilder = SaveKeyringParcel.buildNewKeyringParcel(); + keyBuilder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.DSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); - parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + keyBuilder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); - parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + keyBuilder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.RSA, 3072, null, KeyFlags.ENCRYPT_COMMS, 0L)); - parcelKey.mAddUserIds.add("yubikey"); + keyBuilder.addUserId("yubikey"); - parcelKey.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); + keyBuilder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase)); PgpKeyOperation opSecurityToken = new PgpKeyOperation(null); - PgpEditKeyResult resultSecurityToken = opSecurityToken.createSecretKeyRing(parcelKey); + PgpEditKeyResult resultSecurityToken = opSecurityToken.createSecretKeyRing(keyBuilder.build()); Assert.assertTrue("initial test key creation must succeed", resultSecurityToken.success()); Assert.assertNotNull("initial test key creation must succeed", resultSecurityToken.getRing()); UncachedKeyRing ringSecurityToken = resultSecurityToken.getRing(); - SaveKeyringParcel parcelSecurityToken = new SaveKeyringParcel(); - parcelSecurityToken.mMasterKeyId = ringSecurityToken.getMasterKeyId(); - parcelSecurityToken.mFingerprint = ringSecurityToken.getFingerprint(); - UncachedKeyRing modified; { // moveKeyToSecurityToken should fail with BAD_NFC_ALGO when presented with the DSA-1024 key long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 0); - parcelSecurityToken.reset(); - parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(keyId)); + SaveKeyringParcel.Builder securityTokenBuilder = SaveKeyringParcel.buildChangeKeyringParcel( + ringSecurityToken.getMasterKeyId(), ringSecurityToken.getFingerprint()); + securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createMoveToSecurityTokenChange(keyId)); assertModifyFailure("moveKeyToSecurityToken operation should fail on invalid key algorithm", ringSecurityToken, - parcelSecurityToken, cryptoInput, LogType.MSG_MF_ERROR_BAD_SECURITY_TOKEN_ALGO); + securityTokenBuilder.build(), cryptoInput, LogType.MSG_MF_ERROR_BAD_SECURITY_TOKEN_ALGO); } long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 1); { // moveKeyToSecurityToken should return a pending SECURITY_TOKEN_MOVE_KEY_TO_CARD result when presented with the RSA-2048 // key, and then make key divert-to-card when it gets a serial in the cryptoInputParcel. - parcelSecurityToken.reset(); - parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(keyId)); + SaveKeyringParcel.Builder securityTokenBuilder = SaveKeyringParcel.buildChangeKeyringParcel( + ringSecurityToken.getMasterKeyId(), ringSecurityToken.getFingerprint()); + securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createMoveToSecurityTokenChange(keyId)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringSecurityToken.getEncoded(), 0); PgpKeyOperation op = new PgpKeyOperation(null); - PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcelSecurityToken); + PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, securityTokenBuilder.build()); Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending()); Assert.assertEquals("required input should be RequiredInputType.SECURITY_TOKEN_MOVE_KEY_TO_CARD", result.getRequiredInputParcel().mType, RequiredInputType.SECURITY_TOKEN_MOVE_KEY_TO_CARD); @@ -889,7 +887,7 @@ public class PgpKeyOperationTest { CryptoInputParcel inputParcel = CryptoInputParcel.createCryptoInputParcel(); inputParcel = inputParcel.withCryptoData(keyIdBytes, serial); - modified = applyModificationWithChecks(parcelSecurityToken, ringSecurityToken, onlyA, onlyB, inputParcel); + modified = applyModificationWithChecks(securityTokenBuilder.build(), ringSecurityToken, onlyA, onlyB, inputParcel); 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", @@ -901,13 +899,14 @@ public class PgpKeyOperationTest { } { // editing a signing subkey requires a primary key binding sig -> pendinginput - parcelSecurityToken.reset(); - parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true)); + SaveKeyringParcel.Builder securityTokenBuilder = SaveKeyringParcel.buildChangeKeyringParcel( + ringSecurityToken.getMasterKeyId(), ringSecurityToken.getFingerprint()); + securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createRecertifyChange(keyId, true)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0); PgpKeyOperation op = new PgpKeyOperation(null); - PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcelSecurityToken); + PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, securityTokenBuilder.build()); Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending()); Assert.assertEquals("required input should be RequiredInputType.SECURITY_TOKEN_SIGN", RequiredInputType.SECURITY_TOKEN_SIGN, result.getRequiredInputParcel().mType); @@ -922,10 +921,8 @@ public class PgpKeyOperationTest { String uid = ring.getPublicKey().getUnorderedUserIds().get(1); { // revoke second user id - - parcel.mRevokeUserIds.add(uid); - - modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + builder.addRevokeUserId(uid); + modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); @@ -943,20 +940,20 @@ public class PgpKeyOperationTest { { // re-add second user id - parcel.reset(); - parcel.mChangePrimaryUserId = uid; + resetBuilder(); + builder.setChangePrimaryUserId(uid); - assertModifyFailure("setting primary user id to a revoked user id should fail", modified, parcel, + assertModifyFailure("setting primary user id to a revoked user id should fail", modified, builder.build(), LogType.MSG_MF_ERROR_REVOKED_PRIMARY); } { // re-add second user id - parcel.reset(); - parcel.mAddUserIds.add(uid); + resetBuilder(); + builder.addUserId(uid); - applyModificationWithChecks(parcel, modified, onlyA, onlyB); + applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("exactly two outdated packets in original", 2, onlyA.size()); Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); @@ -986,10 +983,10 @@ public class PgpKeyOperationTest { } { // revocation of non-existent user id should fail - parcel.reset(); - parcel.mRevokeUserIds.add("nonexistent"); + resetBuilder(); + builder.addRevokeUserId("nonexistent"); - assertModifyFailure("revocation of nonexistent user id should fail", modified, parcel, + assertModifyFailure("revocation of nonexistent user id should fail", modified, builder.build(), LogType.MSG_MF_ERROR_NOEXIST_REVOKE); } @@ -999,15 +996,15 @@ public class PgpKeyOperationTest { public void testUserIdAdd() throws Exception { { - parcel.mAddUserIds.add(""); - assertModifyFailure("adding an empty user id should fail", ring, parcel, + builder.addUserId(""); + assertModifyFailure("adding an empty user id should fail", ring, builder.build(), LogType.MSG_MF_UID_ERROR_EMPTY); } - parcel.reset(); - parcel.mAddUserIds.add("rainbow"); + resetBuilder(); + builder.addUserId("rainbow"); - UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB); Assert.assertTrue("keyring must contain added user id", modified.getPublicKey().getUnorderedUserIds().contains("rainbow")); @@ -1036,12 +1033,12 @@ public class PgpKeyOperationTest { public void testUserAttributeAdd() throws Exception { { - parcel.mAddUserAttribute.add(WrappedUserAttribute.fromData(new byte[0])); - assertModifyFailure("adding an empty user attribute should fail", ring, parcel, + builder.addUserAttribute(WrappedUserAttribute.fromData(new byte[0])); + assertModifyFailure("adding an empty user attribute should fail", ring, builder.build(), LogType.MSG_MF_UAT_ERROR_EMPTY); } - parcel.reset(); + resetBuilder(); Random r = new Random(); int type = r.nextInt(110)+2; // any type except image attribute, to avoid interpretation of these @@ -1049,9 +1046,9 @@ public class PgpKeyOperationTest { new Random().nextBytes(data); WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data); - parcel.mAddUserAttribute.add(uat); + builder.addUserAttribute(uat); - UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); + UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); Assert.assertEquals("exactly two extra packets in modified", 2, onlyB.size()); @@ -1082,7 +1079,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, + applyModificationWithChecks(builder.build(), modified, onlyA, onlyB, CryptoInputParcel.createCryptoInputParcel(new Date(), passphrase), true, false); Assert.assertEquals("duplicate modification: one extra packet in original", 1, onlyA.size()); @@ -1103,20 +1100,20 @@ public class PgpKeyOperationTest { String uid = ring.getPublicKey().getUnorderedUserIds().get(1); { // first part, add new user id which is also primary - parcel.mAddUserIds.add("jack"); - parcel.mChangePrimaryUserId = "jack"; + builder.addUserId("jack"); + builder.setChangePrimaryUserId("jack"); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("primary user id must be the one added", "jack", modified.getPublicKey().getPrimaryUserId()); } { // second part, change primary to a different one - parcel.reset(); - parcel.mChangePrimaryUserId = uid; + resetBuilder(); + builder.setChangePrimaryUserId(uid); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB); Assert.assertEquals("old keyring must have two outdated certificates", 2, onlyA.size()); Assert.assertEquals("new keyring must have two new packets", 2, onlyB.size()); @@ -1126,15 +1123,11 @@ public class PgpKeyOperationTest { } { // third part, change primary to a non-existent one - parcel.reset(); + resetBuilder(); //noinspection SpellCheckingInspection - parcel.mChangePrimaryUserId = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - if (parcel.mChangePrimaryUserId.equals(passphrase)) { - parcel.mChangePrimaryUserId += "A"; - } - + builder.setChangePrimaryUserId("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); assertModifyFailure("changing primary user id to a non-existent one should fail", - ring, parcel, LogType.MSG_MF_ERROR_NOEXIST_PRIMARY); + ring, builder.build(), LogType.MSG_MF_ERROR_NOEXIST_PRIMARY); } // check for revoked primary user id already done in revoke test @@ -1145,9 +1138,9 @@ public class PgpKeyOperationTest { public void testPassphraseChange() throws Exception { // change passphrase to empty - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); // note that canonicalization here necessarily strips the empty notation packet - UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, cryptoInput); + UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB, cryptoInput); Assert.assertEquals("exactly three packets should have been modified (the secret keys)", 3, onlyB.size()); @@ -1160,15 +1153,15 @@ public class PgpKeyOperationTest { // modify keyring, change to non-empty passphrase Passphrase otherPassphrase = TestingUtils.genPassphrase(true); CryptoInputParcel otherCryptoInput = CryptoInputParcel.createCryptoInputParcel(otherPassphrase); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase)); - modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB, + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase)); + modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB, CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase())); Assert.assertEquals("exactly three packets should have been modified (the secret keys)", 3, onlyB.size()); { // quick check to make sure no two secret keys have the same IV - HashSet ivs = new HashSet(); + HashSet ivs = new HashSet<>(); for (int i = 0; i < 3; i++) { SecretKeyPacket p = (SecretKeyPacket) new BCPGInputStream( new ByteArrayInputStream(onlyB.get(i).buf)).readPacket(); @@ -1186,7 +1179,7 @@ public class PgpKeyOperationTest { PacketTags.SECRET_SUBKEY, sKeyNoPassphrase.tag); Passphrase otherPassphrase2 = TestingUtils.genPassphrase(true); - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase2)); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase2)); { // if we replace a secret key with one without passphrase modified = KeyringTestingHelper.removePacket(modified, sKeyNoPassphrase.position); @@ -1195,7 +1188,7 @@ public class PgpKeyOperationTest { // we should still be able to modify it (and change its passphrase) without errors PgpKeyOperation op = new PgpKeyOperation(null); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0); - PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, otherCryptoInput, parcel); + PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, otherCryptoInput, builder.build()); Assert.assertTrue("key modification must succeed", result.success()); Assert.assertFalse("log must not contain a warning", result.getLog().containsWarnings()); @@ -1212,7 +1205,7 @@ public class PgpKeyOperationTest { PgpKeyOperation op = new PgpKeyOperation(null); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0); PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(otherPassphrase2), parcel); + CryptoInputParcel.createCryptoInputParcel(otherPassphrase2), builder.build()); 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,10 +1218,10 @@ public class PgpKeyOperationTest { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0); - parcel.mAddUserIds.add("discord"); + builder.addUserId("discord"); PgpKeyOperation op = new PgpKeyOperation(null); PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(new Date()), parcel); + CryptoInputParcel.createCryptoInputParcel(new Date()), builder.build()); Assert.assertFalse("non-restricted operations should fail without passphrase", result.success()); } @@ -1299,8 +1292,8 @@ public class PgpKeyOperationTest { CanonicalizedKeyRing canonicalized = inputKeyRing.canonicalize(new OperationLog(), 0); Assert.assertNotNull("canonicalization must succeed", canonicalized); - ArrayList onlyA = new ArrayList(); - ArrayList onlyB = new ArrayList(); + ArrayList onlyA = new ArrayList<>(); + ArrayList onlyB = new ArrayList<>(); //noinspection unchecked Assert.assertTrue("keyrings differ", !KeyringTestingHelper.diffKeyrings( expectedKeyRing.getEncoded(), expectedKeyRing.getEncoded(), onlyA, onlyB)); 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 c9de64f30..36d54bcb2 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringCanonicalizeTest.java @@ -96,27 +96,27 @@ public class UncachedKeyringCanonicalizeTest { Security.insertProviderAt(new BouncyCastleProvider(), 1); ShadowLog.stream = System.out; - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); - parcel.mAddUserIds.add("twi"); - parcel.mAddUserIds.add("pink"); + builder.addUserId("twi"); + builder.addUserId("pink"); { WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(100, "sunshine, sunshine, ladybugs awake~".getBytes()); - parcel.mAddUserAttribute.add(uat); + builder.addUserAttribute(uat); } // passphrase is tested in PgpKeyOperationTest, just use empty here - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); PgpKeyOperation op = new PgpKeyOperation(null); - PgpEditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(builder.build()); Assert.assertTrue("initial test key creation must succeed", result.success()); staticRing = result.getRing(); Assert.assertNotNull("initial test key creation must succeed", staticRing); @@ -352,14 +352,14 @@ public class UncachedKeyringCanonicalizeTest { @Test public void testForeignSignature() throws Exception { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddUserIds.add("trix"); + builder.addUserId("trix"); PgpKeyOperation op = new PgpKeyOperation(null); OperationResult.OperationLog log = new OperationResult.OperationLog(); - UncachedKeyRing foreign = op.createSecretKeyRing(parcel).getRing(); + UncachedKeyRing foreign = op.createSecretKeyRing(builder.build()).getRing(); Assert.assertNotNull("initial test key creation must succeed", foreign); PGPSecretKey foreignSecretKey = 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 4b9ed015d..abc71cd65 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringMergeTest.java @@ -89,7 +89,7 @@ public class UncachedKeyringMergeTest { ArrayList onlyB = new ArrayList<>(); OperationResult.OperationLog log = new OperationResult.OperationLog(); PgpKeyOperation op; - SaveKeyringParcel parcel; + SaveKeyringParcel.Builder builder; @BeforeClass public static void setUpOnce() throws Exception { @@ -97,43 +97,42 @@ public class UncachedKeyringMergeTest { ShadowLog.stream = System.out; { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddUserIds.add("twi"); - parcel.mAddUserIds.add("pink"); + builder.addUserId("twi"); + builder.addUserId("pink"); { WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(100, "sunshine, sunshine, ladybugs awake~".getBytes()); - parcel.mAddUserAttribute.add(uat); + builder.addUserAttribute(uat); } // passphrase is tested in PgpKeyOperationTest, just use empty here - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); PgpKeyOperation op = new PgpKeyOperation(null); OperationResult.OperationLog log = new OperationResult.OperationLog(); - PgpEditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(builder.build()); staticRingA = result.getRing(); staticRingA = staticRingA.canonicalize(new OperationLog(), 0).getUncachedKeyRing(); } { - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddUserIds.add("shy"); + builder.addUserId("shy"); // passphrase is tested in PgpKeyOperationTest, just use empty here - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); PgpKeyOperation op = new PgpKeyOperation(null); - OperationResult.OperationLog log = new OperationResult.OperationLog(); - PgpEditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(builder.build()); staticRingB = result.getRing(); staticRingB = staticRingB.canonicalize(new OperationLog(), 0).getUncachedKeyRing(); } @@ -155,10 +154,11 @@ public class UncachedKeyringMergeTest { // setting up some parameters just to reduce code duplication op = new PgpKeyOperation(new ProgressScaler(null, 0, 100, 100)); - // set this up, gonna need it more than once - parcel = new SaveKeyringParcel(); - parcel.mMasterKeyId = ringA.getMasterKeyId(); - parcel.mFingerprint = ringA.getFingerprint(); + resetBuilder(); + } + + private void resetBuilder() { + builder = SaveKeyringParcel.buildChangeKeyringParcel(ringA.getMasterKeyId(), ringA.getFingerprint()); } public void testSelfNoOp() throws Exception { @@ -190,15 +190,15 @@ public class UncachedKeyringMergeTest { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringA.getEncoded(), 0); - parcel.reset(); - parcel.mAddUserIds.add("flim"); + resetBuilder(); + builder.addUserId("flim"); modifiedA = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing(); - parcel.reset(); - parcel.mAddUserIds.add("flam"); + resetBuilder(); + builder.addUserId("flam"); modifiedB = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing(); } { // merge A into base @@ -232,13 +232,13 @@ public class UncachedKeyringMergeTest { { CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringA.getEncoded(), 0); - parcel.reset(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + resetBuilder(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); modifiedA = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing(); modifiedB = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing(); subKeyIdA = KeyringTestingHelper.getSubkeyId(modifiedA, 2); subKeyIdB = KeyringTestingHelper.getSubkeyId(modifiedB, 2); @@ -275,12 +275,12 @@ public class UncachedKeyringMergeTest { public void testAddedKeySignature() throws Exception { final UncachedKeyRing modified; { - parcel.reset(); - parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(ringA, 1)); + resetBuilder(); + builder.addRevokeSubkey(KeyringTestingHelper.getSubkeyId(ringA, 1)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing( ringA.getEncoded(), 0); modified = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing(); } { @@ -368,7 +368,7 @@ public class UncachedKeyringMergeTest { public void testAddedUserAttributeSignature() throws Exception { final UncachedKeyRing modified; { - parcel.reset(); + resetBuilder(); Random r = new Random(); int type = r.nextInt(110)+1; @@ -376,12 +376,12 @@ public class UncachedKeyringMergeTest { new Random().nextBytes(data); WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data); - parcel.mAddUserAttribute.add(uat); + builder.addUserAttribute(uat); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing( ringA.getEncoded(), 0); modified = op.modifySecretKeyRing(secretRing, - CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing(); + CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing(); } { diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java index 88b60e5e4..221264707 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/UncachedKeyringTest.java @@ -54,16 +54,16 @@ public class UncachedKeyringTest { Security.insertProviderAt(new BouncyCastleProvider(), 1); ShadowLog.stream = System.out; - SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel(); + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L)); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L)); - parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd( + builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd( Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L)); - parcel.mAddUserIds.add("twi"); - parcel.mAddUserIds.add("pink"); + builder.addUserId("twi"); + builder.addUserId("pink"); { Random r = new Random(); int type = r.nextInt(110)+1; @@ -71,13 +71,13 @@ public class UncachedKeyringTest { new Random().nextBytes(data); WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data); - parcel.mAddUserAttribute.add(uat); + builder.addUserAttribute(uat); } // passphrase is tested in PgpKeyOperationTest, just use empty here - parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); + builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase())); PgpKeyOperation op = new PgpKeyOperation(null); - PgpEditKeyResult result = op.createSecretKeyRing(parcel); + PgpEditKeyResult result = op.createSecretKeyRing(builder.build()); staticRing = result.getRing(); staticPubRing = staticRing.extractPublicKeyRing(); From c4a4fdadff78482c6a63f9549c27fe8656b84a0a Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 23 May 2017 14:15:58 +0200 Subject: [PATCH 16/23] suppress mutable warnings for primitive arrays (we don't wanna wrap those) --- .../java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java | 1 + .../org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java | 1 + .../sufficientlysecure/keychain/service/ChangeUnlockParcel.java | 1 + .../keychain/service/DeleteKeyringParcel.java | 1 + .../keychain/service/PromoteKeyringParcel.java | 2 ++ .../sufficientlysecure/keychain/service/SaveKeyringParcel.java | 2 ++ .../keychain/service/UploadKeyringParcel.java | 1 + 7 files changed, 9 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java index 78b72e90b..ee2a6a448 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/ParcelableS2K.java @@ -44,6 +44,7 @@ public abstract class ParcelableS2K implements Parcelable { abstract int getS2kType(); abstract int getS2kHashAlgo(); abstract long getS2kItCount(); + @SuppressWarnings("mutable") abstract byte[] getS2kIV(); @Memoized 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 297f150ff..59e50aefa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java @@ -40,6 +40,7 @@ public abstract class PgpSignEncryptData implements Parcelable { @Nullable public abstract Passphrase getSymmetricPassphrase(); @Nullable + @SuppressWarnings("mutable") public abstract long[] getEncryptionMasterKeyIds(); public abstract int getCompressionAlgorithm(); @Nullable diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ChangeUnlockParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ChangeUnlockParcel.java index c7d492141..bdf054f41 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ChangeUnlockParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ChangeUnlockParcel.java @@ -31,6 +31,7 @@ public abstract class ChangeUnlockParcel implements Parcelable { @Nullable public abstract Long getMasterKeyId(); @Nullable + @SuppressWarnings("mutable") public abstract byte[] getFingerprint(); public abstract Passphrase getNewPassphrase(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java index ebc37bbc8..8b62c3c57 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/DeleteKeyringParcel.java @@ -27,6 +27,7 @@ import com.google.auto.value.AutoValue; @AutoValue public abstract class DeleteKeyringParcel implements Parcelable { + @SuppressWarnings("mutable") public abstract long[] getMasterKeyIds(); public abstract boolean isDeleteSecret(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java index 9383a7d80..c62815c7b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PromoteKeyringParcel.java @@ -30,8 +30,10 @@ import com.google.auto.value.AutoValue; public abstract class PromoteKeyringParcel implements Parcelable { public abstract long getMasterKeyId(); @Nullable + @SuppressWarnings("mutable") public abstract byte[] getCardAid(); @Nullable + @SuppressWarnings("mutable") public abstract long[] getSubKeyIds(); public static PromoteKeyringParcel createPromoteKeyringParcel(long keyRingId, byte[] cardAid, diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 2f667f7a3..06909127a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -55,6 +55,7 @@ public abstract class SaveKeyringParcel implements Parcelable { public abstract Long getMasterKeyId(); // the key fingerprint, for safety. MUST be null for a new key. @Nullable + @SuppressWarnings("mutable") public abstract byte[] getFingerprint(); public abstract List getAddUserIds(); @@ -263,6 +264,7 @@ public abstract class SaveKeyringParcel implements Parcelable { // if this is non-null, the subkey will be changed to a divert-to-card // (security token) key for the given serial number @Nullable + @SuppressWarnings("mutable") public abstract byte[] getSecurityTokenSerialNo(); public static SubkeyChange createRecertifyChange(long keyId, boolean recertify) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java index d33e18d86..b934157a1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/UploadKeyringParcel.java @@ -33,6 +33,7 @@ public abstract class UploadKeyringParcel implements Parcelable { @Nullable public abstract Long getMasterKeyId(); @Nullable + @SuppressWarnings("mutable") public abstract byte[] getUncachedKeyringBytes(); From 040a5a20069b12c093e2b70a19e37f017461608e Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 23 May 2017 14:27:01 +0200 Subject: [PATCH 17/23] use autovalue for BackupKeyringParcel --- .../keychain/operations/BackupOperation.java | 29 ++++---- .../keychain/remote/OpenPgpService.java | 3 +- .../keychain/service/BackupKeyringParcel.java | 69 +++++-------------- .../keychain/ui/BackupCodeFragment.java | 3 +- .../operations/BackupOperationTest.java | 4 +- 5 files changed, 39 insertions(+), 69 deletions(-) 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 924514cef..56c688b8f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java @@ -71,7 +71,7 @@ import org.sufficientlysecure.keychain.util.Log; * This class receives a source and/or destination of keys as input and performs * all steps for this backup. * - * @see org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter#getSelectedEntries() + * see org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter#getSelectedEntries() * For the backup operation, the input consists of a set of key ids and * either the name of a file or an output uri to write to. */ @@ -104,8 +104,8 @@ public class BackupOperation extends BaseOperation { OutputStream outputStream) { OperationLog log = new OperationLog(); - if (backupInput.mMasterKeyIds != null) { - log.add(LogType.MSG_BACKUP, 0, backupInput.mMasterKeyIds.length); + if (backupInput.getMasterKeyIds() != null) { + log.add(LogType.MSG_BACKUP, 0, backupInput.getMasterKeyIds().length); } else { log.add(LogType.MSG_BACKUP_ALL, 0); } @@ -113,7 +113,7 @@ public class BackupOperation extends BaseOperation { try { Uri plainUri = null; OutputStream plainOut; - if (backupInput.mIsEncrypted) { + if (backupInput.getIsEncrypted()) { if (cryptoInput == null) { throw new IllegalStateException("Encrypted backup must supply cryptoInput parameter"); } @@ -121,23 +121,23 @@ public class BackupOperation extends BaseOperation { plainUri = TemporaryFileProvider.createFile(mContext); plainOut = mContext.getContentResolver().openOutputStream(plainUri); } else { - if (backupInput.mOutputUri == null || outputStream != null) { + if (backupInput.getOutputUri() == null || outputStream != null) { throw new IllegalArgumentException("Unencrypted export to output stream is not supported!"); } else { - plainOut = mContext.getContentResolver().openOutputStream(backupInput.mOutputUri); + plainOut = mContext.getContentResolver().openOutputStream(backupInput.getOutputUri()); } } CountingOutputStream outStream = new CountingOutputStream(new BufferedOutputStream(plainOut)); boolean backupSuccess = exportKeysToStream( - log, backupInput.mMasterKeyIds, backupInput.mExportSecret, outStream); + log, backupInput.getMasterKeyIds(), backupInput.getExportSecret(), outStream); if (!backupSuccess) { // if there was an error, it will be in the log so we just have to return return new ExportResult(ExportResult.RESULT_ERROR, log); } - if (!backupInput.mIsEncrypted) { + if (!backupInput.getIsEncrypted()) { // log.add(LogType.MSG_EXPORT_NO_ENCRYPT, 1); log.add(LogType.MSG_BACKUP_SUCCESS, 1); return new ExportResult(ExportResult.RESULT_OK, log); @@ -172,25 +172,26 @@ public class BackupOperation extends BaseOperation { PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); data.setSymmetricPassphrase(cryptoInput.getPassphrase()); - data.setEnableAsciiArmorOutput(backupInput.mEnableAsciiArmorOutput); + data.setEnableAsciiArmorOutput(backupInput.getEnableAsciiArmorOutput()); data.setAddBackupHeader(true); PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(data.build()); InputStream inStream = mContext.getContentResolver().openInputStream(plainUri); String filename; - if (backupInput.mMasterKeyIds != null && backupInput.mMasterKeyIds.length == 1) { - filename = Constants.FILE_BACKUP_PREFIX + KeyFormattingUtils.convertKeyIdToHex(backupInput.mMasterKeyIds[0]); + long[] masterKeyIds = backupInput.getMasterKeyIds(); + if (masterKeyIds != null && masterKeyIds.length == 1) { + filename = Constants.FILE_BACKUP_PREFIX + KeyFormattingUtils.convertKeyIdToHex(masterKeyIds[0]); } else { filename = Constants.FILE_BACKUP_PREFIX + new SimpleDateFormat("yyyy-MM-dd", Locale .getDefault()).format(new Date()); } - filename += backupInput.mExportSecret ? Constants.FILE_EXTENSION_BACKUP_SECRET : Constants.FILE_EXTENSION_BACKUP_PUBLIC; + filename += backupInput.getExportSecret() ? Constants.FILE_EXTENSION_BACKUP_SECRET : Constants.FILE_EXTENSION_BACKUP_PUBLIC; InputData inputData = new InputData(inStream, exportedDataSize, filename); OutputStream outStream; - if (backupInput.mOutputUri == null) { + if (backupInput.getOutputUri() == null) { if (outputStream == null) { throw new IllegalArgumentException("If output uri is not set, outputStream must not be null!"); } @@ -199,7 +200,7 @@ public class BackupOperation extends BaseOperation { if (outputStream != null) { throw new IllegalArgumentException("If output uri is set, outputStream must null!"); } - outStream = mContext.getContentResolver().openOutputStream(backupInput.mOutputUri); + outStream = mContext.getContentResolver().openOutputStream(backupInput.getOutputUri()); } return signEncryptOperation.execute(inputParcel, CryptoInputParcel.createCryptoInputParcel(), inputData, outStream); 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 be3e76a32..e0518856e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -658,7 +658,8 @@ public class OpenPgpService extends Service { // after user interaction with RemoteBackupActivity, // the backup code is cached in CryptoInputParcelCacheService, now we can proceed - BackupKeyringParcel input = new BackupKeyringParcel(masterKeyIds, backupSecret, true, enableAsciiArmorOutput, null); + BackupKeyringParcel input = BackupKeyringParcel + .createBackupKeyringParcel(masterKeyIds, backupSecret, true, enableAsciiArmorOutput, null); BackupOperation op = new BackupOperation(this, mKeyRepository, null); ExportResult pgpResult = op.execute(input, inputParcel, outputStream); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BackupKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BackupKeyringParcel.java index b0d98ee33..a5e139d59 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BackupKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/BackupKeyringParcel.java @@ -19,61 +19,28 @@ package org.sufficientlysecure.keychain.service; + import android.net.Uri; -import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.Nullable; + +import com.google.auto.value.AutoValue; -public class BackupKeyringParcel implements Parcelable { - public Uri mCanonicalizedPublicKeyringUri; +@AutoValue +public abstract class BackupKeyringParcel implements Parcelable { + @Nullable + @SuppressWarnings("mutable") + public abstract long[] getMasterKeyIds(); + public abstract boolean getExportSecret(); + public abstract boolean getIsEncrypted(); + public abstract boolean getEnableAsciiArmorOutput(); + @Nullable + public abstract Uri getOutputUri(); - public final boolean mExportSecret; - public final boolean mIsEncrypted; - public final boolean mEnableAsciiArmorOutput; - public final long mMasterKeyIds[]; - public final Uri mOutputUri; - - public BackupKeyringParcel(long[] masterKeyIds, boolean exportSecret, boolean isEncrypted, boolean enableAsciiArmorOutput, Uri outputUri) { - mMasterKeyIds = masterKeyIds; - mExportSecret = exportSecret; - mOutputUri = outputUri; - mIsEncrypted = isEncrypted; - mEnableAsciiArmorOutput = enableAsciiArmorOutput; + public static BackupKeyringParcel createBackupKeyringParcel(long[] masterKeyIds, boolean exportSecret, + boolean isEncrypted, boolean enableAsciiArmorOutput, Uri outputUri) { + return new AutoValue_BackupKeyringParcel( + masterKeyIds, exportSecret, isEncrypted, enableAsciiArmorOutput, outputUri); } - - protected BackupKeyringParcel(Parcel in) { - mCanonicalizedPublicKeyringUri = (Uri) in.readValue(Uri.class.getClassLoader()); - mExportSecret = in.readByte() != 0x00; - mOutputUri = (Uri) in.readValue(Uri.class.getClassLoader()); - mMasterKeyIds = in.createLongArray(); - mIsEncrypted = in.readInt() != 0; - mEnableAsciiArmorOutput = in.readInt() != 0; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeValue(mCanonicalizedPublicKeyringUri); - dest.writeByte((byte) (mExportSecret ? 0x01 : 0x00)); - dest.writeValue(mOutputUri); - dest.writeLongArray(mMasterKeyIds); - dest.writeInt(mIsEncrypted ? 1 : 0); - dest.writeInt(mEnableAsciiArmorOutput ? 1 : 0); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public BackupKeyringParcel createFromParcel(Parcel in) { - return new BackupKeyringParcel(in); - } - - @Override - public BackupKeyringParcel[] newArray(int size) { - return new BackupKeyringParcel[size]; - } - }; } \ No newline at end of file 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 3aee1542d..c06e66c8a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java @@ -606,7 +606,8 @@ public class BackupCodeFragment extends CryptoOperationFragment Date: Tue, 23 May 2017 15:04:04 +0200 Subject: [PATCH 18/23] use autovalue for InputDataParcel and SignEncryptParcel --- .../operations/BenchmarkOperation.java | 3 +- .../operations/SignEncryptOperation.java | 9 +- .../keychain/pgp/SignEncryptParcel.java | 111 ++++++++---------- .../keychain/service/InputDataParcel.java | 67 ++--------- .../keychain/ui/DecryptListFragment.java | 2 +- .../keychain/ui/EncryptFilesFragment.java | 15 +-- .../keychain/ui/EncryptTextFragment.java | 14 +-- .../keychain/pgp/InputDataOperationTest.java | 4 +- 8 files changed, 79 insertions(+), 146 deletions(-) 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 5abfe463b..9fed50b60 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java @@ -86,8 +86,7 @@ public class BenchmarkOperation extends BaseOperation { PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); data.setSymmetricPassphrase(passphrase); data.setSymmetricEncryptionAlgorithm(OpenKeychainSymmetricKeyAlgorithmTags.AES_128); - SignEncryptParcel input = new SignEncryptParcel(data.build()); - input.setBytes(buf); + SignEncryptParcel input = SignEncryptParcel.createSignEncryptParcel(data.build(), buf); encryptResult = op.execute(input, CryptoInputParcel.createCryptoInputParcel()); log.add(encryptResult, 1); log.add(LogType.MSG_BENCH_ENC_TIME, 2, diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java index d0ab2a117..07e491a0c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java @@ -26,7 +26,6 @@ import android.content.Context; import android.net.Uri; import android.support.annotation.NonNull; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; @@ -36,13 +35,11 @@ import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel; import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.SecurityTokenSignOperationsBuilder; -import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -76,8 +73,6 @@ public class SignEncryptOperation extends BaseOperation { SecurityTokenSignOperationsBuilder pendingInputBuilder = null; - PgpSignEncryptData data = input.getData(); - do { if (checkCancelled()) { log.add(LogType.MSG_OPERATION_CANCELLED, 0); @@ -86,7 +81,7 @@ public class SignEncryptOperation extends BaseOperation { PgpSignEncryptOperation op = new PgpSignEncryptOperation(mContext, mKeyRepository, new ProgressScaler(mProgressable, 100 * count / total, 100 * ++count / total, 100), mCancelled); - PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(input.getData()); + PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(input.getSignEncryptData()); if (inputBytes != null) { inputParcel.setInputBytes(inputBytes); } else { @@ -106,7 +101,7 @@ public class SignEncryptOperation extends BaseOperation { } if (pendingInputBuilder == null) { pendingInputBuilder = new SecurityTokenSignOperationsBuilder(requiredInput.mSignatureTime, - data.getSignatureMasterKeyId(), data.getSignatureSubKeyId()); + requiredInput.getMasterKeyId(), requiredInput.getSubKeyId()); } pendingInputBuilder.addAll(requiredInput); } else if (!result.success()) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java index a86bec1ba..741aa3f97 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java @@ -19,14 +19,17 @@ package org.sufficientlysecure.keychain.pgp; import android.net.Uri; -import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import com.google.auto.value.AutoValue; + + /** * This parcel stores the input of one or more PgpSignEncrypt operations. * All operations will use the same general parameters, differing only in @@ -39,83 +42,65 @@ import java.util.List; * - Once the output uris are empty, there must be exactly one input (uri xor bytes) * left, which will be returned in a byte array as part of the result parcel. */ -public class SignEncryptParcel implements Parcelable { +@AutoValue +public abstract class SignEncryptParcel implements Parcelable { + public abstract PgpSignEncryptData getSignEncryptData(); + public abstract List getInputUris(); + public abstract List getOutputUris(); + @SuppressWarnings("mutable") + @Nullable + public abstract byte[] getBytes(); - private PgpSignEncryptData data; - - public ArrayList mInputUris = new ArrayList<>(); - public ArrayList mOutputUris = new ArrayList<>(); - public byte[] mBytes; - - public SignEncryptParcel(PgpSignEncryptData data) { - this.data = data; - } - - public SignEncryptParcel(Parcel src) { - mInputUris = src.createTypedArrayList(Uri.CREATOR); - mOutputUris = src.createTypedArrayList(Uri.CREATOR); - mBytes = src.createByteArray(); - - data = src.readParcelable(getClass().getClassLoader()); - } public boolean isIncomplete() { - return mInputUris.size() > mOutputUris.size(); + List inputUris = getInputUris(); + List outputUris = getOutputUris(); + if (inputUris == null || outputUris == null) { + throw new IllegalStateException("Invalid operation for bytes-backed SignEncryptParcel!"); + } + return inputUris.size() > outputUris.size(); } - public byte[] getBytes() { - return mBytes; + + public static SignEncryptParcel createSignEncryptParcel(PgpSignEncryptData signEncryptData, byte[] bytes) { + // noinspection unchecked, it's ok for the empty list + return new AutoValue_SignEncryptParcel(signEncryptData, Collections.EMPTY_LIST, Collections.EMPTY_LIST, bytes); } - public void setBytes(byte[] bytes) { - mBytes = bytes; + public static Builder builder(SignEncryptParcel signEncryptParcel) { + return new Builder(signEncryptParcel.getSignEncryptData()) + .addInputUris(signEncryptParcel.getInputUris()) + .addOutputUris(signEncryptParcel.getOutputUris()); } - public List getInputUris() { - return Collections.unmodifiableList(mInputUris); + public static Builder builder(PgpSignEncryptData signEncryptData) { + return new Builder(signEncryptData); } - public void addInputUris(Collection inputUris) { - mInputUris.addAll(inputUris); - } - public List getOutputUris() { - return Collections.unmodifiableList(mOutputUris); - } + public static class Builder { + private final PgpSignEncryptData signEncryptData; + private ArrayList inputUris = new ArrayList<>(); + private ArrayList outputUris = new ArrayList<>(); - public void addOutputUris(ArrayList outputUris) { - mOutputUris.addAll(outputUris); - } - - public void setData(PgpSignEncryptData data) { - this.data = data; - } - - public PgpSignEncryptData getData() { - return data; - } - - @Override - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeTypedList(mInputUris); - dest.writeTypedList(mOutputUris); - dest.writeByteArray(mBytes); - - dest.writeParcelable(data, 0); - } - - public static final Creator CREATOR = new Creator() { - public SignEncryptParcel createFromParcel(final Parcel source) { - return new SignEncryptParcel(source); + private Builder(PgpSignEncryptData signEncryptData) { + this.signEncryptData = signEncryptData; } - public SignEncryptParcel[] newArray(final int size) { - return new SignEncryptParcel[size]; + public SignEncryptParcel build() { + return new AutoValue_SignEncryptParcel(signEncryptData, + Collections.unmodifiableList(inputUris), + Collections.unmodifiableList(outputUris), + null); } - }; + public Builder addOutputUris(Collection outputUris) { + this.outputUris.addAll(outputUris); + return this; + } + public Builder addInputUris(Collection inputUris) { + this.inputUris.addAll(inputUris); + return this; + } + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/InputDataParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/InputDataParcel.java index 6affd3334..30475d634 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/InputDataParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/InputDataParcel.java @@ -17,65 +17,24 @@ package org.sufficientlysecure.keychain.service; -import android.net.Uri; -import android.os.Parcel; -import android.os.Parcelable; +import android.net.Uri; +import android.os.Parcelable; +import android.support.annotation.Nullable; + +import com.google.auto.value.AutoValue; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; -public class InputDataParcel implements Parcelable { +@AutoValue +public abstract class InputDataParcel implements Parcelable { + public abstract Uri getInputUri(); + @Nullable + public abstract PgpDecryptVerifyInputParcel getDecryptInput(); + public abstract boolean getMimeDecode(); // TODO static value - ditch this? - private Uri mInputUri; - - private PgpDecryptVerifyInputParcel mDecryptInput; - private boolean mMimeDecode = true; // TODO default to false - - public InputDataParcel(Uri inputUri, PgpDecryptVerifyInputParcel decryptInput) { - mInputUri = inputUri; - mDecryptInput = decryptInput; + public static InputDataParcel createInputDataParcel(Uri inputUri, PgpDecryptVerifyInputParcel decryptInput) { + return new AutoValue_InputDataParcel(inputUri, decryptInput, true); } - - InputDataParcel(Parcel source) { - // we do all of those here, so the PgpSignEncryptInput class doesn't have to be parcelable - mInputUri = source.readParcelable(getClass().getClassLoader()); - mDecryptInput = source.readParcelable(getClass().getClassLoader()); - mMimeDecode = source.readInt() != 0; - } - - public Uri getInputUri() { - return mInputUri; - } - - public PgpDecryptVerifyInputParcel getDecryptInput() { - return mDecryptInput; - } - - public boolean getMimeDecode() { - return mMimeDecode; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mInputUri, 0); - dest.writeParcelable(mDecryptInput, 0); - dest.writeInt(mMimeDecode ? 1 : 0); - } - - public static final Creator CREATOR = new Creator() { - public InputDataParcel createFromParcel(final Parcel source) { - return new InputDataParcel(source); - } - - public InputDataParcel[] newArray(final int size) { - return new InputDataParcel[size]; - } - }; - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index 4a5e2563c..f2fc4d0e5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -639,7 +639,7 @@ public class DecryptListFragment PgpDecryptVerifyInputParcel decryptInput = new PgpDecryptVerifyInputParcel() .setAllowSymmetricDecryption(true); - return new InputDataParcel(mCurrentInputUri, decryptInput); + return InputDataParcel.createInputDataParcel(mCurrentInputUri, decryptInput); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index 224368749..7fe8f1f95 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -577,12 +577,10 @@ public class EncryptFilesFragment } public SignEncryptParcel createOperationInput() { - SignEncryptParcel actionsParcel = getCachedActionsParcel(); // we have three cases here: nothing cached, cached except output, fully cached if (actionsParcel == null) { - // clear output uris for now, they will be created by prepareOutputStreams later mOutputUris = null; @@ -593,7 +591,6 @@ public class EncryptFilesFragment } cacheActionsParcel(actionsParcel); - } // if it's incomplete, prepare output streams @@ -606,9 +603,10 @@ public class EncryptFilesFragment } } - actionsParcel.addOutputUris(mOutputUris); + actionsParcel = SignEncryptParcel.builder(actionsParcel) + .addOutputUris(mOutputUris) + .build(); cacheActionsParcel(actionsParcel); - } return actionsParcel; @@ -675,10 +673,9 @@ public class EncryptFilesFragment } - SignEncryptParcel parcel = new SignEncryptParcel(data.build()); - parcel.addInputUris(mFilesAdapter.getAsArrayList()); - - return parcel; + SignEncryptParcel.Builder builder = SignEncryptParcel.builder(data.build()); + builder.addInputUris(mFilesAdapter.getAsArrayList()); + return builder.build(); } private Intent createSendIntent() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index 6c80ee2f2..acb248566 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -17,6 +17,11 @@ package org.sufficientlysecure.keychain.ui; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; @@ -49,10 +54,6 @@ import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Preferences; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - public class EncryptTextFragment extends CachingCryptoOperationFragment { @@ -286,10 +287,7 @@ public class EncryptTextFragment data.setSymmetricPassphrase(passphrase); } - SignEncryptParcel parcel = new SignEncryptParcel(data.build()); - parcel.setBytes(mMessage.getBytes()); - - return parcel; + return SignEncryptParcel.createSignEncryptParcel(data.build(), mMessage.getBytes()); } private void copyToClipboard(SignEncryptResult result) { 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 96518f125..4cd2d472a 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java @@ -128,7 +128,7 @@ public class InputDataOperationTest { InputDataOperation op = new InputDataOperation(spyApplication, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - InputDataParcel input = new InputDataParcel(fakeInputUri, null); + InputDataParcel input = InputDataParcel.createInputDataParcel(fakeInputUri, null); InputDataResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel()); @@ -308,7 +308,7 @@ public class InputDataOperationTest { InputDataOperation op = new InputDataOperation(spyApplication, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - InputDataParcel input = new InputDataParcel(FAKE_CONTENT_INPUT_URI_1, null); + InputDataParcel input = InputDataParcel.createInputDataParcel(FAKE_CONTENT_INPUT_URI_1, null); return op.execute(input, CryptoInputParcel.createCryptoInputParcel()); } From 7e6cac331775996f174195ec13714223b0f161be Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 23 May 2017 16:52:48 +0200 Subject: [PATCH 19/23] use autovalue for PgpSignEncryptInputParcel, move allowedKeys into PgpSignEncryptData --- .../keychain/operations/BackupOperation.java | 16 +-- .../operations/SignEncryptOperation.java | 9 +- .../keychain/pgp/PgpSignEncryptData.java | 13 +++ .../pgp/PgpSignEncryptInputParcel.java | 109 +++--------------- .../keychain/pgp/PgpSignEncryptOperation.java | 30 +++-- .../keychain/remote/OpenPgpService.java | 14 +-- .../keychain/pgp/PgpEncryptDecryptTest.java | 50 +++----- 7 files changed, 82 insertions(+), 159 deletions(-) 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 56c688b8f..2e28af1ab 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java @@ -170,18 +170,19 @@ public class BackupOperation extends BaseOperation { throws FileNotFoundException { PgpSignEncryptOperation signEncryptOperation = new PgpSignEncryptOperation(mContext, mKeyRepository, mProgressable, mCancelled); - PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); - data.setSymmetricPassphrase(cryptoInput.getPassphrase()); - data.setEnableAsciiArmorOutput(backupInput.getEnableAsciiArmorOutput()); - data.setAddBackupHeader(true); - PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(data.build()); + PgpSignEncryptData.Builder builder = PgpSignEncryptData.builder(); + builder.setSymmetricPassphrase(cryptoInput.getPassphrase()); + builder.setEnableAsciiArmorOutput(backupInput.getEnableAsciiArmorOutput()); + builder.setAddBackupHeader(true); + PgpSignEncryptData pgpSignEncryptData = builder.build(); InputStream inStream = mContext.getContentResolver().openInputStream(plainUri); String filename; long[] masterKeyIds = backupInput.getMasterKeyIds(); if (masterKeyIds != null && masterKeyIds.length == 1) { - filename = Constants.FILE_BACKUP_PREFIX + KeyFormattingUtils.convertKeyIdToHex(masterKeyIds[0]); + filename = Constants.FILE_BACKUP_PREFIX + KeyFormattingUtils.convertKeyIdToHex( + masterKeyIds[0]); } else { filename = Constants.FILE_BACKUP_PREFIX + new SimpleDateFormat("yyyy-MM-dd", Locale .getDefault()).format(new Date()); @@ -203,7 +204,8 @@ public class BackupOperation extends BaseOperation { outStream = mContext.getContentResolver().openOutputStream(backupInput.getOutputUri()); } - return signEncryptOperation.execute(inputParcel, CryptoInputParcel.createCryptoInputParcel(), inputData, outStream); + return signEncryptOperation.execute( + pgpSignEncryptData, 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/SignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java index 07e491a0c..88cfbb649 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java @@ -81,13 +81,14 @@ public class SignEncryptOperation extends BaseOperation { PgpSignEncryptOperation op = new PgpSignEncryptOperation(mContext, mKeyRepository, new ProgressScaler(mProgressable, 100 * count / total, 100 * ++count / total, 100), mCancelled); - PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(input.getSignEncryptData()); + PgpSignEncryptInputParcel inputParcel; if (inputBytes != null) { - inputParcel.setInputBytes(inputBytes); + inputParcel = PgpSignEncryptInputParcel.createForBytes( + input.getSignEncryptData(), outputUris.pollFirst(), inputBytes); } else { - inputParcel.setInputUri(inputUris.removeFirst()); + inputParcel = PgpSignEncryptInputParcel.createForInputUri( + input.getSignEncryptData(), outputUris.pollFirst(), inputUris.removeFirst()); } - inputParcel.setOutputUri(outputUris.pollFirst()); PgpSignEncryptResult result = op.execute(inputParcel, cryptoInput); results.add(result); 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 59e50aefa..4de8c4090 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java @@ -19,6 +19,11 @@ package org.sufficientlysecure.keychain.pgp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import android.os.Parcelable; import android.support.annotation.Nullable; @@ -42,6 +47,8 @@ public abstract class PgpSignEncryptData implements Parcelable { @Nullable @SuppressWarnings("mutable") public abstract long[] getEncryptionMasterKeyIds(); + @Nullable + public abstract List getAllowedSigningKeyIds(); public abstract int getCompressionAlgorithm(); @Nullable public abstract String getVersionHeader(); @@ -86,6 +93,12 @@ public abstract class PgpSignEncryptData implements Parcelable { public abstract Builder setCleartextSignature(boolean isCleartextSignature); public abstract Builder setDetachedSignature(boolean isDetachedSignature); public abstract Builder setHiddenRecipients(boolean isHiddenRecipients); + + abstract Builder setAllowedSigningKeyIds(List allowedSigningKeyIds); + public Builder setAllowedSigningKeyIds(Collection allowedSigningKeyIds) { + setAllowedSigningKeyIds(Collections.unmodifiableList(new ArrayList<>(allowedSigningKeyIds))); + return this; + } } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java index f5f998d25..aef423729 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java @@ -18,104 +18,33 @@ package org.sufficientlysecure.keychain.pgp; + import android.net.Uri; -import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.Nullable; -import java.util.HashSet; +import com.google.auto.value.AutoValue; -public class PgpSignEncryptInputParcel implements Parcelable { +@AutoValue +public abstract class PgpSignEncryptInputParcel implements Parcelable { + public abstract PgpSignEncryptData getData(); + @Nullable + public abstract Uri getOutputUri(); + @Nullable + public abstract Uri getInputUri(); + @Nullable + @SuppressWarnings("mutable") + public abstract byte[] getInputBytes(); - private PgpSignEncryptData data; - - private Uri mInputUri; - private Uri mOutputUri; - private byte[] mInputBytes; - - private HashSet mAllowedKeyIds; - - public PgpSignEncryptInputParcel(PgpSignEncryptData data) { - this.data = data; + public static PgpSignEncryptInputParcel createForBytes( + PgpSignEncryptData signEncryptData, Uri outputUri, byte[] inputBytes) { + return new AutoValue_PgpSignEncryptInputParcel(signEncryptData, outputUri, null, inputBytes); } - PgpSignEncryptInputParcel(Parcel source) { - mInputUri = source.readParcelable(getClass().getClassLoader()); - mOutputUri = source.readParcelable(getClass().getClassLoader()); - mInputBytes = source.createByteArray(); - - data = source.readParcelable(getClass().getClassLoader()); - - mAllowedKeyIds = (HashSet) source.readSerializable(); + public static PgpSignEncryptInputParcel createForInputUri( + PgpSignEncryptData signEncryptData, Uri outputUri, Uri inputUri) { + return new AutoValue_PgpSignEncryptInputParcel(signEncryptData, outputUri, inputUri, null); } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mInputUri, 0); - dest.writeParcelable(mOutputUri, 0); - dest.writeByteArray(mInputBytes); - - data.writeToParcel(dest, 0); - - dest.writeSerializable(mAllowedKeyIds); - } - - public void setInputBytes(byte[] inputBytes) { - this.mInputBytes = inputBytes; - } - - byte[] getInputBytes() { - return mInputBytes; - } - - public PgpSignEncryptInputParcel setInputUri(Uri uri) { - mInputUri = uri; - return this; - } - - Uri getInputUri() { - return mInputUri; - } - - public PgpSignEncryptInputParcel setOutputUri(Uri uri) { - mOutputUri = uri; - return this; - } - - Uri getOutputUri() { - return mOutputUri; - } - - public void setData(PgpSignEncryptData data) { - this.data = data; - } - - public PgpSignEncryptData getData() { - return data; - } - - HashSet getAllowedKeyIds() { - return mAllowedKeyIds; - } - - public void setAllowedKeyIds(HashSet allowedKeyIds) { - mAllowedKeyIds = allowedKeyIds; - } - - public static final Creator CREATOR = new Creator() { - public PgpSignEncryptInputParcel createFromParcel(final Parcel source) { - return new PgpSignEncryptInputParcel(source); - } - - public PgpSignEncryptInputParcel[] newArray(final int size) { - return new PgpSignEncryptInputParcel[size]; - } - }; - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index bb022699e..9a7071388 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -32,6 +32,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.SignatureException; +import java.util.Collection; import java.util.Date; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -148,7 +149,7 @@ public class PgpSignEncryptOperation extends BaseOperation 0) || data.getSymmetricPassphrase() != null); @@ -221,15 +220,13 @@ public class PgpSignEncryptOperation extends BaseOperation allowedSigningKeyIds = data.getAllowedSigningKeyIds(); + if (allowedSigningKeyIds != null && !allowedSigningKeyIds.contains(signingMasterKeyId)) { + // this key is in our db, but NOT allowed! + log.add(LogType.MSG_PSE_ERROR_KEY_NOT_ALLOWED, indent + 1); + return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_KEY_DISALLOWED, log); } - // Make sure key is not expired or revoked if (signingKeyRing.isExpired() || signingKeyRing.isRevoked() || signingKey.isExpired() || signingKey.isRevoked()) { @@ -572,8 +569,7 @@ public class PgpSignEncryptOperation extends BaseOperation Date: Tue, 23 May 2017 17:46:29 +0200 Subject: [PATCH 20/23] fix handling of algorithm tags in parcels --- .../operations/BenchmarkOperation.java | 3 +- .../pgp/PgpDecryptVerifyOperation.java | 13 ++-- .../keychain/pgp/PgpSignEncryptData.java | 26 ++++---- .../keychain/pgp/PgpSignEncryptOperation.java | 61 +++++++++---------- .../keychain/remote/OpenPgpService.java | 23 +++---- .../keychain/ui/EncryptFilesFragment.java | 12 +--- .../keychain/ui/EncryptTextFragment.java | 14 +---- 7 files changed, 65 insertions(+), 87 deletions(-) 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 9fed50b60..a73ccb15e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java @@ -41,7 +41,6 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat import org.sufficientlysecure.keychain.operations.results.SignEncryptResult; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation; -import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags; import org.sufficientlysecure.keychain.pgp.PgpSignEncryptData; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; @@ -85,7 +84,7 @@ public class BenchmarkOperation extends BaseOperation { new ProgressScaler(mProgressable, i*(50/numRepeats), (i+1)*(50/numRepeats), 100), mCancelled); PgpSignEncryptData.Builder data = PgpSignEncryptData.builder(); data.setSymmetricPassphrase(passphrase); - data.setSymmetricEncryptionAlgorithm(OpenKeychainSymmetricKeyAlgorithmTags.AES_128); + data.setSymmetricEncryptionAlgorithm(SymmetricKeyAlgorithmTags.AES_128); SignEncryptParcel input = SignEncryptParcel.createSignEncryptParcel(data.build(), buf); encryptResult = op.execute(input, CryptoInputParcel.createCryptoInputParcel()); log.add(encryptResult, 1); 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 99a7afcdb..f7f31f903 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java @@ -361,10 +361,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation getAllowedSigningKeyIds(); - public abstract int getCompressionAlgorithm(); @Nullable public abstract String getVersionHeader(); + public abstract int getCompressionAlgorithm(); + public abstract int getSignatureHashAlgorithm(); + public abstract int getSymmetricEncryptionAlgorithm(); + public abstract boolean isEnableAsciiArmorOutput(); public abstract boolean isCleartextSignature(); public abstract boolean isDetachedSignature(); @@ -61,16 +64,16 @@ public abstract class PgpSignEncryptData implements Parcelable { public static Builder builder() { return new AutoValue_PgpSignEncryptData.Builder() - .setCompressionAlgorithm(CompressionAlgorithmTags.UNCOMPRESSED) - .setSymmetricEncryptionAlgorithm(PgpSecurityConstants.DEFAULT_SYMMETRIC_ALGORITHM) .setSignatureMasterKeyId(Constants.key.none) - .setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM) .setAdditionalEncryptId(Constants.key.none) .setEnableAsciiArmorOutput(false) .setCleartextSignature(false) .setDetachedSignature(false) .setAddBackupHeader(false) - .setHiddenRecipients(false); + .setHiddenRecipients(false) + .setCompressionAlgorithm(OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) + .setSignatureHashAlgorithm(OpenKeychainHashAlgorithmTags.USE_DEFAULT) + .setSymmetricEncryptionAlgorithm(OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT); } @AutoValue.Builder @@ -79,15 +82,16 @@ public abstract class PgpSignEncryptData implements Parcelable { public abstract Builder setCharset(String charset); public abstract Builder setAdditionalEncryptId(long additionalEncryptId); - public abstract Builder setSignatureHashAlgorithm(int signatureHashAlgorithm); public abstract Builder setSignatureSubKeyId(Long signatureSubKeyId); public abstract Builder setSignatureMasterKeyId(long signatureMasterKeyId); - public abstract Builder setSymmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm); public abstract Builder setSymmetricPassphrase(Passphrase symmetricPassphrase); public abstract Builder setEncryptionMasterKeyIds(long[] encryptionMasterKeyIds); - public abstract Builder setCompressionAlgorithm(int compressionAlgorithm); public abstract Builder setVersionHeader(String versionHeader); + public abstract Builder setCompressionAlgorithm(int compressionAlgorithm); + public abstract Builder setSignatureHashAlgorithm(int signatureHashAlgorithm); + public abstract Builder setSymmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm); + public abstract Builder setAddBackupHeader(boolean isAddBackupHeader); public abstract Builder setEnableAsciiArmorOutput(boolean enableAsciiArmorOutput); public abstract Builder setCleartextSignature(boolean isCleartextSignature); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index 9a7071388..52f5710a0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -61,6 +61,9 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.LogTyp import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; import org.sufficientlysecure.keychain.operations.results.SignEncryptResult; +import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags; +import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainHashAlgorithmTags; +import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeyWritableRepository; @@ -178,13 +181,13 @@ public class PgpSignEncryptOperation extends BaseOperation 0) || data.getSymmetricPassphrase() != null); - boolean enableCompression = (data.getCompressionAlgorithm() != CompressionAlgorithmTags.UNCOMPRESSED); - Log.d(Constants.TAG, "enableSignature:" + enableSignature - + "\nenableEncryption:" + enableEncryption - + "\nenableCompression:" + enableCompression - + "\nenableAsciiArmorOutput:" + data.isEnableAsciiArmorOutput() - + "\nisHiddenRecipients:" + data.isHiddenRecipients()); + int compressionAlgorithm = data.getCompressionAlgorithm(); + if (compressionAlgorithm == OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) { + compressionAlgorithm = PgpSecurityConstants.DEFAULT_COMPRESSION_ALGORITHM; + } + + Log.d(Constants.TAG, data.toString()); ArmoredOutputStream armorOut = null; OutputStream out; @@ -299,12 +302,12 @@ public class PgpSignEncryptOperation extends BaseOperation Date: Tue, 23 May 2017 17:46:44 +0200 Subject: [PATCH 21/23] use suitable signing subkey if none provided --- .../keychain/pgp/PgpSignEncryptOperation.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index 52f5710a0..bfb2036cc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -65,6 +65,7 @@ import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainComp import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainHashAlgorithmTags; import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeyWritableRepository; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; @@ -217,11 +218,19 @@ public class PgpSignEncryptOperation extends BaseOperation allowedSigningKeyIds = data.getAllowedSigningKeyIds(); if (allowedSigningKeyIds != null && !allowedSigningKeyIds.contains(signingMasterKeyId)) { From 79af393847bee6632350f96f3122d1c061fbc6a3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 23 May 2017 21:47:21 +0200 Subject: [PATCH 22/23] use autovalue for PgpDecryptVerifyInputParcel --- .../operations/BenchmarkOperation.java | 7 +- .../operations/InputDataOperation.java | 15 +- .../KeybaseVerificationOperation.java | 4 +- .../pgp/PgpDecryptVerifyInputParcel.java | 187 +++++------------- .../keychain/remote/OpenPgpService.java | 8 +- .../keychain/ui/DecryptListFragment.java | 4 +- .../operations/BackupOperationTest.java | 6 +- .../keychain/pgp/PgpEncryptDecryptTest.java | 70 ++++--- .../keychain/provider/InteropTest.java | 2 +- 9 files changed, 119 insertions(+), 184 deletions(-) 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 a73ccb15e..3d6a46a14 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java @@ -103,9 +103,10 @@ public class BenchmarkOperation extends BaseOperation { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(mContext, mKeyRepository, 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, CryptoInputParcel.createCryptoInputParcel(passphrase)); + PgpDecryptVerifyInputParcel.Builder builder = PgpDecryptVerifyInputParcel.builder() + .setInputBytes(encryptResult.getResultBytes()) + .setAllowSymmetricDecryption(true); + decryptResult = op.execute(builder.build(), 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/InputDataOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/InputDataOperation.java index 3ad764b74..93fd3e796 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/InputDataOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/InputDataOperation.java @@ -103,10 +103,12 @@ public class InputDataOperation extends BaseOperation { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(mContext, mKeyRepository, mProgressable); - decryptInput.setInputUri(input.getInputUri()); - currentInputUri = TemporaryFileProvider.createFile(mContext); - decryptInput.setOutputUri(currentInputUri); + + decryptInput = decryptInput.toBuilder() + .setInputUri(input.getInputUri()) + .setOutputUri(currentInputUri) + .build(); decryptResult = op.execute(decryptInput, cryptoInput); if (decryptResult.isPending()) { @@ -264,9 +266,10 @@ public class InputDataOperation extends BaseOperation { } detachedSig.close(); - PgpDecryptVerifyInputParcel decryptInput = new PgpDecryptVerifyInputParcel(); - decryptInput.setInputUri(uncheckedSignedDataUri); - decryptInput.setDetachedSignature(detachedSig.toByteArray()); + PgpDecryptVerifyInputParcel decryptInput = PgpDecryptVerifyInputParcel.builder() + .setInputUri(uncheckedSignedDataUri) + .setDetachedSignature(detachedSig.toByteArray()) + .build(); PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(mContext, mKeyRepository, mProgressable); 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 89c48ad1b..c7d527eab 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/KeybaseVerificationOperation.java @@ -152,7 +152,9 @@ public class KeybaseVerificationOperation extends BaseOperation mAllowedKeyIds; - private boolean mDecryptMetadataOnly; - private byte[] mDetachedSignature; - private String mRequiredSignerFingerprint; - private String mSenderAddress; +@AutoValue +public abstract class PgpDecryptVerifyInputParcel implements Parcelable { + @Nullable + @SuppressWarnings("mutable") + abstract byte[] getInputBytes(); - public PgpDecryptVerifyInputParcel() { + @Nullable + abstract Uri getInputUri(); + @Nullable + abstract Uri getOutputUri(); + + abstract boolean isAllowSymmetricDecryption(); + abstract boolean isDecryptMetadataOnly(); + + @Nullable + abstract List getAllowedKeyIds(); + @Nullable + @SuppressWarnings("mutable") + abstract byte[] getDetachedSignature(); + @Nullable + abstract String getSenderAddress(); + + public abstract Builder toBuilder(); + + public static Builder builder() { + return new AutoValue_PgpDecryptVerifyInputParcel.Builder() + .setAllowSymmetricDecryption(false) + .setDecryptMetadataOnly(false); } - public PgpDecryptVerifyInputParcel(Uri inputUri, Uri outputUri) { - mInputUri = inputUri; - mOutputUri = outputUri; - } + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder setInputBytes(byte[] inputBytes); + public abstract Builder setInputUri(Uri inputUri); + public abstract Builder setOutputUri(Uri outputUri); - public PgpDecryptVerifyInputParcel(byte[] inputBytes) { - mInputBytes = inputBytes; - } + public abstract Builder setAllowSymmetricDecryption(boolean allowSymmetricDecryption); + public abstract Builder setDecryptMetadataOnly(boolean decryptMetadataOnly); + public abstract Builder setDetachedSignature(byte[] detachedSignature); + public abstract Builder setSenderAddress(String senderAddress); - PgpDecryptVerifyInputParcel(Parcel source) { - // we do all of those here, so the PgpSignEncryptInput class doesn't have to be parcelable - mInputUri = source.readParcelable(getClass().getClassLoader()); - mOutputUri = source.readParcelable(getClass().getClassLoader()); - mInputBytes = source.createByteArray(); + public abstract Builder setAllowedKeyIds(List allowedKeyIds); + abstract List getAllowedKeyIds(); - mAllowSymmetricDecryption = source.readInt() != 0; - mAllowedKeyIds = (HashSet) source.readSerializable(); - mDecryptMetadataOnly = source.readInt() != 0; - mDetachedSignature = source.createByteArray(); - mRequiredSignerFingerprint = source.readString(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mInputUri, 0); - dest.writeParcelable(mOutputUri, 0); - dest.writeByteArray(mInputBytes); - - dest.writeInt(mAllowSymmetricDecryption ? 1 : 0); - dest.writeSerializable(mAllowedKeyIds); - dest.writeInt(mDecryptMetadataOnly ? 1 : 0); - dest.writeByteArray(mDetachedSignature); - dest.writeString(mRequiredSignerFingerprint); - } - - byte[] getInputBytes() { - return mInputBytes; - } - - public PgpDecryptVerifyInputParcel setInputUri(Uri uri) { - mInputUri = uri; - return this; - } - - Uri getInputUri() { - return mInputUri; - } - - public PgpDecryptVerifyInputParcel setOutputUri(Uri uri) { - mOutputUri = uri; - return this; - } - - Uri getOutputUri() { - return mOutputUri; - } - - boolean isAllowSymmetricDecryption() { - return mAllowSymmetricDecryption; - } - - public PgpDecryptVerifyInputParcel setAllowSymmetricDecryption(boolean allowSymmetricDecryption) { - mAllowSymmetricDecryption = allowSymmetricDecryption; - return this; - } - - HashSet getAllowedKeyIds() { - return mAllowedKeyIds; - } - - public PgpDecryptVerifyInputParcel setAllowedKeyIds(HashSet allowedKeyIds) { - mAllowedKeyIds = allowedKeyIds; - return this; - } - - boolean isDecryptMetadataOnly() { - return mDecryptMetadataOnly; - } - - public PgpDecryptVerifyInputParcel setDecryptMetadataOnly(boolean decryptMetadataOnly) { - mDecryptMetadataOnly = decryptMetadataOnly; - return this; - } - - byte[] getDetachedSignature() { - return mDetachedSignature; - } - - public PgpDecryptVerifyInputParcel setDetachedSignature(byte[] detachedSignature) { - mDetachedSignature = detachedSignature; - return this; - } - - public PgpDecryptVerifyInputParcel setSenderAddress(String senderAddress) { - mSenderAddress = senderAddress; - return this; - } - - public String getSenderAddress() { - return mSenderAddress; - } - - String getRequiredSignerFingerprint() { - return mRequiredSignerFingerprint; - } - - public PgpDecryptVerifyInputParcel setRequiredSignerFingerprint(String requiredSignerFingerprint) { - mRequiredSignerFingerprint = requiredSignerFingerprint; - return this; - } - - public static final Creator CREATOR = new Creator() { - public PgpDecryptVerifyInputParcel createFromParcel(final Parcel source) { - return new PgpDecryptVerifyInputParcel(source); + abstract PgpDecryptVerifyInputParcel autoBuild(); + public PgpDecryptVerifyInputParcel build() { + List allowedKeyIds = getAllowedKeyIds(); + if (allowedKeyIds != null) { + setAllowedKeyIds(Collections.unmodifiableList(allowedKeyIds)); + } + return autoBuild(); } - - public PgpDecryptVerifyInputParcel[] newArray(final int size) { - return new PgpDecryptVerifyInputParcel[size]; - } - }; + } } - 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 444214932..42d0b1490 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -22,6 +22,7 @@ package org.sufficientlysecure.keychain.remote; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; @@ -367,12 +368,13 @@ public class OpenPgpService extends Service { // allow only private keys associated with accounts of this app // no support for symmetric encryption - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel() + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() .setAllowSymmetricDecryption(false) - .setAllowedKeyIds(getAllowedKeyIds()) + .setAllowedKeyIds(new ArrayList<>(getAllowedKeyIds())) .setDecryptMetadataOnly(decryptMetadataOnly) .setDetachedSignature(detachedSignature) - .setSenderAddress(senderAddress); + .setSenderAddress(senderAddress) + .build(); DecryptVerifyResult pgpResult = op.execute(input, cryptoInput, inputData, outputStream); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index f2fc4d0e5..84b49ca3f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -637,9 +637,9 @@ public class DecryptListFragment return null; } - PgpDecryptVerifyInputParcel decryptInput = new PgpDecryptVerifyInputParcel() + PgpDecryptVerifyInputParcel.Builder decryptInput = PgpDecryptVerifyInputParcel.builder() .setAllowSymmetricDecryption(true); - return InputDataParcel.createInputDataParcel(mCurrentInputUri, decryptInput); + return InputDataParcel.createInputDataParcel(mCurrentInputUri, decryptInput.build()); } 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 a0a4ab61e..8d926be3d 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/BackupOperationTest.java @@ -327,8 +327,10 @@ public class BackupOperationTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(outStream.toByteArray()); - input.setAllowSymmetricDecryption(true); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setAllowSymmetricDecryption(true) + .setInputBytes(outStream.toByteArray()) + .build(); { DecryptVerifyResult result = 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 ee72582e9..85559cc4e 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -25,7 +25,6 @@ import java.io.PrintStream; import java.security.Security; import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; import java.util.Iterator; import org.apache.tools.ant.util.StringUtils; @@ -199,8 +198,9 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - input.setAllowSymmetricDecryption(true); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setAllowSymmetricDecryption(true) + .build(); DecryptVerifyResult result = op.execute( input, CryptoInputParcel.createCryptoInputParcel(mSymmetricPassphrase), data, out); @@ -229,8 +229,9 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - input.setAllowSymmetricDecryption(true); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setAllowSymmetricDecryption(true) + .build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(new Passphrase(new String(mSymmetricPassphrase.getCharArray()) + "x")), data, out); @@ -251,8 +252,9 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - input.setAllowSymmetricDecryption(true); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setAllowSymmetricDecryption(true) + .build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); @@ -272,8 +274,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - input.setAllowSymmetricDecryption(false); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); @@ -323,7 +324,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("verification must succeed", result.success()); @@ -382,7 +383,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("verification must succeed", result.success()); @@ -438,8 +439,9 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - input.setDetachedSignature(detachedSignature); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setDetachedSignature(detachedSignature) + .build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("verification must succeed", result.success()); @@ -494,7 +496,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("decryption with provided passphrase must succeed", result.success()); @@ -523,7 +525,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); CryptoInputParcel cryptoInput = result.getCachedCryptoInputParcel(); @@ -547,7 +549,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( null, mStaticRing1.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertFalse("decryption with no passphrase must return pending", result.success()); @@ -628,7 +630,9 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(ciphertext); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setInputBytes(ciphertext) + .build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1)); Assert.assertTrue("decryption must succeed", result.success()); @@ -651,7 +655,9 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, KeyWritableRepository.createDatabaseReadWriteInteractor(RuntimeEnvironment.application), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(ciphertext); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setInputBytes(ciphertext) + .build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1)); Assert.assertTrue("decryption must succeed", result.success()); @@ -757,7 +763,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success()); @@ -780,14 +786,15 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); // allow only the second to decrypt - HashSet allowed = new HashSet<>(); + ArrayList allowed = new ArrayList<>(); allowed.add(mStaticRing2.getMasterKeyId()); // provide passphrase for the second, and check that the first is never asked for! PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - input.setAllowedKeyIds(allowed); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setAllowedKeyIds(allowed) + .build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed for allowed key", result.success()); @@ -809,8 +816,9 @@ public class PgpEncryptDecryptTest { // provide passphrase for the second, and check that the first is never asked for! PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); - input.setAllowedKeyIds(new HashSet()); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder() + .setAllowedKeyIds(new ArrayList()) + .build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertFalse("decryption must fail if no key allowed", result.success()); @@ -832,7 +840,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed", result.success()); @@ -886,7 +894,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase1, mStaticRing1.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed for the first key", result.success()); @@ -913,7 +921,7 @@ public class PgpEncryptDecryptTest { PgpDecryptVerifyOperation op = operationWithFakePassphraseCache( mKeyPhrase2, mStaticRing2.getMasterKeyId(), null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); Assert.assertTrue("decryption with cached passphrase must succeed", result.success()); @@ -968,7 +976,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); Assert.assertTrue("decryption with provided passphrase must succeed", result.success()); @@ -996,7 +1004,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); @@ -1019,7 +1027,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out); @@ -1040,7 +1048,7 @@ public class PgpEncryptDecryptTest { InputData data = new InputData(in, in.available()); PgpDecryptVerifyOperation op = operationWithFakePassphraseCache(null, null, null); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); DecryptVerifyResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(), data, out); 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 1220d1a8d..98571ff3f 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/provider/InteropTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/provider/InteropTest.java @@ -143,7 +143,7 @@ public class InteropTest { Passphrase pass = new Passphrase(config.getString("passphrase")); PgpDecryptVerifyOperation op = makeOperation(base.toString(), pass, decrypt, verify); - PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(); + PgpDecryptVerifyInputParcel input = PgpDecryptVerifyInputParcel.builder().build(); CryptoInputParcel cip = CryptoInputParcel.createCryptoInputParcel(pass); DecryptVerifyResult result = op.execute(input, cip, data, out); byte[] plaintext = config.getString("textcontent").getBytes("utf-8"); From eb892741c5bbae61462f8fc513f871da29862ae6 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 24 May 2017 00:21:30 +0200 Subject: [PATCH 23/23] skip license check for adapter lib (it will stay the same as parent) --- dependencyci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dependencyci.yml b/dependencyci.yml index 79bc92b02..cacea11a5 100644 --- a/dependencyci.yml +++ b/dependencyci.yml @@ -12,3 +12,6 @@ platform: # see https://github.com/mikepenz/Android-Iconics/blob/develop/LICENSE tests: unlicensed: skip + 'com.ryanharter.auto.value:auto-value-parcel-adapter': + tests: + unlicensed: skip