use autovalue for PgpSignEncryptInputParcel, move allowedKeys into PgpSignEncryptData

This commit is contained in:
Vincent Breitmoser 2017-05-23 16:52:48 +02:00
parent 9d485dfe9f
commit 7e6cac3317
7 changed files with 82 additions and 159 deletions

View file

@ -170,18 +170,19 @@ public class BackupOperation extends BaseOperation<BackupKeyringParcel> {
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<BackupKeyringParcel> {
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) {

View file

@ -81,13 +81,14 @@ public class SignEncryptOperation extends BaseOperation<SignEncryptParcel> {
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);

View file

@ -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<Long> 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<Long> allowedSigningKeyIds);
public Builder setAllowedSigningKeyIds(Collection<Long> allowedSigningKeyIds) {
setAllowedSigningKeyIds(Collections.unmodifiableList(new ArrayList<>(allowedSigningKeyIds)));
return this;
}
}
}

View file

@ -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<Long> 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<Long>) 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<Long> getAllowedKeyIds() {
return mAllowedKeyIds;
}
public void setAllowedKeyIds(HashSet<Long> allowedKeyIds) {
mAllowedKeyIds = allowedKeyIds;
}
public static final Creator<PgpSignEncryptInputParcel> CREATOR = new Creator<PgpSignEncryptInputParcel>() {
public PgpSignEncryptInputParcel createFromParcel(final Parcel source) {
return new PgpSignEncryptInputParcel(source);
}
public PgpSignEncryptInputParcel[] newArray(final int size) {
return new PgpSignEncryptInputParcel[size];
}
};
}

View file

@ -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<PgpSignEncryptInputPa
}
}
PgpSignEncryptResult result = executeInternal(input, cryptoInput, inputData, outStream);
PgpSignEncryptResult result = executeInternal(input.getData(), cryptoInput, inputData, outStream);
if (outStream instanceof ByteArrayOutputStream) {
byte[] outputData = ((ByteArrayOutputStream) outStream).toByteArray();
result.setOutputBytes(outputData);
@ -158,24 +159,22 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa
}
@NonNull
public PgpSignEncryptResult execute(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput,
InputData inputData, OutputStream outputStream) {
return executeInternal(input, cryptoInput, inputData, outputStream);
public PgpSignEncryptResult execute(PgpSignEncryptData data, CryptoInputParcel cryptoInput,
InputData inputData, OutputStream outputStream) {
return executeInternal(data, cryptoInput, inputData, outputStream);
}
/**
* Signs and/or encrypts data based on parameters of class
*/
private PgpSignEncryptResult executeInternal(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput,
InputData inputData, OutputStream outputStream) {
private PgpSignEncryptResult executeInternal(PgpSignEncryptData data, CryptoInputParcel cryptoInput,
InputData inputData, OutputStream outputStream) {
int indent = 0;
OperationLog log = new OperationLog();
log.add(LogType.MSG_PSE, indent);
indent += 1;
PgpSignEncryptData data = input.getData();
boolean enableSignature = data.getSignatureMasterKeyId() != Constants.key.none;
boolean enableEncryption = ((data.getEncryptionMasterKeyIds() != null && data.getEncryptionMasterKeyIds().length > 0)
|| data.getSymmetricPassphrase() != null);
@ -221,15 +220,13 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa
mKeyRepository.getCanonicalizedSecretKeyRing(signingMasterKeyId);
signingKey = signingKeyRing.getSecretKey(data.getSignatureSubKeyId());
if (input.getAllowedKeyIds() != null) {
if (!input.getAllowedKeyIds().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);
}
Collection<Long> 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<PgpSignEncryptInputPa
}
opTime = System.currentTimeMillis() - startTime;
Log.d(Constants.TAG, "sign/encrypt time taken: " + String.format("%.2f",
opTime / 1000.0) + "s");
Log.d(Constants.TAG, "sign/encrypt time taken: " + String.format("%.2f", opTime / 1000.0) + "s");
// closing outputs
// NOTE: closing needs to be done in the correct order!

View file

@ -58,7 +58,6 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptData;
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel;
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.SecurityProblem;
@ -138,10 +137,7 @@ public class OpenPgpService extends Service {
throw new Exception("signing subkey not found!", e);
}
}
PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData.build());
pseInput.setAllowedKeyIds(getAllowedKeyIds());
pgpData.setAllowedSigningKeyIds(getAllowedKeyIds());
// Get Input- and OutputStream from ParcelFileDescriptor
if (!cleartextSign) {
@ -164,7 +160,7 @@ public class OpenPgpService extends Service {
// execute PGP operation!
PgpSignEncryptOperation pse = new PgpSignEncryptOperation(this, mKeyRepository, null);
PgpSignEncryptResult pgpResult = pse.execute(pseInput, inputParcel, inputData, outputStream);
PgpSignEncryptResult pgpResult = pse.execute(pgpData.build(), inputParcel, inputData, outputStream);
if (pgpResult.isPending()) {
RequiredInputParcel requiredInput = pgpResult.getRequiredInputParcel();
@ -259,9 +255,7 @@ public class OpenPgpService extends Service {
return result;
}
pgpData.setEncryptionMasterKeyIds(keyIdResult.getKeyIds());
PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData.build());
pseInput.setAllowedKeyIds(getAllowedKeyIds());
pgpData.setAllowedSigningKeyIds(getAllowedKeyIds());
CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
if (inputParcel == null) {
@ -279,7 +273,7 @@ public class OpenPgpService extends Service {
// execute PGP operation!
PgpSignEncryptOperation op = new PgpSignEncryptOperation(this, mKeyRepository, null);
PgpSignEncryptResult pgpResult = op.execute(pseInput, inputParcel, inputData, outputStream);
PgpSignEncryptResult pgpResult = op.execute(pgpData.build(), inputParcel, inputData, outputStream);
if (pgpResult.isPending()) {
RequiredInputParcel requiredInput = pgpResult.getRequiredInputParcel();

View file

@ -183,9 +183,8 @@ public class PgpEncryptDecryptTest {
pgpData.setSymmetricEncryptionAlgorithm(
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128);
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(b, CryptoInputParcel.createCryptoInputParcel(new Date()),
data, out);
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(new Date()), data, out);
Assert.assertTrue("encryption must succeed", result.success());
@ -310,9 +309,8 @@ public class PgpEncryptDecryptTest {
pgpData.setCleartextSignature(false);
pgpData.setDetachedSignature(false);
PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out);
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out);
Assert.assertTrue("signing must succeed", result.success());
ciphertext = out.toByteArray();
@ -367,9 +365,8 @@ public class PgpEncryptDecryptTest {
pgpData.setEnableAsciiArmorOutput(true);
pgpData.setDetachedSignature(false);
PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out);
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out);
Assert.assertTrue("signing must succeed", result.success());
ciphertext = out.toByteArray();
@ -427,9 +424,8 @@ public class PgpEncryptDecryptTest {
pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1));
pgpData.setDetachedSignature(true);
PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out);
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(mKeyPhrase1), data, out);
Assert.assertTrue("signing must succeed", result.success());
detachedSignature = result.getDetachedSignature();
@ -483,9 +479,8 @@ public class PgpEncryptDecryptTest {
pgpData.setSymmetricEncryptionAlgorithm(
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128);
PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(new Date()),
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(new Date()),
data, out);
Assert.assertTrue("encryption must succeed", result.success());
@ -586,9 +581,8 @@ public class PgpEncryptDecryptTest {
pgpData.setSymmetricEncryptionAlgorithm(
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128);
PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(new Date()),
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(new Date()),
data, out);
Assert.assertTrue("encryption must succeed", result.success());
@ -700,9 +694,8 @@ public class PgpEncryptDecryptTest {
pgpData.setSymmetricEncryptionAlgorithm(
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128);
PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(input, CryptoInputParcel.createCryptoInputParcel(new Date()),
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(new Date()),
data, out);
Assert.assertTrue("encryption must succeed", result.success());
@ -748,9 +741,8 @@ public class PgpEncryptDecryptTest {
pgpData.setSymmetricEncryptionAlgorithm(
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128);
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(b, CryptoInputParcel.createCryptoInputParcel(new Date()),
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(new Date()),
data, out);
Assert.assertTrue("encryption must succeed", result.success());
@ -879,9 +871,7 @@ public class PgpEncryptDecryptTest {
pgpData.setSymmetricEncryptionAlgorithm(
PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128);
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(b,
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1), data, out);
Assert.assertTrue("encryption must succeed", result.success());
@ -964,10 +954,8 @@ public class PgpEncryptDecryptTest {
pgpData.setEnableAsciiArmorOutput(true);
pgpData.setCharset("iso-2022-jp");
PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData.build());
PgpSignEncryptResult result = op.execute(b, CryptoInputParcel.createCryptoInputParcel(new Date()),
data, out);
PgpSignEncryptResult result = op.execute(pgpData.build(),
CryptoInputParcel.createCryptoInputParcel(new Date()), data, out);
Assert.assertTrue("encryption must succeed", result.success());
ciphertext = out.toByteArray();