fix Decrypt*Fragment for RequiredInputParcel (except decryptOriginalFilename)

This commit is contained in:
Vincent Breitmoser 2015-04-01 00:38:01 +02:00
parent cc44ff1a8b
commit ad69622b69
15 changed files with 150 additions and 276 deletions

View File

@ -15,7 +15,10 @@ import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.operator.PGPDataDecryptor; import org.spongycastle.openpgp.operator.PGPDataDecryptor;
import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import java.nio.ByteBuffer;
import java.security.Provider; import java.security.Provider;
import java.util.Map;
/** /**
* This class is based on JcePublicKeyDataDecryptorFactoryBuilder * This class is based on JcePublicKeyDataDecryptorFactoryBuilder
@ -88,7 +91,7 @@ public class NfcSyncPublicKeyDataDecryptorFactoryBuilder
return this; return this;
} }
public PublicKeyDataDecryptorFactory build(final byte[] nfcDecrypted) { public PublicKeyDataDecryptorFactory build(final Map<ByteBuffer,byte[]> nfcDecryptedMap) {
return new PublicKeyDataDecryptorFactory() return new PublicKeyDataDecryptorFactory()
{ {
public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData) public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData)
@ -99,7 +102,7 @@ public class NfcSyncPublicKeyDataDecryptorFactoryBuilder
throw new PGPException("ECDH not supported!"); throw new PGPException("ECDH not supported!");
} }
return decryptSessionData(keyAlgorithm, secKeyData, nfcDecrypted); return decryptSessionData(keyAlgorithm, secKeyData, nfcDecryptedMap);
} }
public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) public PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key)
@ -197,7 +200,8 @@ public class NfcSyncPublicKeyDataDecryptorFactoryBuilder
// } // }
// } // }
private byte[] decryptSessionData(int keyAlgorithm, byte[][] secKeyData, byte[] nfcDecrypted) private byte[] decryptSessionData(int keyAlgorithm, byte[][] secKeyData,
Map<ByteBuffer,byte[]> nfcDecryptedMap)
throws PGPException throws PGPException
{ {
// Cipher c1 = helper.createPublicKeyCipher(keyAlgorithm); // Cipher c1 = helper.createPublicKeyCipher(keyAlgorithm);
@ -214,15 +218,14 @@ public class NfcSyncPublicKeyDataDecryptorFactoryBuilder
if (keyAlgorithm == PGPPublicKey.RSA_ENCRYPT if (keyAlgorithm == PGPPublicKey.RSA_ENCRYPT
|| keyAlgorithm == PGPPublicKey.RSA_GENERAL) || keyAlgorithm == PGPPublicKey.RSA_GENERAL)
{ {
byte[] bi = secKeyData[0]; // encoded MPI ByteBuffer bi = ByteBuffer.wrap(secKeyData[0]); // encoded MPI
if (nfcDecrypted != null) { if (nfcDecryptedMap.containsKey(bi)) {
// we already have the decrypted bytes from a previous execution, return this! return nfcDecryptedMap.get(bi);
return nfcDecrypted;
} else { } else {
// catch this when decryptSessionData() is executed and divert digest to card, // catch this when decryptSessionData() is executed and divert digest to card,
// when doing the operation again reuse nfcDecrypted // when doing the operation again reuse nfcDecrypted
throw new NfcInteractionNeeded(bi); throw new NfcInteractionNeeded(bi.array());
} }
// c1.update(bi, 2, bi.length - 2); // c1.update(bi, 2, bi.length - 2);

View File

@ -80,7 +80,7 @@ public class CertifyOperation extends BaseOperation {
certificationKey = secretKeyRing.getSecretKey(); certificationKey = secretKeyRing.getSecretKey();
if (!cryptoInput.hasPassphrase()) { if (!cryptoInput.hasPassphrase()) {
return new CertifyResult(log, RequiredInputParcel.createRequiredPassphrase( return new CertifyResult(log, RequiredInputParcel.createRequiredSignPassphrase(
certificationKey.getKeyId(), certificationKey.getKeyId(), null)); certificationKey.getKeyId(), certificationKey.getKeyId(), null));
} }

View File

@ -22,23 +22,10 @@ import android.os.Parcel;
import org.openintents.openpgp.OpenPgpMetadata; import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.OpenPgpSignatureResult;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Passphrase;
public class DecryptVerifyResult extends OperationResult { public class DecryptVerifyResult extends InputPendingResult {
// the fourth bit indicates a "data pending" result! (it's also a form of non-success)
public static final int RESULT_PENDING = RESULT_ERROR + 8;
// fifth to sixth bit in addition indicate specific type of pending
public static final int RESULT_PENDING_ASYM_PASSPHRASE = RESULT_PENDING + 16;
public static final int RESULT_PENDING_SYM_PASSPHRASE = RESULT_PENDING + 32;
public static final int RESULT_PENDING_NFC = RESULT_PENDING + 64;
long mKeyIdPassphraseNeeded;
long mNfcSubKeyId;
byte[] mNfcSessionKey;
Passphrase mNfcPassphrase;
OpenPgpSignatureResult mSignatureResult; OpenPgpSignatureResult mSignatureResult;
OpenPgpMetadata mDecryptMetadata; OpenPgpMetadata mDecryptMetadata;
@ -46,32 +33,6 @@ public class DecryptVerifyResult extends OperationResult {
// https://tools.ietf.org/html/rfc4880#page56 // https://tools.ietf.org/html/rfc4880#page56
String mCharset; String mCharset;
public long getKeyIdPassphraseNeeded() {
return mKeyIdPassphraseNeeded;
}
public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) {
mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
}
public void setNfcState(long subKeyId, byte[] sessionKey, Passphrase passphrase) {
mNfcSubKeyId = subKeyId;
mNfcSessionKey = sessionKey;
mNfcPassphrase = passphrase;
}
public long getNfcSubKeyId() {
return mNfcSubKeyId;
}
public byte[] getNfcEncryptedSessionKey() {
return mNfcSessionKey;
}
public Passphrase getNfcPassphrase() {
return mNfcPassphrase;
}
public OpenPgpSignatureResult getSignatureResult() { public OpenPgpSignatureResult getSignatureResult() {
return mSignatureResult; return mSignatureResult;
} }
@ -104,13 +65,14 @@ public class DecryptVerifyResult extends OperationResult {
super(result, log); super(result, log);
} }
public DecryptVerifyResult(OperationLog log, RequiredInputParcel requiredInput) {
super(log, requiredInput);
}
public DecryptVerifyResult(Parcel source) { public DecryptVerifyResult(Parcel source) {
super(source); super(source);
mKeyIdPassphraseNeeded = source.readLong();
mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader()); mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader());
mNfcSessionKey = source.readInt() != 0 ? source.createByteArray() : null;
mNfcPassphrase = source.readParcelable(Passphrase.class.getClassLoader());
} }
public int describeContents() { public int describeContents() {
@ -119,16 +81,8 @@ public class DecryptVerifyResult extends OperationResult {
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags); super.writeToParcel(dest, flags);
dest.writeLong(mKeyIdPassphraseNeeded);
dest.writeParcelable(mSignatureResult, 0); dest.writeParcelable(mSignatureResult, 0);
dest.writeParcelable(mDecryptMetadata, 0); dest.writeParcelable(mDecryptMetadata, 0);
if (mNfcSessionKey != null) {
dest.writeInt(1);
dest.writeByteArray(mNfcSessionKey);
} else {
dest.writeInt(0);
}
dest.writeParcelable(mNfcPassphrase, flags);
} }
public static final Creator<DecryptVerifyResult> CREATOR = new Creator<DecryptVerifyResult>() { public static final Creator<DecryptVerifyResult> CREATOR = new Creator<DecryptVerifyResult>() {

View File

@ -40,6 +40,7 @@ import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFac
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Passphrase;
@ -264,14 +265,16 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
} }
} }
public PublicKeyDataDecryptorFactory getDecryptorFactory(byte[] nfcDecryptedSessionKey) { public PublicKeyDataDecryptorFactory getDecryptorFactory(CryptoInputParcel cryptoInput) {
if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) { if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {
throw new PrivateKeyNotUnlockedException(); throw new PrivateKeyNotUnlockedException();
} }
if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) { if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) {
return new NfcSyncPublicKeyDataDecryptorFactoryBuilder() return new NfcSyncPublicKeyDataDecryptorFactoryBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(nfcDecryptedSessionKey); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
cryptoInput.getCryptoData()
);
} else { } else {
return new JcePublicKeyDataDecryptorFactoryBuilder() return new JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mPrivateKey); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mPrivateKey);

View File

@ -47,16 +47,15 @@ import org.spongycastle.openpgp.operator.jcajce.NfcSyncPublicKeyDataDecryptorFac
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.BaseOperation; import org.sufficientlysecure.keychain.operations.BaseOperation;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
@ -84,10 +83,8 @@ public class PgpDecryptVerify extends BaseOperation {
private OutputStream mOutStream; private OutputStream mOutStream;
private boolean mAllowSymmetricDecryption; private boolean mAllowSymmetricDecryption;
private Passphrase mPassphrase;
private Set<Long> mAllowedKeyIds; private Set<Long> mAllowedKeyIds;
private boolean mDecryptMetadataOnly; private boolean mDecryptMetadataOnly;
private byte[] mDecryptedSessionKey;
private byte[] mDetachedSignature; private byte[] mDetachedSignature;
private String mRequiredSignerFingerprint; private String mRequiredSignerFingerprint;
private boolean mSignedLiteralData; private boolean mSignedLiteralData;
@ -100,10 +97,8 @@ public class PgpDecryptVerify extends BaseOperation {
this.mOutStream = builder.mOutStream; this.mOutStream = builder.mOutStream;
this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption; this.mAllowSymmetricDecryption = builder.mAllowSymmetricDecryption;
this.mPassphrase = builder.mPassphrase;
this.mAllowedKeyIds = builder.mAllowedKeyIds; this.mAllowedKeyIds = builder.mAllowedKeyIds;
this.mDecryptMetadataOnly = builder.mDecryptMetadataOnly; this.mDecryptMetadataOnly = builder.mDecryptMetadataOnly;
this.mDecryptedSessionKey = builder.mDecryptedSessionKey;
this.mDetachedSignature = builder.mDetachedSignature; this.mDetachedSignature = builder.mDetachedSignature;
this.mSignedLiteralData = builder.mSignedLiteralData; this.mSignedLiteralData = builder.mSignedLiteralData;
this.mRequiredSignerFingerprint = builder.mRequiredSignerFingerprint; this.mRequiredSignerFingerprint = builder.mRequiredSignerFingerprint;
@ -119,10 +114,8 @@ public class PgpDecryptVerify extends BaseOperation {
private OutputStream mOutStream = null; private OutputStream mOutStream = null;
private Progressable mProgressable = null; private Progressable mProgressable = null;
private boolean mAllowSymmetricDecryption = true; private boolean mAllowSymmetricDecryption = true;
private Passphrase mPassphrase = null;
private Set<Long> mAllowedKeyIds = null; private Set<Long> mAllowedKeyIds = null;
private boolean mDecryptMetadataOnly = false; private boolean mDecryptMetadataOnly = false;
private byte[] mDecryptedSessionKey = null;
private byte[] mDetachedSignature = null; private byte[] mDetachedSignature = null;
private String mRequiredSignerFingerprint = null; private String mRequiredSignerFingerprint = null;
private boolean mSignedLiteralData = false; private boolean mSignedLiteralData = false;
@ -160,11 +153,6 @@ public class PgpDecryptVerify extends BaseOperation {
return this; return this;
} }
public Builder setPassphrase(Passphrase passphrase) {
mPassphrase = passphrase;
return this;
}
/** /**
* Allow these key ids alone for decryption. * Allow these key ids alone for decryption.
* This means only ciphertexts encrypted for one of these private key can be decrypted. * This means only ciphertexts encrypted for one of these private key can be decrypted.
@ -183,11 +171,6 @@ public class PgpDecryptVerify extends BaseOperation {
return this; return this;
} }
public Builder setNfcState(byte[] decryptedSessionKey) {
mDecryptedSessionKey = decryptedSessionKey;
return this;
}
/** /**
* If detachedSignature != null, it will be used exclusively to verify the signature * If detachedSignature != null, it will be used exclusively to verify the signature
*/ */
@ -204,7 +187,7 @@ public class PgpDecryptVerify extends BaseOperation {
/** /**
* Decrypts and/or verifies data based on parameters of class * Decrypts and/or verifies data based on parameters of class
*/ */
public DecryptVerifyResult execute() { public DecryptVerifyResult execute(CryptoInputParcel cryptoInput) {
try { try {
if (mDetachedSignature != null) { if (mDetachedSignature != null) {
Log.d(Constants.TAG, "Detached signature present, verifying with this signature only"); Log.d(Constants.TAG, "Detached signature present, verifying with this signature only");
@ -226,10 +209,10 @@ public class PgpDecryptVerify extends BaseOperation {
return verifyCleartextSignature(aIn, 0); return verifyCleartextSignature(aIn, 0);
} else { } else {
// else: ascii armored encryption! go on... // else: ascii armored encryption! go on...
return decryptVerify(in, 0); return decryptVerify(cryptoInput, in, 0);
} }
} else { } else {
return decryptVerify(in, 0); return decryptVerify(cryptoInput, in, 0);
} }
} }
} catch (PGPException e) { } catch (PGPException e) {
@ -248,7 +231,8 @@ public class PgpDecryptVerify extends BaseOperation {
/** /**
* Verify Keybase.io style signed literal data * Verify Keybase.io style signed literal data
*/ */
private DecryptVerifyResult verifySignedLiteralData(InputStream in, int indent) throws IOException, PGPException { private DecryptVerifyResult verifySignedLiteralData(InputStream in, int indent)
throws IOException, PGPException {
OperationLog log = new OperationLog(); OperationLog log = new OperationLog();
log.add(LogType.MSG_VL, indent); log.add(LogType.MSG_VL, indent);
@ -378,7 +362,8 @@ public class PgpDecryptVerify extends BaseOperation {
/** /**
* Decrypt and/or verifies binary or ascii armored pgp * Decrypt and/or verifies binary or ascii armored pgp
*/ */
private DecryptVerifyResult decryptVerify(InputStream in, int indent) throws IOException, PGPException { private DecryptVerifyResult decryptVerify(CryptoInputParcel cryptoInput,
InputStream in, int indent) throws IOException, PGPException {
OperationLog log = new OperationLog(); OperationLog log = new OperationLog();
@ -433,6 +418,8 @@ public class PgpDecryptVerify extends BaseOperation {
} }
} }
Passphrase passphrase = null;
// go through all objects and find one we can decrypt // go through all objects and find one we can decrypt
while (it.hasNext()) { while (it.hasNext()) {
Object obj = it.next(); Object obj = it.next();
@ -492,11 +479,15 @@ public class PgpDecryptVerify extends BaseOperation {
encryptedDataAsymmetric = encData; encryptedDataAsymmetric = encData;
if (secretEncryptionKey.getSecretKeyType() == SecretKeyType.DIVERT_TO_CARD) {
passphrase = null;
} else if (cryptoInput.hasPassphrase()) {
passphrase = cryptoInput.getPassphrase();
} else {
// if no passphrase was explicitly set try to get it from the cache service // if no passphrase was explicitly set try to get it from the cache service
if (mPassphrase == null) {
try { try {
// returns "" if key has no passphrase // returns "" if key has no passphrase
mPassphrase = getCachedPassphrase(subKeyId); passphrase = getCachedPassphrase(subKeyId);
log.add(LogType.MSG_DC_PASS_CACHED, indent + 1); log.add(LogType.MSG_DC_PASS_CACHED, indent + 1);
} catch (PassphraseCacheInterface.NoSecretKeyException e) { } catch (PassphraseCacheInterface.NoSecretKeyException e) {
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1); log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
@ -504,12 +495,11 @@ public class PgpDecryptVerify extends BaseOperation {
} }
// if passphrase was not cached, return here indicating that a passphrase is missing! // if passphrase was not cached, return here indicating that a passphrase is missing!
if (mPassphrase == null) { if (passphrase == null) {
log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1); log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1);
DecryptVerifyResult result = return new DecryptVerifyResult(log,
new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE, log); RequiredInputParcel.createRequiredDecryptPassphrase(
result.setKeyIdPassphraseNeeded(subKeyId); secretKeyRing.getMasterKeyId(), secretEncryptionKey.getKeyId()));
return result;
} }
} }
@ -536,11 +526,14 @@ public class PgpDecryptVerify extends BaseOperation {
// if no passphrase is given, return here // if no passphrase is given, return here
// indicating that a passphrase is missing! // indicating that a passphrase is missing!
if (mPassphrase == null) { if (!cryptoInput.hasPassphrase()) {
log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1); log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE, log); return new DecryptVerifyResult(log,
RequiredInputParcel.createRequiredSymmetricPassphrase());
} }
passphrase = cryptoInput.getPassphrase();
// break out of while, only decrypt the first packet // break out of while, only decrypt the first packet
break; break;
} }
@ -573,7 +566,7 @@ public class PgpDecryptVerify extends BaseOperation {
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build();
PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder(
digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
mPassphrase.getCharArray()); passphrase.getCharArray());
clear = encryptedDataSymmetric.getDataStream(decryptorFactory); clear = encryptedDataSymmetric.getDataStream(decryptorFactory);
encryptedData = encryptedDataSymmetric; encryptedData = encryptedDataSymmetric;
@ -585,7 +578,7 @@ public class PgpDecryptVerify extends BaseOperation {
try { try {
log.add(LogType.MSG_DC_UNLOCKING, indent + 1); log.add(LogType.MSG_DC_UNLOCKING, indent + 1);
if (!secretEncryptionKey.unlock(mPassphrase)) { if (!secretEncryptionKey.unlock(passphrase)) {
log.add(LogType.MSG_DC_ERROR_BAD_PASSPHRASE, indent + 1); log.add(LogType.MSG_DC_ERROR_BAD_PASSPHRASE, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log); return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
} }
@ -599,16 +592,15 @@ public class PgpDecryptVerify extends BaseOperation {
try { try {
PublicKeyDataDecryptorFactory decryptorFactory PublicKeyDataDecryptorFactory decryptorFactory
= secretEncryptionKey.getDecryptorFactory(mDecryptedSessionKey); = secretEncryptionKey.getDecryptorFactory(cryptoInput);
clear = encryptedDataAsymmetric.getDataStream(decryptorFactory); clear = encryptedDataAsymmetric.getDataStream(decryptorFactory);
symmetricEncryptionAlgo = encryptedDataAsymmetric.getSymmetricAlgorithm(decryptorFactory); symmetricEncryptionAlgo = encryptedDataAsymmetric.getSymmetricAlgorithm(decryptorFactory);
} catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) { } catch (NfcSyncPublicKeyDataDecryptorFactoryBuilder.NfcInteractionNeeded e) {
log.add(LogType.MSG_DC_PENDING_NFC, indent + 1); log.add(LogType.MSG_DC_PENDING_NFC, indent + 1);
DecryptVerifyResult result = return new DecryptVerifyResult(log, RequiredInputParcel.createNfcDecryptOperation(
new DecryptVerifyResult(DecryptVerifyResult.RESULT_PENDING_NFC, log); e.encryptedSessionKey, secretEncryptionKey.getKeyId()
result.setNfcState(secretEncryptionKey.getKeyId(), e.encryptedSessionKey, mPassphrase); ));
return result;
} }
encryptedData = encryptedDataAsymmetric; encryptedData = encryptedDataAsymmetric;
} else { } else {
@ -878,8 +870,8 @@ public class PgpDecryptVerify extends BaseOperation {
* The method is heavily based on * The method is heavily based on
* pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java * pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java
*/ */
private DecryptVerifyResult verifyCleartextSignature(ArmoredInputStream aIn, int indent) private DecryptVerifyResult verifyCleartextSignature(
throws IOException, PGPException { ArmoredInputStream aIn, int indent) throws IOException, PGPException {
OperationLog log = new OperationLog(); OperationLog log = new OperationLog();

View File

@ -408,7 +408,7 @@ public class PgpKeyOperation {
// Do we require a passphrase? If so, pass it along // Do we require a passphrase? If so, pass it along
if (!isDivertToCard(masterSecretKey) && !cryptoInput.hasPassphrase()) { if (!isDivertToCard(masterSecretKey) && !cryptoInput.hasPassphrase()) {
log.add(LogType.MSG_MF_REQUIRE_PASSPHRASE, indent); log.add(LogType.MSG_MF_REQUIRE_PASSPHRASE, indent);
return new PgpEditKeyResult(log, RequiredInputParcel.createRequiredPassphrase( return new PgpEditKeyResult(log, RequiredInputParcel.createRequiredSignPassphrase(
masterSecretKey.getKeyID(), masterSecretKey.getKeyID(), masterSecretKey.getKeyID(), masterSecretKey.getKeyID(),
cryptoInput.getSignatureTime())); cryptoInput.getSignatureTime()));
} }

View File

@ -33,14 +33,12 @@ import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;
import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder; import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder;
import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.BaseOperation; import org.sufficientlysecure.keychain.operations.BaseOperation;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
@ -181,7 +179,7 @@ public class PgpSignEncryptOperation extends BaseOperation {
case PASSPHRASE: { case PASSPHRASE: {
if (cryptoInput.getPassphrase() == null) { if (cryptoInput.getPassphrase() == null) {
log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1); log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1);
return new PgpSignEncryptResult(log, RequiredInputParcel.createRequiredPassphrase( return new PgpSignEncryptResult(log, RequiredInputParcel.createRequiredSignPassphrase(
signingKeyRing.getMasterKeyId(), signingKey.getKeyId(), signingKeyRing.getMasterKeyId(), signingKey.getKeyId(),
cryptoInput.getSignatureTime())); cryptoInput.getSignatureTime()));
} }

View File

@ -473,31 +473,23 @@ public class OpenPgpService extends RemoteService {
// allow only private keys associated with accounts of this app // allow only private keys associated with accounts of this app
// no support for symmetric encryption // no support for symmetric encryption
builder.setPassphrase(cryptoInput.getPassphrase()) // TODO proper CryptoInputParcel support builder.setAllowSymmetricDecryption(false)
.setAllowSymmetricDecryption(false)
.setAllowedKeyIds(allowedKeyIds) .setAllowedKeyIds(allowedKeyIds)
.setDecryptMetadataOnly(decryptMetadataOnly) .setDecryptMetadataOnly(decryptMetadataOnly)
.setNfcState(null) // TODO proper CryptoInputParcel support
.setDetachedSignature(detachedSignature); .setDetachedSignature(detachedSignature);
DecryptVerifyResult pgpResult = builder.build().execute(); DecryptVerifyResult pgpResult = builder.build().execute(cryptoInput);
if (pgpResult.isPending()) { if (pgpResult.isPending()) {
if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) == // prepare and return PendingIntent to be executed by client
DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) { RequiredInputParcel requiredInput = pgpResult.getRequiredInputParcel();
throw new AssertionError("not implemented"); // TODO PendingIntent pIntent = getRequiredInputPendingIntent(getBaseContext(), data, requiredInput);
// return returnPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());
} else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) == Intent result = new Intent();
DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) { result.putExtra(OpenPgpApi.RESULT_INTENT, pIntent);
throw new PgpGeneralException( result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
"Decryption of symmetric content not supported by API!"); return result;
} else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_NFC) ==
DecryptVerifyResult.RESULT_PENDING_NFC) {
throw new AssertionError("not implemented"); // TODO
} else {
throw new PgpGeneralException(
"Encountered unhandled type of pending action not supported by API!");
}
} else if (pgpResult.success()) { } else if (pgpResult.success()) {
Intent result = new Intent(); Intent result = new Intent();

View File

@ -151,8 +151,6 @@ public class KeychainIntentService extends IntentService implements Progressable
// decrypt/verify // decrypt/verify
public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes"; public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes";
public static final String DECRYPT_PASSPHRASE = "passphrase";
public static final String DECRYPT_NFC_DECRYPTED_SESSION_KEY = "nfc_decrypted_session_key";
// keybase proof // keybase proof
public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint"; public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint";
@ -284,25 +282,19 @@ public class KeychainIntentService extends IntentService implements Progressable
try { try {
/* Input */ /* Input */
Passphrase passphrase = data.getParcelable(DECRYPT_PASSPHRASE); CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
InputData inputData = createDecryptInputData(data); InputData inputData = createDecryptInputData(data);
/* Operation */
Bundle resultData = new Bundle();
// verifyText and decrypt returning additional resultData values for the // verifyText and decrypt returning additional resultData values for the
// verification of signatures // verification of signatures
PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder( PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(
this, new ProviderHelper(this), this, inputData, null this, new ProviderHelper(this), this, inputData, null
); );
builder.setAllowSymmetricDecryption(true) builder.setAllowSymmetricDecryption(true)
.setPassphrase(passphrase) .setDecryptMetadataOnly(true);
.setDecryptMetadataOnly(true)
.setNfcState(nfcDecryptedSessionKey);
DecryptVerifyResult decryptVerifyResult = builder.build().execute(); DecryptVerifyResult decryptVerifyResult = builder.build().execute(cryptoInput);
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult); sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
} catch (Exception e) { } catch (Exception e) {
@ -377,7 +369,8 @@ public class KeychainIntentService extends IntentService implements Progressable
); );
builder.setSignedLiteralData(true).setRequiredSignerFingerprint(requiredFingerprint); builder.setSignedLiteralData(true).setRequiredSignerFingerprint(requiredFingerprint);
DecryptVerifyResult decryptVerifyResult = builder.build().execute(); DecryptVerifyResult decryptVerifyResult = builder.build().execute(
new CryptoInputParcel());
outStream.close(); outStream.close();
if (!decryptVerifyResult.success()) { if (!decryptVerifyResult.success()) {
@ -413,14 +406,12 @@ public class KeychainIntentService extends IntentService implements Progressable
try { try {
/* Input */ /* Input */
Passphrase passphrase = data.getParcelable(DECRYPT_PASSPHRASE); CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
InputData inputData = createDecryptInputData(data); InputData inputData = createDecryptInputData(data);
OutputStream outStream = createCryptOutputStream(data); OutputStream outStream = createCryptOutputStream(data);
/* Operation */ /* Operation */
Bundle resultData = new Bundle(); Bundle resultData = new Bundle();
// verifyText and decrypt returning additional resultData values for the // verifyText and decrypt returning additional resultData values for the
@ -429,24 +420,22 @@ public class KeychainIntentService extends IntentService implements Progressable
this, new ProviderHelper(this), this, this, new ProviderHelper(this), this,
inputData, outStream inputData, outStream
); );
builder.setAllowSymmetricDecryption(true) builder.setAllowSymmetricDecryption(true);
.setPassphrase(passphrase)
.setNfcState(nfcDecryptedSessionKey);
DecryptVerifyResult decryptVerifyResult = builder.build().execute(); DecryptVerifyResult decryptVerifyResult = builder.build().execute(cryptoInput);
outStream.close(); outStream.close();
resultData.putParcelable(DecryptVerifyResult.EXTRA_RESULT, decryptVerifyResult); resultData.putParcelable(DecryptVerifyResult.EXTRA_RESULT, decryptVerifyResult);
/* Output */ /* Output */
finalizeDecryptOutputStream(data, resultData, outStream); finalizeDecryptOutputStream(data, resultData, outStream);
Log.logDebugBundle(resultData, "resultData"); Log.logDebugBundle(resultData, "resultData");
sendMessageToHandler(MessageStatus.OKAY, resultData); sendMessageToHandler(MessageStatus.OKAY, resultData);
} catch (Exception e) {
} catch (IOException | PgpGeneralException e) {
// TODO get rid of this!
sendErrorToHandler(e); sendErrorToHandler(e);
} }

View File

@ -1,18 +1,19 @@
package org.sufficientlysecure.keychain.service.input; package org.sufficientlysecure.keychain.service.input;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import org.sufficientlysecure.keychain.Constants.key;
public class RequiredInputParcel implements Parcelable { public class RequiredInputParcel implements Parcelable {
public enum RequiredInputType { public enum RequiredInputType {
PASSPHRASE, NFC_SIGN, NFC_DECRYPT PASSPHRASE, PASSPHRASE_SYMMETRIC, NFC_SIGN, NFC_DECRYPT
} }
public Date mSignatureTime; public Date mSignatureTime;
@ -38,14 +39,23 @@ public class RequiredInputParcel implements Parcelable {
public RequiredInputParcel(Parcel source) { public RequiredInputParcel(Parcel source) {
mType = RequiredInputType.values()[source.readInt()]; mType = RequiredInputType.values()[source.readInt()];
if (source.readInt() != 0) { // 0 = none, 1 = both, 2 = only hashes (decrypt)
int hashTypes = source.readInt();
if (hashTypes != 0) {
int count = source.readInt(); int count = source.readInt();
mInputHashes = new byte[count][]; mInputHashes = new byte[count][];
if (hashTypes == 1) {
mSignAlgos = new int[count]; mSignAlgos = new int[count];
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
mInputHashes[i] = source.createByteArray(); mInputHashes[i] = source.createByteArray();
mSignAlgos[i] = source.readInt(); mSignAlgos[i] = source.readInt();
} }
} else {
mSignAlgos = null;
for (int i = 0; i < count; i++) {
mInputHashes[i] = source.createByteArray();
}
}
} else { } else {
mInputHashes = null; mInputHashes = null;
mSignAlgos = null; mSignAlgos = null;
@ -72,17 +82,28 @@ public class RequiredInputParcel implements Parcelable {
signatureTime, null, null); signatureTime, null, null);
} }
public static RequiredInputParcel createNfcDecryptOperation(byte[] inputHash) { public static RequiredInputParcel createNfcDecryptOperation(byte[] inputHash, long subKeyId) {
return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT, return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT,
new byte[][] { inputHash }, null, null, null, null); new byte[][] { inputHash }, null, null, null, subKeyId);
} }
public static RequiredInputParcel createRequiredPassphrase( public static RequiredInputParcel createRequiredSignPassphrase(
long masterKeyId, long subKeyId, Date signatureTime) { long masterKeyId, long subKeyId, Date signatureTime) {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE, return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
null, null, signatureTime, masterKeyId, subKeyId); null, null, signatureTime, masterKeyId, subKeyId);
} }
public static RequiredInputParcel createRequiredDecryptPassphrase(
long masterKeyId, long subKeyId) {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
null, null, null, masterKeyId, subKeyId);
}
public static RequiredInputParcel createRequiredSymmetricPassphrase() {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE_SYMMETRIC,
null, null, null, null, null);
}
public static RequiredInputParcel createRequiredPassphrase( public static RequiredInputParcel createRequiredPassphrase(
RequiredInputParcel req) { RequiredInputParcel req) {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE, return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
@ -98,12 +119,14 @@ public class RequiredInputParcel implements Parcelable {
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType.ordinal()); dest.writeInt(mType.ordinal());
if (mInputHashes != null) { if (mInputHashes != null) {
dest.writeInt(1); dest.writeInt(mSignAlgos != null ? 1 : 2);
dest.writeInt(mInputHashes.length); dest.writeInt(mInputHashes.length);
for (int i = 0; i < mInputHashes.length; i++) { for (int i = 0; i < mInputHashes.length; i++) {
dest.writeByteArray(mInputHashes[i]); dest.writeByteArray(mInputHashes[i]);
if (mSignAlgos != null) {
dest.writeInt(mSignAlgos[i]); dest.writeInt(mSignAlgos[i]);
} }
}
} else { } else {
dest.writeInt(0); dest.writeInt(0);
} }

View File

@ -49,7 +49,8 @@ public abstract class CryptoOperationFragment extends Fragment {
return; return;
} }
case PASSPHRASE: { case PASSPHRASE:
case PASSPHRASE_SYMMETRIC: {
Intent intent = new Intent(getActivity(), PassphraseDialogActivity.class); Intent intent = new Intent(getActivity(), PassphraseDialogActivity.class);
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput); intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput);
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);

View File

@ -93,9 +93,6 @@ public class DecryptFilesFragment extends DecryptFragment {
mDecryptButton = view.findViewById(R.id.decrypt_file_action_decrypt); mDecryptButton = view.findViewById(R.id.decrypt_file_action_decrypt);
view.findViewById(R.id.decrypt_file_browse).setOnClickListener(new View.OnClickListener() { view.findViewById(R.id.decrypt_file_browse).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
// reset state
mPassphrase = null;
mNfcDecryptedSessionKey = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT); FileHelper.openDocument(DecryptFilesFragment.this, "*/*", REQUEST_CODE_INPUT);
} else { } else {
@ -207,8 +204,7 @@ public class DecryptFilesFragment extends DecryptFragment {
data.putInt(KeychainIntentService.TARGET, IOType.URI.ordinal()); data.putInt(KeychainIntentService.TARGET, IOType.URI.ordinal());
data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_OUTPUT_URI, mOutputUri); data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_OUTPUT_URI, mOutputUri);
// data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
// data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@ -235,20 +231,6 @@ public class DecryptFilesFragment extends DecryptFragment {
DecryptVerifyResult pgpResult = DecryptVerifyResult pgpResult =
returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT);
// if (pgpResult.isPending()) {
// if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) ==
// DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) {
// startPassphraseDialog(pgpResult.getKeyIdPassphraseNeeded());
// } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) ==
// DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) {
// startPassphraseDialog(Constants.key.symmetric);
// } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_NFC) ==
// DecryptVerifyResult.RESULT_PENDING_NFC) {
// startNfcDecrypt(pgpResult.getNfcSubKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcEncryptedSessionKey());
// } else {
// throw new RuntimeException("Unhandled pending result!");
// }
if (pgpResult.success()) { if (pgpResult.success()) {
switch (mCurrentCryptoOperation) { switch (mCurrentCryptoOperation) {
@ -304,22 +286,6 @@ public class DecryptFilesFragment extends DecryptFragment {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) { switch (requestCode) {
// case REQUEST_CODE_PASSPHRASE: {
// if (resultCode == Activity.RESULT_OK && data != null) {
// mPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
//// decryptOriginalFilename();
// }
// return;
// }
//
// case REQUEST_CODE_NFC_DECRYPT: {
// if (resultCode == Activity.RESULT_OK && data != null) {
// mNfcDecryptedSessionKey = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_DECRYPTED_SESSION_KEY);
//// decryptOriginalFilename();
// }
// return;
// }
case REQUEST_CODE_INPUT: { case REQUEST_CODE_INPUT: {
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
setInputUri(data.getData()); setInputUri(data.getData());

View File

@ -19,7 +19,6 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -32,14 +31,10 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.util.Passphrase;
public abstract class DecryptFragment extends CryptoOperationFragment { public abstract class DecryptFragment extends CryptoOperationFragment {
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
// public static final int REQUEST_CODE_PASSPHRASE = 0x00008001;
// public static final int REQUEST_CODE_NFC_DECRYPT = 0x00008002;
protected long mSignatureKeyId = 0; protected long mSignatureKeyId = 0;
protected LinearLayout mResultLayout; protected LinearLayout mResultLayout;
@ -56,11 +51,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment {
protected TextView mSignatureEmail; protected TextView mSignatureEmail;
protected TextView mSignatureAction; protected TextView mSignatureAction;
// State
protected Passphrase mPassphrase;
protected byte[] mNfcDecryptedSessionKey;
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);

View File

@ -17,7 +17,6 @@
package org.sufficientlysecure.keychain.ui; package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -30,7 +29,6 @@ import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
@ -52,10 +50,7 @@ public class DecryptTextFragment extends DecryptFragment {
// view // view
private LinearLayout mValidLayout; private LinearLayout mValidLayout;
private LinearLayout mInvalidLayout; private LinearLayout mInvalidLayout;
private Button mInvalidButton;
private TextView mText; private TextView mText;
private View mShareButton;
private View mCopyButton;
// model // model
private String mCiphertext; private String mCiphertext;
@ -82,23 +77,26 @@ public class DecryptTextFragment extends DecryptFragment {
View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false); View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
mValidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_valid); mValidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_valid);
mInvalidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_invalid); mInvalidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_invalid);
mInvalidButton = (Button) view.findViewById(R.id.decrypt_text_invalid_button);
mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext); mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
mShareButton = view.findViewById(R.id.action_decrypt_share_plaintext);
mCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext); View vShareButton = view.findViewById(R.id.action_decrypt_share_plaintext);
mShareButton.setOnClickListener(new View.OnClickListener() { vShareButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString())); startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString()));
} }
}); });
mCopyButton.setOnClickListener(new View.OnClickListener() {
View vCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext);
vCopyButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
copyToClipboard(mText.getText().toString()); copyToClipboard(mText.getText().toString());
} }
}); });
mInvalidButton.setOnClickListener(new View.OnClickListener() {
Button vInvalidButton = (Button) view.findViewById(R.id.decrypt_text_invalid_button);
vInvalidButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
mInvalidLayout.setVisibility(View.GONE); mInvalidLayout.setVisibility(View.GONE);
@ -162,8 +160,7 @@ public class DecryptTextFragment extends DecryptFragment {
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput); data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
data.putInt(KeychainIntentService.TARGET, IOType.BYTES.ordinal()); data.putInt(KeychainIntentService.TARGET, IOType.BYTES.ordinal());
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes()); data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes());
// data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
// data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@ -189,19 +186,6 @@ public class DecryptTextFragment extends DecryptFragment {
DecryptVerifyResult pgpResult = DecryptVerifyResult pgpResult =
returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT);
// if (pgpResult.isPending()) {
// if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) ==
// DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) {
// startPassphraseDialog(pgpResult.getKeyIdPassphraseNeeded());
// } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) ==
// DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) {
// startPassphraseDialog(Constants.key.symmetric);
// } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_NFC) ==
// DecryptVerifyResult.RESULT_PENDING_NFC) {
// startNfcDecrypt(pgpResult.getNfcSubKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcEncryptedSessionKey());
// } else {
// throw new RuntimeException("Unhandled pending result!");
// }
if (pgpResult.success()) { if (pgpResult.success()) {
byte[] decryptedMessage = returnData byte[] decryptedMessage = returnData
@ -250,34 +234,4 @@ public class DecryptTextFragment extends DecryptFragment {
getActivity().startService(intent); getActivity().startService(intent);
} }
// @Override
// public void onActivityResult(int requestCode, int resultCode, Intent data) {
// switch (requestCode) {
//
// case REQUEST_CODE_PASSPHRASE: {
// if (resultCode == Activity.RESULT_OK && data != null) {
// mPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
// decryptStart();
// } else {
// getActivity().finish();
// }
// return;
// }
//
// case REQUEST_CODE_NFC_DECRYPT: {
// if (resultCode == Activity.RESULT_OK && data != null) {
// mNfcDecryptedSessionKey = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_DECRYPTED_SESSION_KEY);
// decryptStart();
// } else {
// getActivity().finish();
// }
// return;
// }
//
// default: {
// super.onActivityResult(requestCode, resultCode, data);
// }
// }
// }
} }

View File

@ -97,10 +97,19 @@ public class PassphraseDialogActivity extends FragmentActivity {
keyId = getIntent().getLongExtra(EXTRA_SUBKEY_ID, 0); keyId = getIntent().getLongExtra(EXTRA_SUBKEY_ID, 0);
} else { } else {
RequiredInputParcel requiredInput = getIntent().getParcelableExtra(EXTRA_REQUIRED_INPUT); RequiredInputParcel requiredInput = getIntent().getParcelableExtra(EXTRA_REQUIRED_INPUT);
if (requiredInput.mType != RequiredInputType.PASSPHRASE) { switch (requiredInput.mType) {
throw new AssertionError("Wrong required input type for PassphraseDialogActivity!"); case PASSPHRASE_SYMMETRIC: {
keyId = Constants.key.symmetric;
break;
} }
case PASSPHRASE: {
keyId = requiredInput.getSubKeyId(); keyId = requiredInput.getSubKeyId();
break;
}
default: {
throw new AssertionError("Unsupported required input type for PassphraseDialogActivity!");
}
}
} }
Intent serviceIntent = getIntent().getParcelableExtra(EXTRA_SERVICE_INTENT); Intent serviceIntent = getIntent().getParcelableExtra(EXTRA_SERVICE_INTENT);