diff options
Diffstat (limited to 'OpenKeychain/src')
13 files changed, 564 insertions, 391 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 7c2f9d6b2..0ea7e7e59 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java @@ -47,6 +47,7 @@ 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.pgp.CanonicalizedKeyRing; +import org.sufficientlysecure.keychain.pgp.PgpSignEncryptData;  import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel;  import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;  import org.sufficientlysecure.keychain.pgp.Progressable; @@ -151,10 +152,11 @@ public class BackupOperation extends BaseOperation<BackupKeyringParcel> {              PgpSignEncryptOperation pseOp = new PgpSignEncryptOperation(mContext, mProviderHelper, mProgressable, mCancelled); -            PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(); -            inputParcel.setSymmetricPassphrase(cryptoInput.getPassphrase()); -            inputParcel.setEnableAsciiArmorOutput(true); -            inputParcel.setAddBackupHeader(true); +            PgpSignEncryptData data = new PgpSignEncryptData(); +            data.setSymmetricPassphrase(cryptoInput.getPassphrase()); +            data.setEnableAsciiArmorOutput(true); +            data.setAddBackupHeader(true); +            PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(data);              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 52deffeab..a179fa66a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java @@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;  import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;  import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;  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;  import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -83,9 +84,10 @@ public class BenchmarkOperation extends BaseOperation<BenchmarkInputParcel> {              SignEncryptOperation op =                      new SignEncryptOperation(mContext, mProviderHelper,                              new ProgressScaler(mProgressable, i*(50/numRepeats), (i+1)*(50/numRepeats), 100), mCancelled); -            SignEncryptParcel input = new SignEncryptParcel(); -            input.setSymmetricPassphrase(passphrase); -            input.setSymmetricEncryptionAlgorithm(OpenKeychainSymmetricKeyAlgorithmTags.AES_128); +            PgpSignEncryptData data = new PgpSignEncryptData(); +            data.setSymmetricPassphrase(passphrase); +            data.setSymmetricEncryptionAlgorithm(OpenKeychainSymmetricKeyAlgorithmTags.AES_128); +            SignEncryptParcel input = new SignEncryptParcel(data);              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 5bca372cb..dedc03553 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java @@ -18,15 +18,6 @@  package org.sufficientlysecure.keychain.operations; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicBoolean; -  import android.content.Context;  import android.net.Uri;  import android.support.annotation.NonNull; @@ -36,6 +27,8 @@ 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.PgpSignEncryptData; +import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel;  import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;  import org.sufficientlysecure.keychain.pgp.Progressable;  import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; @@ -45,16 +38,18 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;  import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;  import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.SecurityTokenSignOperationsBuilder;  import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType; -import org.sufficientlysecure.keychain.util.FileHelper; -import org.sufficientlysecure.keychain.util.InputData;  import org.sufficientlysecure.keychain.util.Log;  import org.sufficientlysecure.keychain.util.ProgressScaler; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +  /**   * This is a high-level operation, which encapsulates one or more sign/encrypt   * operations, using URIs or byte arrays as input and output. - * + * <p/>   * This operation is fail-fast: If any sign/encrypt sub-operation fails or returns   * a pending result, it will terminate.   */ @@ -75,20 +70,20 @@ public class SignEncryptOperation extends BaseOperation<SignEncryptParcel> {          ArrayDeque<Uri> inputUris = new ArrayDeque<>(input.getInputUris());          ArrayDeque<Uri> outputUris = new ArrayDeque<>(input.getOutputUris());          byte[] inputBytes = input.getBytes(); -        byte[] outputBytes = null;          int total = inputBytes != null ? 1 : inputUris.size(), count = 0;          ArrayList<PgpSignEncryptResult> results = new ArrayList<>();          SecurityTokenSignOperationsBuilder pendingInputBuilder = null; +        PgpSignEncryptData data = input.getData();          // if signing subkey has not explicitly been set, get first usable subkey capable of signing -        if (input.getSignatureMasterKeyId() != Constants.key.none -                && input.getSignatureSubKeyId() == null) { +        if (data.getSignatureMasterKeyId() != Constants.key.none +                && data.getSignatureSubKeyId() == null) {              try {                  long signKeyId = mProviderHelper.getCachedPublicKeyRing( -                        input.getSignatureMasterKeyId()).getSecretSignId(); -                input.setSignatureSubKeyId(signKeyId); +                        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); @@ -96,61 +91,22 @@ public class SignEncryptOperation extends BaseOperation<SignEncryptParcel> {          }          do { -              if (checkCancelled()) {                  log.add(LogType.MSG_OPERATION_CANCELLED, 0);                  return new SignEncryptResult(SignEncryptResult.RESULT_CANCELLED, log, results);              } -            InputData inputData; -            { -                if (inputBytes != null) { -                    log.add(LogType.MSG_SE_INPUT_BYTES, 1); -                    InputStream is = new ByteArrayInputStream(inputBytes); -                    inputData = new InputData(is, inputBytes.length); -                    inputBytes = null; -                } else { -                    if (inputUris.isEmpty()) { -                        log.add(LogType.MSG_SE_ERROR_NO_INPUT, 1); -                        return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results); -                    } - -                    log.add(LogType.MSG_SE_INPUT_URI, 1); -                    Uri uri = inputUris.removeFirst(); -                    try { -                        InputStream is = FileHelper.openInputStreamSafe(mContext.getContentResolver(), uri); -                        long fileSize = FileHelper.getFileSize(mContext, uri, 0); -                        String filename = FileHelper.getFilename(mContext, uri); -                        inputData = new InputData(is, fileSize, filename); -                    } catch (FileNotFoundException e) { -                        log.add(LogType.MSG_SE_ERROR_INPUT_URI_NOT_FOUND, 1); -                        return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results); -                    } -                } -            } - -            OutputStream outStream; -            { -                if (!outputUris.isEmpty()) { -                    try { -                        Uri outputUri = outputUris.removeFirst(); -                        outStream = mContext.getContentResolver().openOutputStream(outputUri); -                    } catch (FileNotFoundException e) { -                        log.add(LogType.MSG_SE_ERROR_OUTPUT_URI_NOT_FOUND, 1); -                        return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results); -                    } -                } else { -                    if (outputBytes != null) { -                        log.add(LogType.MSG_SE_ERROR_TOO_MANY_INPUTS, 1); -                        return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results); -                    } -                    outStream = new ByteArrayOutputStream(); -                } -            } -              PgpSignEncryptOperation op = new PgpSignEncryptOperation(mContext, mProviderHelper,                      new ProgressScaler(mProgressable, 100 * count / total, 100 * ++count / total, 100), mCancelled); -            PgpSignEncryptResult result = op.execute(input, cryptoInput, inputData, outStream); +            PgpSignEncryptInputParcel inputParcel = new PgpSignEncryptInputParcel(input.getData()); +            if (inputBytes != null) { +                inputParcel.setInputBytes(inputBytes); +            } else { +                inputParcel.setInputUri(inputUris.removeFirst()); +            } +            inputParcel.setOutputUri(outputUris.pollFirst()); + +            PgpSignEncryptResult result = op.execute(inputParcel, cryptoInput);              results.add(result);              log.add(result, 2); @@ -162,17 +118,12 @@ public class SignEncryptOperation extends BaseOperation<SignEncryptParcel> {                  }                  if (pendingInputBuilder == null) {                      pendingInputBuilder = new SecurityTokenSignOperationsBuilder(requiredInput.mSignatureTime, -                            input.getSignatureMasterKeyId(), input.getSignatureSubKeyId()); +                            data.getSignatureMasterKeyId(), data.getSignatureSubKeyId());                  }                  pendingInputBuilder.addAll(requiredInput);              } else if (!result.success()) {                  return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);              } - -            if (outStream instanceof ByteArrayOutputStream) { -                outputBytes = ((ByteArrayOutputStream) outStream).toByteArray(); -            } -          } while (!inputUris.isEmpty());          if (pendingInputBuilder != null && !pendingInputBuilder.isEmpty()) { @@ -184,8 +135,8 @@ public class SignEncryptOperation extends BaseOperation<SignEncryptParcel> {          }          log.add(LogType.MSG_SE_SUCCESS, 1); -        return new SignEncryptResult(SignEncryptResult.RESULT_OK, log, results, outputBytes); - +        return new SignEncryptResult(SignEncryptResult.RESULT_OK, log, results, +                results.get(results.size() - 1).getOutputBytes());      }  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index d3d962808..be736d785 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -710,15 +710,15 @@ public abstract class OperationResult implements Parcelable {          // signencrypt          MSG_SE (LogLevel.START, R.string.msg_se), -        MSG_SE_INPUT_BYTES (LogLevel.INFO, R.string.msg_se_input_bytes), -        MSG_SE_INPUT_URI (LogLevel.INFO, R.string.msg_se_input_uri),          MSG_SE_ERROR_NO_INPUT (LogLevel.DEBUG, R.string.msg_se_error_no_input), -        MSG_SE_ERROR_INPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_input_uri_not_found), -        MSG_SE_ERROR_OUTPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_output_uri_not_found),          MSG_SE_ERROR_TOO_MANY_INPUTS (LogLevel.ERROR, R.string.msg_se_error_too_many_inputs),          MSG_SE_SUCCESS (LogLevel.OK, R.string.msg_se_success),          // pgpsignencrypt +        MSG_PSE_INPUT_BYTES (LogLevel.INFO, R.string.msg_se_input_bytes), +        MSG_PSE_INPUT_URI (LogLevel.INFO, R.string.msg_se_input_uri), +        MSG_PSE_ERROR_INPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_input_uri_not_found), +        MSG_PSE_ERROR_OUTPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_output_uri_not_found),          MSG_PSE_ASYMMETRIC (LogLevel.INFO, R.string.msg_pse_asymmetric),          MSG_PSE_COMPRESSING (LogLevel.DEBUG, R.string.msg_pse_compressing),          MSG_PSE_ENCRYPTING (LogLevel.DEBUG, R.string.msg_pse_encrypting), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java index c4f66b950..2b9f149ed 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java @@ -25,6 +25,8 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;  public class PgpSignEncryptResult extends InputPendingResult { +    byte[] mOutputBytes; +      byte[] mDetachedSignature;      public long mOperationTime;      // this is the micalg parameter used in PGP/MIME, see RFC3156: @@ -53,6 +55,14 @@ public class PgpSignEncryptResult extends InputPendingResult {          mDetachedSignature = source.readInt() != 0 ? source.createByteArray() : null;      } +    public void setOutputBytes(byte[] outputBytes) { +        mOutputBytes = outputBytes; +    } + +    public byte[] getOutputBytes() { +        return mOutputBytes; +    } +      public int describeContents() {          return 0;      } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java new file mode 100644 index 000000000..c4e569d24 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.com> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.pgp; + +import android.os.Parcel; +import android.os.Parcelable; + +import org.bouncycastle.bcpg.CompressionAlgorithmTags; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.util.Passphrase; + + +public class PgpSignEncryptData implements Parcelable { + +    protected String mVersionHeader = null; +    protected boolean mEnableAsciiArmorOutput = false; +    protected int mCompressionAlgorithm = CompressionAlgorithmTags.UNCOMPRESSED; +    protected long[] mEncryptionMasterKeyIds = null; +    protected Passphrase mSymmetricPassphrase = null; +    protected int mSymmetricEncryptionAlgorithm = PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT; +    protected long mSignatureMasterKeyId = Constants.key.none; +    protected Long mSignatureSubKeyId = null; +    protected int mSignatureHashAlgorithm = PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT; +    protected long mAdditionalEncryptId = Constants.key.none; +    protected String mCharset; +    protected boolean mCleartextSignature; +    protected boolean mDetachedSignature = false; +    protected boolean mHiddenRecipients = false; +    protected boolean mIntegrityProtected = true; +    protected boolean mAddBackupHeader = false; + +    public PgpSignEncryptData(){ +    } + +    PgpSignEncryptData(Parcel source) { +        ClassLoader loader = getClass().getClassLoader(); + +        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; +        mIntegrityProtected = source.readInt() == 1; +        mAddBackupHeader = source.readInt() == 1; +    } + +    @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(mIntegrityProtected ? 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 boolean isIntegrityProtected() { +        return mIntegrityProtected; +    } + +    /** +     * Only use for testing! Never disable integrity protection! +     */ +    public PgpSignEncryptData setIntegrityProtected(boolean integrityProtected) { +        this.mIntegrityProtected = integrityProtected; +        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<PgpSignEncryptData> CREATOR = new Creator<PgpSignEncryptData>() { +        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/PgpSignEncryptInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java index 8eae92e63..8e0c7ab40 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java @@ -18,58 +18,29 @@  package org.sufficientlysecure.keychain.pgp; -import org.bouncycastle.bcpg.CompressionAlgorithmTags; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.util.Passphrase; - +import android.net.Uri;  import android.os.Parcel;  import android.os.Parcelable;  public class PgpSignEncryptInputParcel implements Parcelable { -    protected String mVersionHeader = null; -    protected boolean mEnableAsciiArmorOutput = false; -    protected int mCompressionAlgorithm = CompressionAlgorithmTags.UNCOMPRESSED; -    protected long[] mEncryptionMasterKeyIds = null; -    protected Passphrase mSymmetricPassphrase = null; -    protected int mSymmetricEncryptionAlgorithm = PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT; -    protected long mSignatureMasterKeyId = Constants.key.none; -    protected Long mSignatureSubKeyId = null; -    protected int mSignatureHashAlgorithm = PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT; -    protected long mAdditionalEncryptId = Constants.key.none; -    protected String mCharset; -    protected boolean mCleartextSignature; -    protected boolean mDetachedSignature = false; -    protected boolean mHiddenRecipients = false; -    protected boolean mIntegrityProtected = true; -    protected boolean mAddBackupHeader = false; +    private PgpSignEncryptData data; -    public PgpSignEncryptInputParcel() { +    private Uri mInputUri; +    private Uri mOutputUri; +    private byte[] mInputBytes; +    public PgpSignEncryptInputParcel(PgpSignEncryptData data) { +        this.data = data;      }      PgpSignEncryptInputParcel(Parcel source) { +        mInputUri = source.readParcelable(getClass().getClassLoader()); +        mOutputUri = source.readParcelable(getClass().getClassLoader()); +        mInputBytes = source.createByteArray(); -        ClassLoader loader = getClass().getClassLoader(); - -        // we do all of those here, so the PgpSignEncryptInput class doesn't have to be parcelable -        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; -        mIntegrityProtected = source.readInt() == 1; -        mAddBackupHeader = source.readInt() == 1; +        data = source.readParcelable(getClass().getClassLoader());      }      @Override @@ -79,173 +50,45 @@ public class PgpSignEncryptInputParcel implements Parcelable {      @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(mIntegrityProtected ? 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 PgpSignEncryptInputParcel setAdditionalEncryptId(long additionalEncryptId) { -        mAdditionalEncryptId = additionalEncryptId; -        return this; -    } - -    public int getSignatureHashAlgorithm() { -        return mSignatureHashAlgorithm; -    } - -    public PgpSignEncryptInputParcel setSignatureHashAlgorithm(int signatureHashAlgorithm) { -        mSignatureHashAlgorithm = signatureHashAlgorithm; -        return this; -    } - -    public Long getSignatureSubKeyId() { -        return mSignatureSubKeyId; -    } - -    public PgpSignEncryptInputParcel setSignatureSubKeyId(long signatureSubKeyId) { -        mSignatureSubKeyId = signatureSubKeyId; -        return this; -    } - -    public long getSignatureMasterKeyId() { -        return mSignatureMasterKeyId; -    } - -    public PgpSignEncryptInputParcel setSignatureMasterKeyId(long signatureMasterKeyId) { -        mSignatureMasterKeyId = signatureMasterKeyId; -        return this; -    } +        dest.writeParcelable(mInputUri, 0); +        dest.writeParcelable(mOutputUri, 0); +        dest.writeByteArray(mInputBytes); -    public int getSymmetricEncryptionAlgorithm() { -        return mSymmetricEncryptionAlgorithm; +        data.writeToParcel(dest, 0);      } -    public PgpSignEncryptInputParcel setSymmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) { -        mSymmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; -        return this; +    public void setInputBytes(byte[] inputBytes) { +        this.mInputBytes = inputBytes;      } -    public Passphrase getSymmetricPassphrase() { -        return mSymmetricPassphrase; +    byte[] getInputBytes() { +        return mInputBytes;      } -    public PgpSignEncryptInputParcel setSymmetricPassphrase(Passphrase symmetricPassphrase) { -        mSymmetricPassphrase = symmetricPassphrase; +    public PgpSignEncryptInputParcel setInputUri(Uri uri) { +        mInputUri = uri;          return this;      } -    public long[] getEncryptionMasterKeyIds() { -        return mEncryptionMasterKeyIds; +    Uri getInputUri() { +        return mInputUri;      } -    public PgpSignEncryptInputParcel setEncryptionMasterKeyIds(long[] encryptionMasterKeyIds) { -        mEncryptionMasterKeyIds = encryptionMasterKeyIds; +    public PgpSignEncryptInputParcel setOutputUri(Uri uri) { +        mOutputUri = uri;          return this;      } -    public int getCompressionAlgorithm() { -        return mCompressionAlgorithm; -    } - -    public PgpSignEncryptInputParcel setCompressionAlgorithm(int compressionAlgorithm) { -        mCompressionAlgorithm = compressionAlgorithm; -        return this; -    } - -    public boolean isEnableAsciiArmorOutput() { -        return mEnableAsciiArmorOutput; -    } - -    public String getVersionHeader() { -        return mVersionHeader; -    } - -    public PgpSignEncryptInputParcel setVersionHeader(String versionHeader) { -        mVersionHeader = versionHeader; -        return this; -    } - -    public PgpSignEncryptInputParcel setEnableAsciiArmorOutput(boolean enableAsciiArmorOutput) { -        mEnableAsciiArmorOutput = enableAsciiArmorOutput; -        return this; -    } - -    public PgpSignEncryptInputParcel setCleartextSignature(boolean cleartextSignature) { -        this.mCleartextSignature = cleartextSignature; -        return this; -    } - -    public boolean isCleartextSignature() { -        return mCleartextSignature; -    } - -    public PgpSignEncryptInputParcel setDetachedSignature(boolean detachedSignature) { -        this.mDetachedSignature = detachedSignature; -        return this; -    } - -    public boolean isDetachedSignature() { -        return mDetachedSignature; -    } - -    public PgpSignEncryptInputParcel setHiddenRecipients(boolean hiddenRecipients) { -        this.mHiddenRecipients = hiddenRecipients; -        return this; -    } - -    public boolean isIntegrityProtected() { -        return mIntegrityProtected; -    } - -    /** -     * Only use for testing! Never disable integrity protection! -     */ -    public PgpSignEncryptInputParcel setIntegrityProtected(boolean integrityProtected) { -        this.mIntegrityProtected = integrityProtected; -        return this; -    } - -    public PgpSignEncryptInputParcel setAddBackupHeader(boolean addBackupHeader) { -        this.mAddBackupHeader = addBackupHeader; -        return this; +    Uri getOutputUri() { +        return mOutputUri;      } -    public boolean isAddBackupHeader() { -        return mAddBackupHeader; +    public void setData(PgpSignEncryptData data) { +        this.data = data;      } -    public boolean isHiddenRecipients() { -        return mHiddenRecipients; +    public PgpSignEncryptData getData() { +        return data;      }      public static final Creator<PgpSignEncryptInputParcel> CREATOR = new Creator<PgpSignEncryptInputParcel>() { 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 0bb6419eb..7a1d99927 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -20,6 +20,7 @@  package org.sufficientlysecure.keychain.pgp;  import android.content.Context; +import android.net.Uri;  import android.os.Parcelable;  import android.support.annotation.NonNull; @@ -39,16 +40,19 @@ import org.bouncycastle.openpgp.operator.jcajce.PGPUtil;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.operations.BaseOperation; +import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;  import org.sufficientlysecure.keychain.operations.results.OperationResult;  import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;  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.exception.PgpGeneralException;  import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;  import org.sufficientlysecure.keychain.provider.ProviderHelper;  import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;  import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;  import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.FileHelper;  import org.sufficientlysecure.keychain.util.InputData;  import org.sufficientlysecure.keychain.util.Log;  import org.sufficientlysecure.keychain.util.Passphrase; @@ -57,7 +61,9 @@ 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; @@ -83,7 +89,7 @@ import java.util.concurrent.atomic.AtomicBoolean;   * @see org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult   * @see org.sufficientlysecure.keychain.operations.SignEncryptOperation   */ -public class PgpSignEncryptOperation extends BaseOperation { +public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputParcel> {      private static byte[] NEW_LINE; @@ -105,16 +111,65 @@ public class PgpSignEncryptOperation extends BaseOperation {      @NonNull      @Override -    // TODO this is horrible, refactor ASAP!! -    public OperationResult execute(Parcelable input, CryptoInputParcel cryptoInput) { -        return null; +    public PgpSignEncryptResult execute(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput) { +        OperationLog log = new OperationLog(); + +        InputData inputData; +        { +            if (input.getInputBytes() != null) { +                log.add(LogType.MSG_PSE_INPUT_BYTES, 1); +                InputStream is = new ByteArrayInputStream(input.getInputBytes()); +                inputData = new InputData(is, input.getInputBytes().length); +            } else { +                log.add(LogType.MSG_PSE_INPUT_URI, 1); +                Uri uri = input.getInputUri(); +                try { +                    InputStream is = FileHelper.openInputStreamSafe(mContext.getContentResolver(), uri); +                    long fileSize = FileHelper.getFileSize(mContext, uri, 0); +                    String filename = FileHelper.getFilename(mContext, uri); +                    inputData = new InputData(is, fileSize, filename); +                } catch (FileNotFoundException e) { +                    log.add(LogType.MSG_PSE_ERROR_INPUT_URI_NOT_FOUND, 1); +                    return new PgpSignEncryptResult(SignEncryptResult.RESULT_ERROR, log); +                } +            } +        } + +        OutputStream outStream; +        { +            if (input.getOutputUri() != null) { +                try { +                    Uri outputUri = input.getOutputUri(); +                    outStream = mContext.getContentResolver().openOutputStream(outputUri); +                } catch (FileNotFoundException e) { +                    log.add(LogType.MSG_PSE_ERROR_OUTPUT_URI_NOT_FOUND, 1); +                    return new PgpSignEncryptResult(SignEncryptResult.RESULT_ERROR, log); +                } +            } else { +                outStream = new ByteArrayOutputStream(); +            } +        } + +        PgpSignEncryptResult result = executeInternal(input, cryptoInput, inputData, outStream); +        if (outStream instanceof ByteArrayOutputStream) { +            byte[] outputData = ((ByteArrayOutputStream) outStream).toByteArray(); +            result.setOutputBytes(outputData); +        } + +        return result; +    } + +    @NonNull +    public PgpSignEncryptResult execute(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput, +                                        InputData inputData, OutputStream outputStream) { +        return executeInternal(input, cryptoInput, inputData, outputStream);      }      /**       * Signs and/or encrypts data based on parameters of class       */ -    public PgpSignEncryptResult execute(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput, -                                     InputData inputData, OutputStream outputStream) { +    private PgpSignEncryptResult executeInternal(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput, +                                                 InputData inputData, OutputStream outputStream) {          int indent = 0;          OperationLog log = new OperationLog(); @@ -122,36 +177,37 @@ public class PgpSignEncryptOperation extends BaseOperation {          log.add(LogType.MSG_PSE, indent);          indent += 1; -        boolean enableSignature = input.getSignatureMasterKeyId() != Constants.key.none; -        boolean enableEncryption = ((input.getEncryptionMasterKeyIds() != null && input.getEncryptionMasterKeyIds().length > 0) -                || input.getSymmetricPassphrase() != null); -        boolean enableCompression = (input.getCompressionAlgorithm() != CompressionAlgorithmTags.UNCOMPRESSED); +        PgpSignEncryptData data = input.getData(); +        boolean enableSignature = data.getSignatureMasterKeyId() != Constants.key.none; +        boolean enableEncryption = ((data.getEncryptionMasterKeyIds() != null && data.getEncryptionMasterKeyIds().length > 0) +                || data.getSymmetricPassphrase() != null); +        boolean enableCompression = (data.getCompressionAlgorithm() != CompressionAlgorithmTags.UNCOMPRESSED);          Log.d(Constants.TAG, "enableSignature:" + enableSignature                  + "\nenableEncryption:" + enableEncryption                  + "\nenableCompression:" + enableCompression -                + "\nenableAsciiArmorOutput:" + input.isEnableAsciiArmorOutput() -                + "\nisHiddenRecipients:" + input.isHiddenRecipients()); +                + "\nenableAsciiArmorOutput:" + data.isEnableAsciiArmorOutput() +                + "\nisHiddenRecipients:" + data.isHiddenRecipients());          // add additional key id to encryption ids (mostly to do self-encryption) -        if (enableEncryption && input.getAdditionalEncryptId() != Constants.key.none) { -            input.setEncryptionMasterKeyIds(Arrays.copyOf(input.getEncryptionMasterKeyIds(), input.getEncryptionMasterKeyIds().length + 1)); -            input.getEncryptionMasterKeyIds()[input.getEncryptionMasterKeyIds().length - 1] = input.getAdditionalEncryptId(); +        if (enableEncryption && data.getAdditionalEncryptId() != Constants.key.none) { +            data.setEncryptionMasterKeyIds(Arrays.copyOf(data.getEncryptionMasterKeyIds(), data.getEncryptionMasterKeyIds().length + 1)); +            data.getEncryptionMasterKeyIds()[data.getEncryptionMasterKeyIds().length - 1] = data.getAdditionalEncryptId();          }          ArmoredOutputStream armorOut = null;          OutputStream out; -        if (input.isEnableAsciiArmorOutput()) { +        if (data.isEnableAsciiArmorOutput()) {              armorOut = new ArmoredOutputStream(new BufferedOutputStream(outputStream, 1 << 16)); -            if (input.getVersionHeader() != null) { -                armorOut.setHeader("Version", input.getVersionHeader()); +            if (data.getVersionHeader() != null) { +                armorOut.setHeader("Version", data.getVersionHeader());              }              // if we have a charset, put it in the header -            if (input.getCharset() != null) { -                armorOut.setHeader("Charset", input.getCharset()); +            if (data.getCharset() != null) { +                armorOut.setHeader("Charset", data.getCharset());              }              // add proprietary header to indicate that this is a key backup -            if (input.isAddBackupHeader()) { +            if (data.isAddBackupHeader()) {                  armorOut.setHeader("BackupVersion", "2");              }              out = armorOut; @@ -166,12 +222,12 @@ public class PgpSignEncryptOperation extends BaseOperation {              updateProgress(R.string.progress_extracting_signature_key, 0, 100);              try { -                long signingMasterKeyId = input.getSignatureMasterKeyId(); -                long signingSubKeyId = input.getSignatureSubKeyId(); +                long signingMasterKeyId = data.getSignatureMasterKeyId(); +                long signingSubKeyId = data.getSignatureSubKeyId();                  CanonicalizedSecretKeyRing signingKeyRing =                          mProviderHelper.getCanonicalizedSecretKeyRing(signingMasterKeyId); -                signingKey = signingKeyRing.getSecretKey(input.getSignatureSubKeyId()); +                signingKey = signingKeyRing.getSecretKey(data.getSignatureSubKeyId());                  // Make sure key is not expired or revoked @@ -240,9 +296,9 @@ public class PgpSignEncryptOperation extends BaseOperation {              }              // Use requested hash algo -            int requestedAlgorithm = input.getSignatureHashAlgorithm(); +            int requestedAlgorithm = data.getSignatureHashAlgorithm();              if (requestedAlgorithm == PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT) { -                input.setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM); +                data.setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM);              }          }          updateProgress(R.string.progress_preparing_streams, 2, 100); @@ -252,36 +308,36 @@ public class PgpSignEncryptOperation extends BaseOperation {          if (enableEncryption) {              // Use requested encryption algo -            int algo = input.getSymmetricEncryptionAlgorithm(); +            int algo = data.getSymmetricEncryptionAlgorithm();              if (algo == PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT) {                  algo = PgpSecurityConstants.DEFAULT_SYMMETRIC_ALGORITHM;              }              JcePGPDataEncryptorBuilder encryptorBuilder =                      new JcePGPDataEncryptorBuilder(algo)                              .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) -                            .setWithIntegrityPacket(input.isIntegrityProtected()); +                            .setWithIntegrityPacket(data.isIntegrityProtected());              cPk = new PGPEncryptedDataGenerator(encryptorBuilder); -            if (input.getSymmetricPassphrase() != null) { +            if (data.getSymmetricPassphrase() != null) {                  // Symmetric encryption                  log.add(LogType.MSG_PSE_SYMMETRIC, indent);                  JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = -                        new JcePBEKeyEncryptionMethodGenerator(input.getSymmetricPassphrase().getCharArray()); +                        new JcePBEKeyEncryptionMethodGenerator(data.getSymmetricPassphrase().getCharArray());                  cPk.addMethod(symmetricEncryptionGenerator);              } else {                  log.add(LogType.MSG_PSE_ASYMMETRIC, indent);                  // Asymmetric encryption -                for (long id : input.getEncryptionMasterKeyIds()) { +                for (long id : data.getEncryptionMasterKeyIds()) {                      try {                          CanonicalizedPublicKeyRing keyRing = mProviderHelper.getCanonicalizedPublicKeyRing(                                  KeyRings.buildUnifiedKeyRingUri(id));                          Set<Long> encryptSubKeyIds = keyRing.getEncryptIds();                          for (Long subKeyId : encryptSubKeyIds) {                              CanonicalizedPublicKey key = keyRing.getPublicKey(subKeyId); -                            cPk.addMethod(key.getPubKeyEncryptionGenerator(input.isHiddenRecipients())); +                            cPk.addMethod(key.getPubKeyEncryptionGenerator(data.isHiddenRecipients()));                              log.add(LogType.MSG_PSE_KEY_OK, indent + 1,                                      KeyFormattingUtils.convertKeyIdToHex(subKeyId));                          } @@ -310,9 +366,9 @@ public class PgpSignEncryptOperation extends BaseOperation {              updateProgress(R.string.progress_preparing_signature, 4, 100);              try { -                boolean cleartext = input.isCleartextSignature() && input.isEnableAsciiArmorOutput() && !enableEncryption; +                boolean cleartext = data.isCleartextSignature() && data.isEnableAsciiArmorOutput() && !enableEncryption;                  signatureGenerator = signingKey.getDataSignatureGenerator( -                        input.getSignatureHashAlgorithm(), cleartext, +                        data.getSignatureHashAlgorithm(), cleartext,                          cryptoInput.getCryptoData(), cryptoInput.getSignatureTime());              } catch (PgpGeneralException e) {                  log.add(LogType.MSG_PSE_ERROR_NFC, indent); @@ -351,7 +407,7 @@ public class PgpSignEncryptOperation extends BaseOperation {                      log.add(LogType.MSG_PSE_COMPRESSING, indent);                      // Use preferred compression algo -                    int algo = input.getCompressionAlgorithm(); +                    int algo = data.getCompressionAlgorithm();                      if (algo == PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) {                          algo = PgpSecurityConstants.DEFAULT_COMPRESSION_ALGORITHM;                      } @@ -367,7 +423,7 @@ public class PgpSignEncryptOperation extends BaseOperation {                  PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();                  char literalDataFormatTag; -                if (input.isCleartextSignature()) { +                if (data.isCleartextSignature()) {                      literalDataFormatTag = PGPLiteralData.UTF8;                  } else {                      literalDataFormatTag = PGPLiteralData.BINARY; @@ -397,14 +453,14 @@ public class PgpSignEncryptOperation extends BaseOperation {                  literalGen.close();                  indent -= 1; -            } else if (enableSignature && input.isCleartextSignature() && input.isEnableAsciiArmorOutput()) { +            } else if (enableSignature && data.isCleartextSignature() && data.isEnableAsciiArmorOutput()) {                  /* cleartext signature: sign-only of ascii text */                  updateProgress(R.string.progress_signing, 8, 100);                  log.add(LogType.MSG_PSE_SIGNING_CLEARTEXT, indent);                  // write -----BEGIN PGP SIGNED MESSAGE----- -                armorOut.beginClearText(input.getSignatureHashAlgorithm()); +                armorOut.beginClearText(data.getSignatureHashAlgorithm());                  InputStream in = new BufferedInputStream(inputData.getInputStream());                  final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); @@ -432,7 +488,7 @@ public class PgpSignEncryptOperation extends BaseOperation {                  armorOut.endClearText();                  pOut = new BCPGOutputStream(armorOut); -            } else if (enableSignature && input.isDetachedSignature()) { +            } else if (enableSignature && data.isDetachedSignature()) {                  /* detached signature */                  updateProgress(R.string.progress_signing, 8, 100); @@ -443,10 +499,10 @@ public class PgpSignEncryptOperation extends BaseOperation {                  // handle output stream separately for detached signatures                  detachedByteOut = new ByteArrayOutputStream();                  OutputStream detachedOut = detachedByteOut; -                if (input.isEnableAsciiArmorOutput()) { +                if (data.isEnableAsciiArmorOutput()) {                      detachedArmorOut = new ArmoredOutputStream(new BufferedOutputStream(detachedOut, 1 << 16)); -                    if (input.getVersionHeader() != null) { -                        detachedArmorOut.setHeader("Version", input.getVersionHeader()); +                    if (data.getVersionHeader() != null) { +                        detachedArmorOut.setHeader("Version", data.getVersionHeader());                      }                      detachedOut = detachedArmorOut; @@ -469,7 +525,7 @@ public class PgpSignEncryptOperation extends BaseOperation {                  }                  pOut = null; -            } else if (enableSignature && !input.isCleartextSignature() && !input.isDetachedSignature()) { +            } else if (enableSignature && !data.isCleartextSignature() && !data.isDetachedSignature()) {                  /* sign-only binary (files/data stream) */                  updateProgress(R.string.progress_signing, 8, 100); @@ -479,7 +535,7 @@ public class PgpSignEncryptOperation extends BaseOperation {                  if (enableCompression) {                      // Use preferred compression algo -                    int algo = input.getCompressionAlgorithm(); +                    int algo = data.getCompressionAlgorithm();                      if (algo == PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) {                          algo = PgpSecurityConstants.DEFAULT_COMPRESSION_ALGORITHM;                      } @@ -534,7 +590,7 @@ public class PgpSignEncryptOperation extends BaseOperation {                  }              } -            opTime = System.currentTimeMillis() -startTime; +            opTime = System.currentTimeMillis() - startTime;              Log.d(Constants.TAG, "sign/encrypt time taken: " + String.format("%.2f",                      opTime / 1000.0) + "s"); @@ -591,7 +647,7 @@ public class PgpSignEncryptOperation extends BaseOperation {              }              result.setDetachedSignature(detachedByteOut.toByteArray());              try { -                String digestName = PGPUtil.getDigestName(input.getSignatureHashAlgorithm()); +                String digestName = PGPUtil.getDigestName(data.getSignatureHashAlgorithm());                  // construct micalg parameter according to https://tools.ietf.org/html/rfc3156#section-5                  result.setMicAlgDigestName("pgp-" + digestName.toLowerCase());              } catch (PGPException e) { 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 8f80a4802..2acd4243a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java @@ -20,41 +20,43 @@ package org.sufficientlysecure.keychain.pgp;  import android.net.Uri;  import android.os.Parcel; +import android.os.Parcelable;  import java.util.ArrayList;  import java.util.Collection;  import java.util.Collections;  import java.util.List; -/** This parcel stores the input of one or more PgpSignEncrypt operations. +/** + * This parcel stores the input of one or more PgpSignEncrypt operations.   * All operations will use the same general paramters, differing only in   * input and output. Each input/output set depends on the paramters: - * + * <p/>   * - Each input uri is individually encrypted/signed   * - If a byte array is supplied, it is treated as an input before uris are processed   * - The number of output uris must match the number of input uris, plus one more - *   if there is a byte array present. + * if there is a byte array present.   * - 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. - * + * left, which will be returned in a byte array as part of the result parcel.   */ -public class SignEncryptParcel extends PgpSignEncryptInputParcel { +public class SignEncryptParcel implements Parcelable { + +    private PgpSignEncryptData data;      public ArrayList<Uri> mInputUris = new ArrayList<>();      public ArrayList<Uri> mOutputUris = new ArrayList<>();      public byte[] mBytes; -    public SignEncryptParcel() { -        super(); +    public SignEncryptParcel(PgpSignEncryptData data) { +        this.data = data;      }      public SignEncryptParcel(Parcel src) { -        super(src); -          mInputUris = src.createTypedArrayList(Uri.CREATOR);          mOutputUris = src.createTypedArrayList(Uri.CREATOR);          mBytes = src.createByteArray(); +        data = src.readParcelable(getClass().getClassLoader());      }      public boolean isIncomplete() { @@ -85,17 +87,25 @@ public class SignEncryptParcel extends PgpSignEncryptInputParcel {          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) { -        super.writeToParcel(dest, flags); -          dest.writeTypedList(mInputUris);          dest.writeTypedList(mOutputUris);          dest.writeByteArray(mBytes); + +        dest.writeParcelable(data, 0);      }      public static final Creator<SignEncryptParcel> CREATOR = new Creator<SignEncryptParcel>() { 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 88cd066a2..e20ab67e8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -62,6 +62,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing.UserId;  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.exception.PgpKeyNotFoundException; @@ -199,13 +200,14 @@ public class OpenPgpService extends Service {              boolean asciiArmor = cleartextSign || data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);              // sign-only -            PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel() -                    .setEnableAsciiArmorOutput(asciiArmor) +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEnableAsciiArmorOutput(asciiArmor)                      .setCleartextSignature(cleartextSign)                      .setDetachedSignature(!cleartextSign)                      .setVersionHeader(null)                      .setSignatureHashAlgorithm(PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT); +              Intent signKeyIdIntent = getSignKeyMasterId(data);              // NOTE: Fallback to return account settings (Old API)              if (signKeyIdIntent.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR) @@ -217,18 +219,21 @@ public class OpenPgpService extends Service {              if (signKeyId == Constants.key.none) {                  throw new Exception("No signing key given");              } else { -                pseInput.setSignatureMasterKeyId(signKeyId); +                pgpData.setSignatureMasterKeyId(signKeyId);                  // get first usable subkey capable of signing                  try {                      long signSubKeyId = mProviderHelper.getCachedPublicKeyRing( -                            pseInput.getSignatureMasterKeyId()).getSecretSignId(); -                    pseInput.setSignatureSubKeyId(signSubKeyId); +                            pgpData.getSignatureMasterKeyId()).getSecretSignId(); +                    pgpData.setSignatureSubKeyId(signSubKeyId);                  } catch (PgpKeyNotFoundException e) {                      throw new Exception("signing subkey not found!", e);                  }              } + +            PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData); +              // Get Input- and OutputStream from ParcelFileDescriptor              if (!cleartextSign) {                  // output stream only needed for cleartext signatures, @@ -335,8 +340,8 @@ public class OpenPgpService extends Service {              long inputLength = inputStream.available();              InputData inputData = new InputData(inputStream, inputLength, originalFilename); -            PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(); -            pseInput.setEnableAsciiArmorOutput(asciiArmor) +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEnableAsciiArmorOutput(asciiArmor)                      .setVersionHeader(null)                      .setCompressionAlgorithm(compressionId)                      .setSymmetricEncryptionAlgorithm(PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT) @@ -354,20 +359,20 @@ public class OpenPgpService extends Service {                  if (signKeyId == Constants.key.none) {                      throw new Exception("No signing key given");                  } else { -                    pseInput.setSignatureMasterKeyId(signKeyId); +                    pgpData.setSignatureMasterKeyId(signKeyId);                      // get first usable subkey capable of signing                      try {                          long signSubKeyId = mProviderHelper.getCachedPublicKeyRing( -                                pseInput.getSignatureMasterKeyId()).getSecretSignId(); -                        pseInput.setSignatureSubKeyId(signSubKeyId); +                                pgpData.getSignatureMasterKeyId()).getSecretSignId(); +                        pgpData.setSignatureSubKeyId(signSubKeyId);                      } catch (PgpKeyNotFoundException e) {                          throw new Exception("signing subkey not found!", e);                      }                  }                  // sign and encrypt -                pseInput.setSignatureHashAlgorithm(PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT) +                pgpData.setSignatureHashAlgorithm(PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT)                          .setAdditionalEncryptId(signKeyId); // add sign key for encryption              } @@ -382,9 +387,11 @@ public class OpenPgpService extends Service {                  if (accSettings == null || (accSettings.getKeyId() == Constants.key.none)) {                      return mApiPermissionHelper.getCreateAccountIntent(data, accName);                  } -                pseInput.setAdditionalEncryptId(accSettings.getKeyId()); +                pgpData.setAdditionalEncryptId(accSettings.getKeyId());              } +            PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData); +              CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);              if (inputParcel == null) {                  inputParcel = new CryptoInputParcel(new Date()); 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 d5c540856..80bac18e3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -63,6 +63,7 @@ import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;  import org.sufficientlysecure.keychain.pgp.KeyRing;  import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants; +import org.sufficientlysecure.keychain.pgp.PgpSignEncryptData;  import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;  import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;  import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; @@ -620,9 +621,7 @@ public class EncryptFilesFragment          }          // fill values for this action -        SignEncryptParcel data = new SignEncryptParcel(); - -        data.addInputUris(mFilesAdapter.getAsArrayList()); +        PgpSignEncryptData data = new PgpSignEncryptData();          if (mUseCompression) {              data.setCompressionAlgorithm( @@ -673,7 +672,11 @@ public class EncryptFilesFragment              data.setSymmetricPassphrase(passphrase);          } -        return data; + +        SignEncryptParcel parcel = new SignEncryptParcel(data); +        parcel.addInputUris(mFilesAdapter.getAsArrayList()); + +        return parcel;      }      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 10d88253d..f805c70c3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -38,6 +38,7 @@ import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;  import org.sufficientlysecure.keychain.pgp.KeyRing;  import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants; +import org.sufficientlysecure.keychain.pgp.PgpSignEncryptData;  import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;  import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;  import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment; @@ -230,9 +231,8 @@ public class EncryptTextFragment          }          // fill values for this action -        SignEncryptParcel data = new SignEncryptParcel(); +        PgpSignEncryptData data = new PgpSignEncryptData(); -        data.setBytes(mMessage.getBytes());          data.setCleartextSignature(true);          if (mUseCompression) { @@ -283,7 +283,11 @@ public class EncryptTextFragment              }              data.setSymmetricPassphrase(passphrase);          } -        return data; + +        SignEncryptParcel parcel = new SignEncryptParcel(data); +        parcel.setBytes(mMessage.getBytes()); + +        return parcel;      }      private void copyToClipboard(SignEncryptResult result) { 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 3770b825c..c1fc0d51b 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/PgpEncryptDecryptTest.java @@ -180,11 +180,12 @@ public class PgpEncryptDecryptTest {              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(); -            b.setSymmetricPassphrase(mSymmetricPassphrase); -            b.setSymmetricEncryptionAlgorithm( +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setSymmetricPassphrase(mSymmetricPassphrase); +            pgpData.setSymmetricEncryptionAlgorithm(                      PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); +            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData);              PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()),                      data, out); @@ -303,13 +304,15 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); +            PgpSignEncryptData pgpData = new PgpSignEncryptData();              // only sign, and not as cleartext -            input.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); -            input.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); -            input.setCleartextSignature(false); -            input.setDetachedSignature(false); +            pgpData.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); +            pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); +            pgpData.setCleartextSignature(false); +            pgpData.setDetachedSignature(false); + +            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData);              PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out);              Assert.assertTrue("signing must succeed", result.success()); @@ -357,14 +360,16 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); +            PgpSignEncryptData pgpData = new PgpSignEncryptData();              // only sign, as cleartext -            input.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); -            input.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); -            input.setCleartextSignature(true); -            input.setEnableAsciiArmorOutput(true); -            input.setDetachedSignature(false); +            pgpData.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); +            pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); +            pgpData.setCleartextSignature(true); +            pgpData.setEnableAsciiArmorOutput(true); +            pgpData.setDetachedSignature(false); + +            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData);              PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out);              Assert.assertTrue("signing must succeed", result.success()); @@ -417,12 +422,14 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); +            PgpSignEncryptData pgpData = new PgpSignEncryptData();               // only sign, as cleartext -            input.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); -            input.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); -            input.setDetachedSignature(true); +            pgpData.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); +            pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); +            pgpData.setDetachedSignature(true); + +            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData);              PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1), data, out);              Assert.assertTrue("signing must succeed", result.success()); @@ -472,11 +479,14 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); -            input.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); -            input.setSymmetricEncryptionAlgorithm( +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); +            pgpData.setSymmetricEncryptionAlgorithm(                      PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); + +            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); +              PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()),                      data, out);              Assert.assertTrue("encryption must succeed", result.success()); @@ -572,11 +582,14 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); -            input.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); -            input.setSymmetricEncryptionAlgorithm( +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); +            pgpData.setSymmetricEncryptionAlgorithm(                      PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); + +            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); +              PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()),                      data, out);              Assert.assertTrue("encryption must succeed", result.success()); @@ -679,11 +692,14 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); -            input.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); -            input.setSymmetricEncryptionAlgorithm( +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); +            pgpData.setSymmetricEncryptionAlgorithm(                      PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); + +            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); +              PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()),                      data, out);              Assert.assertTrue("encryption must succeed", result.success()); @@ -722,14 +738,16 @@ public class PgpEncryptDecryptTest {              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(); -            b.setEncryptionMasterKeyIds(new long[] { +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEncryptionMasterKeyIds(new long[] {                      mStaticRing1.getMasterKeyId(),                      mStaticRing2.getMasterKeyId()              }); -            b.setSymmetricEncryptionAlgorithm( +            pgpData.setSymmetricEncryptionAlgorithm(                      PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); +            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData); +              PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()),                      data, out);              Assert.assertTrue("encryption must succeed", result.success()); @@ -848,17 +866,19 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(); -            b.setEncryptionMasterKeyIds(new long[] { +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEncryptionMasterKeyIds(new long[] {                      mStaticRing1.getMasterKeyId(),                      mStaticRing2.getMasterKeyId()              }); -            b.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); -            b.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); -            b.setSymmetricEncryptionAlgorithm( +            pgpData.setSignatureMasterKeyId(mStaticRing1.getMasterKeyId()); +            pgpData.setSignatureSubKeyId(KeyringTestingHelper.getSubkeyId(mStaticRing1, 1)); +            pgpData.setSymmetricEncryptionAlgorithm(                      PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); +            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData); +              PgpSignEncryptResult result = op.execute(b,                      new CryptoInputParcel(new Date(), mKeyPhrase1), data, out);              Assert.assertTrue("encryption must succeed", result.success()); @@ -933,14 +953,17 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(); -            b.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); -            b.setSymmetricEncryptionAlgorithm( +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); +            pgpData.setSymmetricEncryptionAlgorithm(                      PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128);              // this only works with ascii armored output! -            b.setEnableAsciiArmorOutput(true); -            b.setCharset("iso-2022-jp"); +            pgpData.setEnableAsciiArmorOutput(true); +            pgpData.setCharset("iso-2022-jp"); + +            PgpSignEncryptInputParcel b = new PgpSignEncryptInputParcel(pgpData); +              PgpSignEncryptResult result = op.execute(b, new CryptoInputParcel(new Date()),                      data, out);              Assert.assertTrue("encryption must succeed", result.success()); @@ -1002,11 +1025,14 @@ public class PgpEncryptDecryptTest {                      new ProviderHelper(RuntimeEnvironment.application), null);              InputData data = new InputData(in, in.available()); -            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(); -            input.setEncryptionMasterKeyIds(new long[]{key.getMasterKeyId()}) +            PgpSignEncryptData pgpData = new PgpSignEncryptData(); +            pgpData.setEncryptionMasterKeyIds(new long[]{key.getMasterKeyId()})                      .setSymmetricEncryptionAlgorithm(algorithm)                      .setIntegrityProtected(isIntegrityProtected); + +            PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); +              PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()),                      data, out);              Assert.assertTrue("encryption must succeed", result.success());  | 
