aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure
diff options
context:
space:
mode:
authorAndrea Torlaschi <runnerway@gmail.com>2016-03-08 18:47:46 +0100
committerAndrea Torlaschi <runnerway@gmail.com>2016-05-10 23:38:11 +0200
commitc942d8b2ff062abce236ebff6fba268ab5247038 (patch)
tree0387f7e2126911bdf3d9f13bd727386b17af0ab2 /OpenKeychain/src/main/java/org/sufficientlysecure
parentc8a0eb3a083c92b654610f34655fed80312a8ef1 (diff)
downloadopen-keychain-c942d8b2ff062abce236ebff6fba268ab5247038.tar.gz
open-keychain-c942d8b2ff062abce236ebff6fba268ab5247038.tar.bz2
open-keychain-c942d8b2ff062abce236ebff6fba268ab5247038.zip
PgpSignEncryptOperation refactoring
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BackupOperation.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BenchmarkOperation.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java97
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java259
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java219
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java148
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java34
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java31
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java10
12 files changed, 496 insertions, 349 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) {