mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 17:22:16 -05:00
rewrite PgpDecryptVerify input, introduce PgpDecryptVerifyInputParcel
This commit is contained in:
parent
36ecd60c1b
commit
0d8370be1d
@ -36,6 +36,23 @@ public class DecryptVerifyResult extends InputPendingResult {
|
||||
// https://tools.ietf.org/html/rfc4880#page56
|
||||
String mCharset;
|
||||
|
||||
byte[] mOutputBytes;
|
||||
|
||||
public DecryptVerifyResult(int result, OperationLog log) {
|
||||
super(result, log);
|
||||
}
|
||||
|
||||
public DecryptVerifyResult(OperationLog log, RequiredInputParcel requiredInput) {
|
||||
super(log, requiredInput);
|
||||
}
|
||||
|
||||
public DecryptVerifyResult(Parcel source) {
|
||||
super(source);
|
||||
mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
|
||||
mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader());
|
||||
}
|
||||
|
||||
|
||||
public boolean isKeysDisallowed () {
|
||||
return (mResult & RESULT_KEY_DISALLOWED) == RESULT_KEY_DISALLOWED;
|
||||
}
|
||||
@ -64,18 +81,12 @@ public class DecryptVerifyResult extends InputPendingResult {
|
||||
mCharset = charset;
|
||||
}
|
||||
|
||||
public DecryptVerifyResult(int result, OperationLog log) {
|
||||
super(result, log);
|
||||
public void setOutputBytes(byte[] outputBytes) {
|
||||
mOutputBytes = outputBytes;
|
||||
}
|
||||
|
||||
public DecryptVerifyResult(OperationLog log, RequiredInputParcel requiredInput) {
|
||||
super(log, requiredInput);
|
||||
}
|
||||
|
||||
public DecryptVerifyResult(Parcel source) {
|
||||
super(source);
|
||||
mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
|
||||
mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader());
|
||||
public byte[] getOutputBytes() {
|
||||
return mOutputBytes;
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
|
@ -58,6 +58,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat
|
||||
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;
|
||||
@ -66,6 +67,7 @@ import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@ -73,147 +75,90 @@ import java.net.URLConnection;
|
||||
import java.security.SignatureException;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class uses a Builder pattern!
|
||||
*/
|
||||
public class PgpDecryptVerify extends BaseOperation {
|
||||
|
||||
private InputData mData;
|
||||
private OutputStream mOutStream;
|
||||
|
||||
private boolean mAllowSymmetricDecryption;
|
||||
private Set<Long> mAllowedKeyIds;
|
||||
private boolean mDecryptMetadataOnly;
|
||||
private byte[] mDetachedSignature;
|
||||
private String mRequiredSignerFingerprint;
|
||||
private boolean mSignedLiteralData;
|
||||
|
||||
protected PgpDecryptVerify(Builder builder) {
|
||||
super(builder.mContext, builder.mProviderHelper, builder.mProgressable);
|
||||
|
||||
// private Constructor can only be called from Builder
|
||||
this.mData = builder.mData;
|
||||
this.mOutStream = builder.mOutStream;
|
||||
|
||||
this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption;
|
||||
this.mAllowedKeyIds = builder.mAllowedKeyIds;
|
||||
this.mDecryptMetadataOnly = builder.mDecryptMetadataOnly;
|
||||
this.mDetachedSignature = builder.mDetachedSignature;
|
||||
this.mSignedLiteralData = builder.mSignedLiteralData;
|
||||
this.mRequiredSignerFingerprint = builder.mRequiredSignerFingerprint;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
// mandatory parameter
|
||||
private Context mContext;
|
||||
private ProviderHelper mProviderHelper;
|
||||
private InputData mData;
|
||||
|
||||
// optional
|
||||
private OutputStream mOutStream = null;
|
||||
private Progressable mProgressable = null;
|
||||
private boolean mAllowSymmetricDecryption = true;
|
||||
private Set<Long> mAllowedKeyIds = null;
|
||||
private boolean mDecryptMetadataOnly = false;
|
||||
private byte[] mDetachedSignature = null;
|
||||
private String mRequiredSignerFingerprint = null;
|
||||
private boolean mSignedLiteralData = false;
|
||||
|
||||
public Builder(Context context, ProviderHelper providerHelper,
|
||||
Progressable progressable,
|
||||
InputData data, OutputStream outStream) {
|
||||
mContext = context;
|
||||
mProviderHelper = providerHelper;
|
||||
mProgressable = progressable;
|
||||
mData = data;
|
||||
mOutStream = outStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used when verifying signed literals to check that they are signed with
|
||||
* the required key
|
||||
*/
|
||||
public Builder setRequiredSignerFingerprint(String fingerprint) {
|
||||
mRequiredSignerFingerprint = fingerprint;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is to force a mode where the message is just the signature key id and
|
||||
* then a literal data packet; used in Keybase.io proofs
|
||||
*/
|
||||
public Builder setSignedLiteralData(boolean signedLiteralData) {
|
||||
mSignedLiteralData = signedLiteralData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAllowSymmetricDecryption(boolean allowSymmetricDecryption) {
|
||||
mAllowSymmetricDecryption = allowSymmetricDecryption;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow these key ids alone for decryption.
|
||||
* This means only ciphertexts encrypted for one of these private key can be decrypted.
|
||||
*/
|
||||
public Builder setAllowedKeyIds(Set<Long> allowedKeyIds) {
|
||||
mAllowedKeyIds = allowedKeyIds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enabled, the actual decryption/verification of the content will not be executed.
|
||||
* The metadata only will be decrypted and returned.
|
||||
*/
|
||||
public Builder setDecryptMetadataOnly(boolean decryptMetadataOnly) {
|
||||
mDecryptMetadataOnly = decryptMetadataOnly;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If detachedSignature != null, it will be used exclusively to verify the signature
|
||||
*/
|
||||
public Builder setDetachedSignature(byte[] detachedSignature) {
|
||||
mDetachedSignature = detachedSignature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PgpDecryptVerify build() {
|
||||
return new PgpDecryptVerify(this);
|
||||
}
|
||||
public PgpDecryptVerify(Context context, ProviderHelper providerHelper, Progressable progressable) {
|
||||
super(context, providerHelper, progressable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts and/or verifies data based on parameters of class
|
||||
*/
|
||||
public DecryptVerifyResult execute(CryptoInputParcel cryptoInput) {
|
||||
public DecryptVerifyResult execute(PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput) {
|
||||
InputData inputData;
|
||||
OutputStream outputStream;
|
||||
|
||||
if (input.getInputBytes() != null) {
|
||||
byte[] inputBytes = input.getInputBytes();
|
||||
inputData = new InputData(new ByteArrayInputStream(inputBytes), inputBytes.length);
|
||||
} else {
|
||||
try {
|
||||
InputStream inputStream = mContext.getContentResolver().openInputStream(input.getInputUri());
|
||||
long inputSize = FileHelper.getFileSize(mContext, input.getInputUri(), 0);
|
||||
inputData = new InputData(inputStream, inputSize);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (input.getOutputUri() == null) {
|
||||
outputStream = new ByteArrayOutputStream();
|
||||
} else {
|
||||
try {
|
||||
outputStream = mContext.getContentResolver().openOutputStream(input.getOutputUri());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
DecryptVerifyResult result = executeInternal(input, cryptoInput, inputData, outputStream);
|
||||
if (outputStream instanceof ByteArrayOutputStream) {
|
||||
byte[] outputData = ((ByteArrayOutputStream) outputStream).toByteArray();
|
||||
result.setOutputBytes(outputData);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public DecryptVerifyResult execute(PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput,
|
||||
InputData inputData, OutputStream outputStream) {
|
||||
return executeInternal(input, cryptoInput, inputData, outputStream);
|
||||
}
|
||||
|
||||
private DecryptVerifyResult executeInternal(PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput,
|
||||
InputData inputData, OutputStream outputStream) {
|
||||
try {
|
||||
if (mDetachedSignature != null) {
|
||||
if (input.getDetachedSignature() != null) {
|
||||
Log.d(Constants.TAG, "Detached signature present, verifying with this signature only");
|
||||
|
||||
return verifyDetachedSignature(mData.getInputStream(), 0);
|
||||
return verifyDetachedSignature(input, inputData, outputStream, 0);
|
||||
} else {
|
||||
// automatically works with PGP ascii armor and PGP binary
|
||||
InputStream in = PGPUtil.getDecoderStream(mData.getInputStream());
|
||||
InputStream in = PGPUtil.getDecoderStream(inputData.getInputStream());
|
||||
|
||||
if (in instanceof ArmoredInputStream) {
|
||||
ArmoredInputStream aIn = (ArmoredInputStream) in;
|
||||
// it is ascii armored
|
||||
Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine());
|
||||
|
||||
if (mSignedLiteralData) {
|
||||
return verifySignedLiteralData(aIn, 0);
|
||||
if (input.isSignedLiteralData()) {
|
||||
return verifySignedLiteralData(input, aIn, outputStream, 0);
|
||||
} else if (aIn.isClearText()) {
|
||||
// a cleartext signature, verify it with the other method
|
||||
return verifyCleartextSignature(aIn, 0);
|
||||
} else {
|
||||
// else: ascii armored encryption! go on...
|
||||
return decryptVerify(cryptoInput, in, 0);
|
||||
return decryptVerify(input, cryptoInput, in, outputStream, 0);
|
||||
}
|
||||
} else {
|
||||
return decryptVerify(cryptoInput, in, 0);
|
||||
return decryptVerify(input, cryptoInput, in, outputStream, 0);
|
||||
}
|
||||
}
|
||||
} catch (PGPException e) {
|
||||
@ -232,7 +177,8 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
/**
|
||||
* Verify Keybase.io style signed literal data
|
||||
*/
|
||||
private DecryptVerifyResult verifySignedLiteralData(InputStream in, int indent)
|
||||
private DecryptVerifyResult verifySignedLiteralData(
|
||||
PgpDecryptVerifyInputParcel input, InputStream in, OutputStream out, int indent)
|
||||
throws IOException, PGPException {
|
||||
OperationLog log = new OperationLog();
|
||||
log.add(LogType.MSG_VL, indent);
|
||||
@ -283,9 +229,9 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
}
|
||||
|
||||
String fingerprint = KeyFormattingUtils.convertFingerprintToHex(signingRing.getFingerprint());
|
||||
if (!(mRequiredSignerFingerprint.equals(fingerprint))) {
|
||||
if (!(input.getRequiredSignerFingerprint().equals(fingerprint))) {
|
||||
log.add(LogType.MSG_VL_ERROR_MISSING_KEY, indent);
|
||||
Log.d(Constants.TAG, "Fingerprint mismatch; wanted " + mRequiredSignerFingerprint +
|
||||
Log.d(Constants.TAG, "Fingerprint mismatch; wanted " + input.getRequiredSignerFingerprint() +
|
||||
" got " + fingerprint + "!");
|
||||
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
|
||||
}
|
||||
@ -317,7 +263,7 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
int length;
|
||||
byte[] buffer = new byte[1 << 16];
|
||||
while ((length = dataIn.read(buffer)) > 0) {
|
||||
mOutStream.write(buffer, 0, length);
|
||||
out.write(buffer, 0, length);
|
||||
signature.update(buffer, 0, length);
|
||||
}
|
||||
|
||||
@ -363,8 +309,9 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
/**
|
||||
* Decrypt and/or verifies binary or ascii armored pgp
|
||||
*/
|
||||
private DecryptVerifyResult decryptVerify(CryptoInputParcel cryptoInput,
|
||||
InputStream in, int indent) throws IOException, PGPException {
|
||||
private DecryptVerifyResult decryptVerify(
|
||||
PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput,
|
||||
InputStream in, OutputStream out, int indent) throws IOException, PGPException {
|
||||
|
||||
OperationLog log = new OperationLog();
|
||||
|
||||
@ -455,13 +402,13 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
}
|
||||
|
||||
// allow only specific keys for decryption?
|
||||
if (mAllowedKeyIds != null) {
|
||||
if (input.getAllowedKeyIds() != null) {
|
||||
long masterKeyId = secretKeyRing.getMasterKeyId();
|
||||
Log.d(Constants.TAG, "encData.getKeyID(): " + subKeyId);
|
||||
Log.d(Constants.TAG, "mAllowedKeyIds: " + mAllowedKeyIds);
|
||||
Log.d(Constants.TAG, "mAllowedKeyIds: " + input.getAllowedKeyIds());
|
||||
Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
|
||||
|
||||
if (!mAllowedKeyIds.contains(masterKeyId)) {
|
||||
if (!input.getAllowedKeyIds().contains(masterKeyId)) {
|
||||
// this key is in our db, but NOT allowed!
|
||||
// continue with the next packet in the while loop
|
||||
skippedDisallowedKey = true;
|
||||
@ -515,7 +462,7 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
|
||||
log.add(LogType.MSG_DC_SYM, indent);
|
||||
|
||||
if (!mAllowSymmetricDecryption) {
|
||||
if (!input.isAllowSymmetricDecryption()) {
|
||||
log.add(LogType.MSG_DC_SYM_SKIP, indent + 1);
|
||||
continue;
|
||||
}
|
||||
@ -764,7 +711,7 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
}
|
||||
|
||||
// return here if we want to decrypt the metadata only
|
||||
if (mDecryptMetadataOnly) {
|
||||
if (input.isDecryptMetadataOnly()) {
|
||||
log.add(LogType.MSG_DC_OK_META_ONLY, indent);
|
||||
DecryptVerifyResult result =
|
||||
new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
|
||||
@ -787,13 +734,13 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
InputStream dataIn = literalData.getInputStream();
|
||||
|
||||
long alreadyWritten = 0;
|
||||
long wholeSize = mData.getSize() - mData.getStreamPosition();
|
||||
long wholeSize = 0; // TODO inputData.getSize() - inputData.getStreamPosition();
|
||||
int length;
|
||||
byte[] buffer = new byte[1 << 16];
|
||||
while ((length = dataIn.read(buffer)) > 0) {
|
||||
Log.d(Constants.TAG, "read bytes: " + length);
|
||||
if (mOutStream != null) {
|
||||
mOutStream.write(buffer, 0, length);
|
||||
// Log.d(Constants.TAG, "read bytes: " + length);
|
||||
if (out != null) {
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
// update signature buffer if signature is also present
|
||||
@ -919,8 +866,8 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
out.close();
|
||||
|
||||
byte[] clearText = out.toByteArray();
|
||||
if (mOutStream != null) {
|
||||
mOutStream.write(clearText);
|
||||
if (out != null) {
|
||||
out.write(clearText);
|
||||
}
|
||||
|
||||
updateProgress(R.string.progress_processing_signature, 60, 100);
|
||||
@ -987,7 +934,8 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
return result;
|
||||
}
|
||||
|
||||
private DecryptVerifyResult verifyDetachedSignature(InputStream in, int indent)
|
||||
private DecryptVerifyResult verifyDetachedSignature(
|
||||
PgpDecryptVerifyInputParcel input, InputData inputData, OutputStream out, int indent)
|
||||
throws IOException, PGPException {
|
||||
|
||||
OperationLog log = new OperationLog();
|
||||
@ -997,7 +945,7 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
signatureResultBuilder.setSignatureOnly(true);
|
||||
|
||||
updateProgress(R.string.progress_processing_signature, 0, 100);
|
||||
InputStream detachedSigIn = new ByteArrayInputStream(mDetachedSignature);
|
||||
InputStream detachedSigIn = new ByteArrayInputStream(input.getDetachedSignature());
|
||||
detachedSigIn = PGPUtil.getDecoderStream(detachedSigIn);
|
||||
|
||||
JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(detachedSigIn);
|
||||
@ -1022,12 +970,13 @@ public class PgpDecryptVerify extends BaseOperation {
|
||||
|
||||
ProgressScaler progressScaler = new ProgressScaler(mProgressable, 60, 90, 100);
|
||||
long alreadyWritten = 0;
|
||||
long wholeSize = mData.getSize() - mData.getStreamPosition();
|
||||
long wholeSize = inputData.getSize() - inputData.getStreamPosition();
|
||||
int length;
|
||||
byte[] buffer = new byte[1 << 16];
|
||||
InputStream in = inputData.getInputStream();
|
||||
while ((length = in.read(buffer)) > 0) {
|
||||
if (mOutStream != null) {
|
||||
mOutStream.write(buffer, 0, length);
|
||||
if (out != null) {
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
// update signature buffer if signature is also present
|
||||
|
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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 java.util.HashSet;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class PgpDecryptVerifyInputParcel implements Parcelable {
|
||||
|
||||
private Uri mInputUri;
|
||||
private Uri mOutputUri;
|
||||
private byte[] mInputBytes;
|
||||
|
||||
private boolean mAllowSymmetricDecryption;
|
||||
private HashSet<Long> mAllowedKeyIds;
|
||||
private boolean mDecryptMetadataOnly;
|
||||
private byte[] mDetachedSignature;
|
||||
private String mRequiredSignerFingerprint;
|
||||
private boolean mSignedLiteralData;
|
||||
|
||||
public PgpDecryptVerifyInputParcel() {
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel(Uri inputUri, Uri outputUri) {
|
||||
mInputUri = inputUri;
|
||||
mOutputUri = outputUri;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel(byte[] inputBytes) {
|
||||
mInputBytes = inputBytes;
|
||||
}
|
||||
|
||||
PgpDecryptVerifyInputParcel(Parcel source) {
|
||||
// we do all of those here, so the PgpSignEncryptInput class doesn't have to be parcelable
|
||||
mInputUri = source.readParcelable(getClass().getClassLoader());
|
||||
mOutputUri = source.readParcelable(getClass().getClassLoader());
|
||||
mInputBytes = source.createByteArray();
|
||||
|
||||
mAllowSymmetricDecryption = source.readInt() != 0;
|
||||
mAllowedKeyIds = (HashSet<Long>) source.readSerializable();
|
||||
mDecryptMetadataOnly = source.readInt() != 0;
|
||||
mDetachedSignature = source.createByteArray();
|
||||
mRequiredSignerFingerprint = source.readString();
|
||||
mSignedLiteralData = source.readInt() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeParcelable(mInputUri, 0);
|
||||
dest.writeParcelable(mOutputUri, 0);
|
||||
dest.writeByteArray(mInputBytes);
|
||||
|
||||
dest.writeInt(mAllowSymmetricDecryption ? 1 : 0);
|
||||
dest.writeSerializable(mAllowedKeyIds);
|
||||
dest.writeInt(mDecryptMetadataOnly ? 1 : 0);
|
||||
dest.writeByteArray(mDetachedSignature);
|
||||
dest.writeString(mRequiredSignerFingerprint);
|
||||
dest.writeInt(mSignedLiteralData ? 1 : 0);
|
||||
}
|
||||
|
||||
byte[] getInputBytes() {
|
||||
return mInputBytes;
|
||||
}
|
||||
|
||||
Uri getInputUri() {
|
||||
return mInputUri;
|
||||
}
|
||||
|
||||
Uri getOutputUri() {
|
||||
return mOutputUri;
|
||||
}
|
||||
|
||||
boolean isAllowSymmetricDecryption() {
|
||||
return mAllowSymmetricDecryption;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel setAllowSymmetricDecryption(boolean allowSymmetricDecryption) {
|
||||
mAllowSymmetricDecryption = allowSymmetricDecryption;
|
||||
return this;
|
||||
}
|
||||
|
||||
HashSet<Long> getAllowedKeyIds() {
|
||||
return mAllowedKeyIds;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel setAllowedKeyIds(HashSet<Long> allowedKeyIds) {
|
||||
mAllowedKeyIds = allowedKeyIds;
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean isDecryptMetadataOnly() {
|
||||
return mDecryptMetadataOnly;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel setDecryptMetadataOnly(boolean decryptMetadataOnly) {
|
||||
mDecryptMetadataOnly = decryptMetadataOnly;
|
||||
return this;
|
||||
}
|
||||
|
||||
byte[] getDetachedSignature() {
|
||||
return mDetachedSignature;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel setDetachedSignature(byte[] detachedSignature) {
|
||||
mDetachedSignature = detachedSignature;
|
||||
return this;
|
||||
}
|
||||
|
||||
String getRequiredSignerFingerprint() {
|
||||
return mRequiredSignerFingerprint;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel setRequiredSignerFingerprint(String requiredSignerFingerprint) {
|
||||
mRequiredSignerFingerprint = requiredSignerFingerprint;
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean isSignedLiteralData() {
|
||||
return mSignedLiteralData;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel setSignedLiteralData(boolean signedLiteralData) {
|
||||
mSignedLiteralData = signedLiteralData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static final Creator<PgpDecryptVerifyInputParcel> CREATOR = new Creator<PgpDecryptVerifyInputParcel>() {
|
||||
public PgpDecryptVerifyInputParcel createFromParcel(final Parcel source) {
|
||||
return new PgpDecryptVerifyInputParcel(source);
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel[] newArray(final int size) {
|
||||
return new PgpDecryptVerifyInputParcel[size];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1514,8 +1514,8 @@ public class ProviderHelper {
|
||||
return keyIds;
|
||||
}
|
||||
|
||||
public Set<Long> getAllowedKeyIdsForApp(Uri uri) {
|
||||
Set<Long> keyIds = new HashSet<>();
|
||||
public HashSet<Long> getAllowedKeyIdsForApp(Uri uri) {
|
||||
HashSet<Long> keyIds = new HashSet<>();
|
||||
|
||||
Cursor cursor = mContentResolver.query(uri, null, null, null, null);
|
||||
try {
|
||||
|
@ -38,6 +38,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEnt
|
||||
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
@ -63,7 +64,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class OpenPgpService extends RemoteService {
|
||||
|
||||
@ -488,23 +489,23 @@ public class OpenPgpService extends RemoteService {
|
||||
}
|
||||
}
|
||||
|
||||
private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
|
||||
private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor inputDescriptor,
|
||||
ParcelFileDescriptor output, boolean decryptMetadataOnly) {
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
// Get Input- and OutputStream from ParcelFileDescriptor
|
||||
is = new ParcelFileDescriptor.AutoCloseInputStream(input);
|
||||
inputStream = new ParcelFileDescriptor.AutoCloseInputStream(inputDescriptor);
|
||||
|
||||
// output is optional, e.g., for verifying detached signatures
|
||||
if (decryptMetadataOnly || output == null) {
|
||||
os = null;
|
||||
outputStream = null;
|
||||
} else {
|
||||
os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
|
||||
outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(output);
|
||||
}
|
||||
|
||||
String currentPkg = getCurrentCallingPackage();
|
||||
Set<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
|
||||
HashSet<Long> allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp(
|
||||
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
|
||||
|
||||
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) {
|
||||
@ -512,33 +513,31 @@ public class OpenPgpService extends RemoteService {
|
||||
ApiAccounts.buildBaseUri(currentPkg)));
|
||||
}
|
||||
|
||||
long inputLength = is.available();
|
||||
InputData inputData = new InputData(is, inputLength);
|
||||
|
||||
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
|
||||
this, new ProviderHelper(getContext()), null, inputData, os
|
||||
);
|
||||
|
||||
CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
|
||||
if (inputParcel == null) {
|
||||
inputParcel = new CryptoInputParcel();
|
||||
CryptoInputParcel cryptoInput = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
|
||||
if (cryptoInput == null) {
|
||||
cryptoInput = new CryptoInputParcel();
|
||||
}
|
||||
// override passphrase in input parcel if given by API call
|
||||
if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
|
||||
inputParcel = new CryptoInputParcel(inputParcel.getSignatureTime(),
|
||||
cryptoInput = new CryptoInputParcel(cryptoInput.getSignatureTime(),
|
||||
new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)));
|
||||
}
|
||||
|
||||
byte[] detachedSignature = data.getByteArrayExtra(OpenPgpApi.EXTRA_DETACHED_SIGNATURE);
|
||||
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(this, mProviderHelper, null);
|
||||
|
||||
long inputLength = inputStream.available();
|
||||
|
||||
// allow only private keys associated with accounts of this app
|
||||
// no support for symmetric encryption
|
||||
builder.setAllowSymmetricDecryption(false)
|
||||
.setAllowedKeyIds(allowedKeyIds)
|
||||
.setDecryptMetadataOnly(decryptMetadataOnly)
|
||||
.setDetachedSignature(detachedSignature);
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel()
|
||||
.setAllowSymmetricDecryption(false)
|
||||
.setAllowedKeyIds(allowedKeyIds)
|
||||
.setDecryptMetadataOnly(decryptMetadataOnly)
|
||||
.setDetachedSignature(detachedSignature);
|
||||
|
||||
DecryptVerifyResult pgpResult = builder.build().execute(inputParcel);
|
||||
DecryptVerifyResult pgpResult = op.execute(input, cryptoInput, inputStream, outputStream);
|
||||
|
||||
if (pgpResult.isPending()) {
|
||||
// prepare and return PendingIntent to be executed by client
|
||||
@ -624,16 +623,16 @@ public class OpenPgpService extends RemoteService {
|
||||
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
|
||||
return result;
|
||||
} finally {
|
||||
if (is != null) {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
is.close();
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "IOException when closing InputStream", e);
|
||||
}
|
||||
}
|
||||
if (os != null) {
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
os.close();
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "IOException when closing OutputStream", e);
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
@ -61,17 +62,11 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
|
||||
import org.sufficientlysecure.keychain.util.FileHelper;
|
||||
import org.sufficientlysecure.keychain.util.InputData;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -122,34 +117,13 @@ public class KeychainIntentService extends IntentService implements Progressable
|
||||
|
||||
/* keys for data bundle */
|
||||
|
||||
// encrypt, decrypt, import export
|
||||
public static final String TARGET = "target";
|
||||
public static final String SOURCE = "source";
|
||||
|
||||
// possible targets:
|
||||
public static enum IOType {
|
||||
UNKNOWN,
|
||||
BYTES,
|
||||
URI;
|
||||
|
||||
private static final IOType[] values = values();
|
||||
|
||||
public static IOType fromInt(int n) {
|
||||
if (n < 0 || n >= values.length) {
|
||||
return UNKNOWN;
|
||||
} else {
|
||||
return values[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// encrypt
|
||||
public static final String ENCRYPT_DECRYPT_INPUT_URI = "input_uri";
|
||||
public static final String ENCRYPT_DECRYPT_OUTPUT_URI = "output_uri";
|
||||
public static final String SIGN_ENCRYPT_PARCEL = "sign_encrypt_parcel";
|
||||
|
||||
// decrypt/verify
|
||||
public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes";
|
||||
public static final String DECRYPT_VERIFY_PARCEL = "decrypt_verify_parcel";
|
||||
|
||||
// keybase proof
|
||||
public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint";
|
||||
@ -189,14 +163,6 @@ public class KeychainIntentService extends IntentService implements Progressable
|
||||
// consolidate
|
||||
public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery";
|
||||
|
||||
|
||||
/*
|
||||
* possible data keys as result send over messenger
|
||||
*/
|
||||
|
||||
// decrypt/verify
|
||||
public static final String RESULT_DECRYPTED_BYTES = "decrypted_data";
|
||||
|
||||
Messenger mMessenger;
|
||||
|
||||
// this attribute can possibly merged with the one above? not sure...
|
||||
@ -280,26 +246,16 @@ public class KeychainIntentService extends IntentService implements Progressable
|
||||
}
|
||||
case ACTION_DECRYPT_METADATA: {
|
||||
|
||||
try {
|
||||
/* Input */
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
/* Input */
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL);
|
||||
|
||||
InputData inputData = createDecryptInputData(data);
|
||||
// verifyText and decrypt returning additional resultData values for the
|
||||
// verification of signatures
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(this, new ProviderHelper(this), this);
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput);
|
||||
|
||||
// verifyText and decrypt returning additional resultData values for the
|
||||
// verification of signatures
|
||||
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
|
||||
this, new ProviderHelper(this), this, inputData, null
|
||||
);
|
||||
builder.setAllowSymmetricDecryption(true)
|
||||
.setDecryptMetadataOnly(true);
|
||||
|
||||
DecryptVerifyResult decryptVerifyResult = builder.build().execute(cryptoInput);
|
||||
|
||||
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -356,22 +312,13 @@ public class KeychainIntentService extends IntentService implements Progressable
|
||||
}
|
||||
}
|
||||
|
||||
// kind of awkward, but this whole class wants to pull bytes out of “data”
|
||||
data.putInt(KeychainIntentService.TARGET, IOType.BYTES.ordinal());
|
||||
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, messageBytes);
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(this, new ProviderHelper(this), this);
|
||||
|
||||
InputData inputData = createDecryptInputData(data);
|
||||
OutputStream outStream = createCryptOutputStream(data);
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(messageBytes)
|
||||
.setSignedLiteralData(true)
|
||||
.setRequiredSignerFingerprint(requiredFingerprint);
|
||||
|
||||
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
|
||||
this, new ProviderHelper(this), this,
|
||||
inputData, outStream
|
||||
);
|
||||
builder.setSignedLiteralData(true).setRequiredSignerFingerprint(requiredFingerprint);
|
||||
|
||||
DecryptVerifyResult decryptVerifyResult = builder.build().execute(
|
||||
new CryptoInputParcel());
|
||||
outStream.close();
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, new CryptoInputParcel());
|
||||
|
||||
if (!decryptVerifyResult.success()) {
|
||||
OperationLog log = decryptVerifyResult.getLog();
|
||||
@ -383,7 +330,7 @@ public class KeychainIntentService extends IntentService implements Progressable
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prover.validate(outStream.toString())) {
|
||||
if (!prover.validate(new String(decryptVerifyResult.getOutputBytes()))) {
|
||||
sendProofError(getString(R.string.keybase_message_payload_mismatch));
|
||||
return;
|
||||
}
|
||||
@ -404,40 +351,16 @@ public class KeychainIntentService extends IntentService implements Progressable
|
||||
}
|
||||
case ACTION_DECRYPT_VERIFY: {
|
||||
|
||||
try {
|
||||
/* Input */
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
/* Input */
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL);
|
||||
|
||||
InputData inputData = createDecryptInputData(data);
|
||||
OutputStream outStream = createCryptOutputStream(data);
|
||||
/* Operation */
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(this, new ProviderHelper(this), this);
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput);
|
||||
|
||||
/* Operation */
|
||||
Bundle resultData = new Bundle();
|
||||
|
||||
// verifyText and decrypt returning additional resultData values for the
|
||||
// verification of signatures
|
||||
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
|
||||
this, new ProviderHelper(this), this,
|
||||
inputData, outStream
|
||||
);
|
||||
builder.setAllowSymmetricDecryption(true);
|
||||
|
||||
DecryptVerifyResult decryptVerifyResult = builder.build().execute(cryptoInput);
|
||||
|
||||
outStream.close();
|
||||
|
||||
resultData.putParcelable(DecryptVerifyResult.EXTRA_RESULT, decryptVerifyResult);
|
||||
|
||||
/* Output */
|
||||
finalizeDecryptOutputStream(data, resultData, outStream);
|
||||
Log.logDebugBundle(resultData, "resultData");
|
||||
|
||||
sendMessageToHandler(MessageStatus.OKAY, resultData);
|
||||
|
||||
} catch (IOException | PgpGeneralException e) {
|
||||
// TODO get rid of this!
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
/* Output */
|
||||
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -676,65 +599,6 @@ public class KeychainIntentService extends IntentService implements Progressable
|
||||
sendMessageToHandler(MessageStatus.PREVENT_CANCEL);
|
||||
}
|
||||
|
||||
private InputData createDecryptInputData(Bundle data) throws IOException, PgpGeneralException {
|
||||
return createCryptInputData(data, DECRYPT_CIPHERTEXT_BYTES);
|
||||
}
|
||||
|
||||
private InputData createCryptInputData(Bundle data, String bytesName) throws PgpGeneralException, IOException {
|
||||
int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
|
||||
IOType type = IOType.fromInt(source);
|
||||
switch (type) {
|
||||
case BYTES: /* encrypting bytes directly */
|
||||
byte[] bytes = data.getByteArray(bytesName);
|
||||
return new InputData(new ByteArrayInputStream(bytes), bytes.length);
|
||||
|
||||
case URI: /* encrypting content uri */
|
||||
Uri providerUri = data.getParcelable(ENCRYPT_DECRYPT_INPUT_URI);
|
||||
|
||||
// InputStream
|
||||
return new InputData(getContentResolver().openInputStream(providerUri), FileHelper.getFileSize(this, providerUri, 0));
|
||||
|
||||
default:
|
||||
throw new PgpGeneralException("No target chosen!");
|
||||
}
|
||||
}
|
||||
|
||||
private OutputStream createCryptOutputStream(Bundle data) throws PgpGeneralException, FileNotFoundException {
|
||||
int target = data.getInt(TARGET);
|
||||
IOType type = IOType.fromInt(target);
|
||||
switch (type) {
|
||||
case BYTES:
|
||||
return new ByteArrayOutputStream();
|
||||
|
||||
case URI:
|
||||
Uri providerUri = data.getParcelable(ENCRYPT_DECRYPT_OUTPUT_URI);
|
||||
|
||||
return getContentResolver().openOutputStream(providerUri);
|
||||
|
||||
default:
|
||||
throw new PgpGeneralException("No target chosen!");
|
||||
}
|
||||
}
|
||||
|
||||
private void finalizeDecryptOutputStream(Bundle data, Bundle resultData, OutputStream outStream) {
|
||||
finalizeCryptOutputStream(data, resultData, outStream, RESULT_DECRYPTED_BYTES);
|
||||
}
|
||||
|
||||
private void finalizeCryptOutputStream(Bundle data, Bundle resultData, OutputStream outStream, String bytesName) {
|
||||
int target = data.getInt(TARGET);
|
||||
IOType type = IOType.fromInt(target);
|
||||
switch (type) {
|
||||
case BYTES:
|
||||
byte output[] = ((ByteArrayOutputStream) outStream).toByteArray();
|
||||
resultData.putByteArray(bytesName, output);
|
||||
break;
|
||||
case URI:
|
||||
// nothing, output was written, just send okay and verification bundle
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (ACTION_CANCEL.equals(intent.getAction())) {
|
||||
|
@ -36,8 +36,8 @@ import android.widget.TextView;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService.IOType;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
|
||||
@ -202,16 +202,14 @@ public class DecryptFilesFragment extends DecryptFragment {
|
||||
intent.setAction(mCurrentCryptoOperation);
|
||||
|
||||
// data
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
|
||||
Log.d(Constants.TAG, "mInputUri=" + mInputUri + ", mOutputUri=" + mOutputUri);
|
||||
|
||||
data.putInt(KeychainIntentService.SOURCE, IOType.URI.ordinal());
|
||||
data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_INPUT_URI, mInputUri);
|
||||
|
||||
data.putInt(KeychainIntentService.TARGET, IOType.URI.ordinal());
|
||||
data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_OUTPUT_URI, mOutputUri);
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(mInputUri, mOutputUri)
|
||||
.setAllowSymmetricDecryption(true)
|
||||
.setDecryptMetadataOnly(true);
|
||||
|
||||
data.putParcelable(KeychainIntentService.DECRYPT_VERIFY_PARCEL, input);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
|
@ -34,8 +34,8 @@ import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService.IOType;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
@ -168,10 +168,8 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY);
|
||||
|
||||
// data
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putInt(KeychainIntentService.TARGET, IOType.BYTES.ordinal());
|
||||
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes());
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(mCiphertext.getBytes());
|
||||
data.putParcelable(KeychainIntentService.DECRYPT_VERIFY_PARCEL, input);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
@ -199,8 +197,7 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT);
|
||||
|
||||
if (pgpResult.success()) {
|
||||
byte[] decryptedMessage = returnData
|
||||
.getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES);
|
||||
byte[] decryptedMessage = pgpResult.getOutputBytes();
|
||||
String displayMessage;
|
||||
if (pgpResult.getCharset() != null) {
|
||||
try {
|
||||
|
@ -120,6 +120,9 @@ public class EncryptModeAsymmetricFragment extends EncryptModeFragment {
|
||||
// preselect keys given, from state or arguments
|
||||
if (savedInstanceState == null) {
|
||||
Long signatureKeyId = getArguments().getLong(ARG_SINGATURE_KEY_ID);
|
||||
if (signatureKeyId == Constants.key.none) {
|
||||
signatureKeyId = null;
|
||||
}
|
||||
long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS);
|
||||
preselectKeys(signatureKeyId, encryptionKeyIds);
|
||||
}
|
||||
|
@ -163,9 +163,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
Bundle args = new Bundle();
|
||||
args.putLong(EXTRA_SUBKEY_ID, keyId);
|
||||
args.putParcelable(EXTRA_SERVICE_INTENT, serviceIntent);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
frag.show(context.getSupportFragmentManager(), "passphraseDialog");
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user