diff options
Diffstat (limited to 'OpenKeychain/src')
25 files changed, 202 insertions, 1207 deletions
diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index b92d49d28..9b52bb788 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -671,12 +671,6 @@                taskAffinity and allowTaskReparenting somehow prevents this from happening!           -->          <activity -            android:name=".ui.NfcActivity" -            android:launchMode="singleTop" -            android:taskAffinity=":Nfc" -            android:allowTaskReparenting="true" /> - -        <activity              android:name=".ui.NfcOperationActivity"              android:launchMode="singleTop"              android:taskAffinity=":Nfc" diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java index b5552a40d..d718d231e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/SignEncryptOperation.java @@ -20,14 +20,21 @@ package org.sufficientlysecure.keychain.operations;  import android.content.Context;  import android.net.Uri; +import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;  import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;  import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;  import org.sufficientlysecure.keychain.operations.results.SignEncryptResult; +import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;  import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;  import org.sufficientlysecure.keychain.pgp.Progressable;  import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;  import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType;  import org.sufficientlysecure.keychain.util.FileHelper;  import org.sufficientlysecure.keychain.util.InputData;  import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -55,7 +62,7 @@ public class SignEncryptOperation extends BaseOperation {          super(context, providerHelper, progressable, cancelled);      } -    public SignEncryptResult execute(SignEncryptParcel input) { +    public SignEncryptResult execute(SignEncryptParcel input, CryptoInputParcel cryptoInput) {          OperationLog log = new OperationLog();          log.add(LogType.MSG_SE, 0); @@ -68,6 +75,20 @@ public class SignEncryptOperation extends BaseOperation {          int total = inputBytes != null ? 1 : inputUris.size(), count = 0;          ArrayList<PgpSignEncryptResult> results = new ArrayList<>(); +        NfcSignOperationsBuilder pendingInputBuilder = null; + +        if (input.getSignatureMasterKeyId() != Constants.key.none +                && input.getSignatureSubKeyId() == null) { +            try { +                long signKeyId = mProviderHelper.getCachedPublicKeyRing( +                        input.getSignatureMasterKeyId()).getSecretSignId(); +                input.setSignatureSubKeyId(signKeyId); +            } catch (PgpKeyNotFoundException e) { +                e.printStackTrace(); +                return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results); +            } +        } +          do {              if (checkCancelled()) { @@ -123,15 +144,22 @@ public class SignEncryptOperation extends BaseOperation {              PgpSignEncryptOperation op = new PgpSignEncryptOperation(mContext, mProviderHelper,                      new ProgressScaler(mProgressable, 100 * count / total, 100 * ++count / total, 100), mCancelled); -            PgpSignEncryptResult result = op.execute(input, inputData, outStream); +            PgpSignEncryptResult result = op.execute(input, cryptoInput, inputData, outStream);              results.add(result);              log.add(result, 2);              if (result.isPending()) { -                return new SignEncryptResult(SignEncryptResult.RESULT_PENDING, log, results); -            } - -            if (!result.success()) { +                RequiredInputParcel requiredInput = result.getRequiredInputParcel(); +                // Passphrase returns immediately, nfc are aggregated +                if (requiredInput.mType == RequiredInputType.PASSPHRASE) { +                    return new SignEncryptResult(log, requiredInput, results); +                } +                if (pendingInputBuilder == null) { +                    pendingInputBuilder = new NfcSignOperationsBuilder(requiredInput.mSignatureTime, +                            input.getSignatureMasterKeyId(), input.getSignatureSubKeyId()); +                } +                pendingInputBuilder.addAll(requiredInput); +            } else if (!result.success()) {                  return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log, results);              } @@ -141,9 +169,12 @@ public class SignEncryptOperation extends BaseOperation {          } while (!inputUris.isEmpty()); +        if (pendingInputBuilder != null && !pendingInputBuilder.isEmpty()) { +            return new SignEncryptResult(log, pendingInputBuilder.build(), results); +        } +          if (!outputUris.isEmpty()) { -            // Any output URIs left are indicative of a programming error -            log.add(LogType.MSG_SE_WARN_OUTPUT_LEFT, 1); +            throw new AssertionError("Got outputs left but no inputs. This is a programming error, please report!");          }          log.add(LogType.MSG_SE_SUCCESS, 1); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java index 45a6b98b8..0b7aa6d03 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/InputPendingResult.java @@ -18,6 +18,8 @@  package org.sufficientlysecure.keychain.operations.results; +import java.util.ArrayList; +  import android.os.Parcel;  import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index 47f9271e1..55d5d974a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -671,7 +671,6 @@ public abstract class OperationResult implements Parcelable {          MSG_SE_ERROR_INPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_input_uri_not_found),          MSG_SE_ERROR_OUTPUT_URI_NOT_FOUND (LogLevel.ERROR, R.string.msg_se_error_output_uri_not_found),          MSG_SE_ERROR_TOO_MANY_INPUTS (LogLevel.ERROR, R.string.msg_se_error_too_many_inputs), -        MSG_SE_WARN_OUTPUT_LEFT (LogLevel.WARN, R.string.msg_se_warn_output_left),          MSG_SE_SUCCESS (LogLevel.OK, R.string.msg_se_success),          // pgpsignencrypt diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java index bda9893dd..acb265462 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java @@ -19,78 +19,31 @@ package org.sufficientlysecure.keychain.operations.results;  import android.os.Parcel; -import org.sufficientlysecure.keychain.util.Passphrase; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -import java.util.Date; -public class PgpSignEncryptResult extends OperationResult { +public class PgpSignEncryptResult 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_PASSPHRASE = RESULT_PENDING + 16; -    public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32; - -    long mKeyIdPassphraseNeeded; - -    long mNfcKeyId; -    byte[] mNfcHash; -    int mNfcAlgo; -    Passphrase mNfcPassphrase;      byte[] mDetachedSignature; -    public long getKeyIdPassphraseNeeded() { -        return mKeyIdPassphraseNeeded; -    } - -    public void setKeyIdPassphraseNeeded(long keyIdPassphraseNeeded) { -        mKeyIdPassphraseNeeded = keyIdPassphraseNeeded; -    } - -    public void setNfcData(long nfcKeyId, byte[] nfcHash, int nfcAlgo, Passphrase passphrase) { -        mNfcKeyId = nfcKeyId; -        mNfcHash = nfcHash; -        mNfcAlgo = nfcAlgo; -        mNfcPassphrase = passphrase; -    } -      public void setDetachedSignature(byte[] detachedSignature) {          mDetachedSignature = detachedSignature;      } -    public long getNfcKeyId() { -        return mNfcKeyId; -    } - -    public byte[] getNfcHash() { -        return mNfcHash; -    } - -    public int getNfcAlgo() { -        return mNfcAlgo; -    } - -    public Passphrase getNfcPassphrase() { -        return mNfcPassphrase; -    } -      public byte[] getDetachedSignature() {          return mDetachedSignature;      } -    public boolean isPending() { -        return (mResult & RESULT_PENDING) == RESULT_PENDING; -    } -      public PgpSignEncryptResult(int result, OperationLog log) {          super(result, log);      } +    public PgpSignEncryptResult(OperationLog log, RequiredInputParcel requiredInput) { +        super(log, requiredInput); +    } +      public PgpSignEncryptResult(Parcel source) {          super(source); -        mNfcHash = source.readInt() != 0 ? source.createByteArray() : null; -        mNfcAlgo = source.readInt();          mDetachedSignature = source.readInt() != 0 ? source.createByteArray() : null;      } @@ -100,13 +53,6 @@ public class PgpSignEncryptResult extends OperationResult {      public void writeToParcel(Parcel dest, int flags) {          super.writeToParcel(dest, flags); -        if (mNfcHash != null) { -            dest.writeInt(1); -            dest.writeByteArray(mNfcHash); -        } else { -            dest.writeInt(0); -        } -        dest.writeInt(mNfcAlgo);          if (mDetachedSignature != null) {              dest.writeInt(1);              dest.writeByteArray(mDetachedSignature); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java index 87483ade9..b05921b0d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/SignEncryptResult.java @@ -21,22 +21,17 @@ import android.os.Parcel;  import java.util.ArrayList; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -public class SignEncryptResult extends OperationResult { + +public class SignEncryptResult extends InputPendingResult {      ArrayList<PgpSignEncryptResult> mResults;      byte[] mResultBytes; -    public static final int RESULT_PENDING = RESULT_ERROR + 8; - - -    public PgpSignEncryptResult getPending() { -        for (PgpSignEncryptResult sub : mResults) { -            if (sub.isPending()) { -                return sub; -            } -        } -        return null; +    public SignEncryptResult(OperationLog log, RequiredInputParcel requiredInput, ArrayList<PgpSignEncryptResult> results) { +        super(log, requiredInput); +        mResults = results;      }      public SignEncryptResult(int result, OperationLog log, ArrayList<PgpSignEncryptResult> results) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java index d5f3cf964..fd3c4910c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInputParcel.java @@ -42,14 +42,12 @@ public class PgpSignEncryptInputParcel implements Parcelable {      protected long mSignatureMasterKeyId = Constants.key.none;      protected Long mSignatureSubKeyId = null;      protected int mSignatureHashAlgorithm = PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED; -    protected Passphrase mSignaturePassphrase = null;      protected long mAdditionalEncryptId = Constants.key.none;      protected boolean mFailOnMissingEncryptionKeyIds = false;      protected String mCharset;      protected boolean mCleartextSignature;      protected boolean mDetachedSignature = false;      protected boolean mHiddenRecipients = false; -    protected CryptoInputParcel mCryptoInput = new CryptoInputParcel();      public PgpSignEncryptInputParcel() { @@ -69,15 +67,12 @@ public class PgpSignEncryptInputParcel implements Parcelable {          mSignatureMasterKeyId = source.readLong();          mSignatureSubKeyId = source.readInt() == 1 ? source.readLong() : null;          mSignatureHashAlgorithm = source.readInt(); -        mSignaturePassphrase = source.readParcelable(loader);          mAdditionalEncryptId = source.readLong();          mFailOnMissingEncryptionKeyIds = source.readInt() == 1;          mCharset = source.readString();          mCleartextSignature = source.readInt() == 1;          mDetachedSignature = source.readInt() == 1;          mHiddenRecipients = source.readInt() == 1; - -        mCryptoInput = source.readParcelable(loader);      }      @Override @@ -101,15 +96,12 @@ public class PgpSignEncryptInputParcel implements Parcelable {              dest.writeInt(0);          }          dest.writeInt(mSignatureHashAlgorithm); -        dest.writeParcelable(mSignaturePassphrase, 0);          dest.writeLong(mAdditionalEncryptId);          dest.writeInt(mFailOnMissingEncryptionKeyIds ? 1 : 0);          dest.writeString(mCharset);          dest.writeInt(mCleartextSignature ? 1 : 0);          dest.writeInt(mDetachedSignature ? 1 : 0);          dest.writeInt(mHiddenRecipients ? 1 : 0); - -        dest.writeParcelable(mCryptoInput, 0);      }      public String getCharset() { @@ -133,15 +125,6 @@ public class PgpSignEncryptInputParcel implements Parcelable {          return this;      } -    public Passphrase getSignaturePassphrase() { -        return mSignaturePassphrase; -    } - -    public PgpSignEncryptInputParcel  setSignaturePassphrase(Passphrase signaturePassphrase) { -        mSignaturePassphrase = signaturePassphrase; -        return this; -    } -      public int getSignatureHashAlgorithm() {          return mSignatureHashAlgorithm;      } @@ -255,19 +238,6 @@ public class PgpSignEncryptInputParcel implements Parcelable {          return mHiddenRecipients;      } -    public PgpSignEncryptInputParcel setCryptoInput(CryptoInputParcel cryptoInput) { -        mCryptoInput = cryptoInput; -        return this; -    } - -    public Map<ByteBuffer, byte[]> getCryptoData() { -        return mCryptoInput.getCryptoData(); -    } - -    public Date getSignatureTime() { -        return mCryptoInput.getSignatureTime(); -    } -      public static final Creator<PgpSignEncryptInputParcel> CREATOR = new Creator<PgpSignEncryptInputParcel>() {          public PgpSignEncryptInputParcel createFromParcel(final Parcel source) {              return new PgpSignEncryptInputParcel(source); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index ef19e3fa1..0b22df790 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -40,10 +40,13 @@ import org.sufficientlysecure.keychain.operations.BaseOperation;  import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;  import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;  import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; +import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;  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.ProviderHelper; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;  import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;  import org.sufficientlysecure.keychain.util.InputData;  import org.sufficientlysecure.keychain.util.Log; @@ -99,7 +102,7 @@ public class PgpSignEncryptOperation extends BaseOperation {      /**       * Signs and/or encrypts data based on parameters of class       */ -    public PgpSignEncryptResult execute(PgpSignEncryptInputParcel input, +    public PgpSignEncryptResult execute(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput,                                       InputData inputData, OutputStream outputStream) {          int indent = 0; @@ -145,62 +148,39 @@ public class PgpSignEncryptOperation extends BaseOperation {          CanonicalizedSecretKey signingKey = null;          if (enableSignature) { +            updateProgress(R.string.progress_extracting_signature_key, 0, 100); +              try {                  // fetch the indicated master key id (the one whose name we sign in)                  CanonicalizedSecretKeyRing signingKeyRing =                          mProviderHelper.getCanonicalizedSecretKeyRing(input.getSignatureMasterKeyId()); -                long signKeyId; -                // use specified signing subkey, or find the one to use -                if (input.getSignatureSubKeyId() == null) { -                    signKeyId = signingKeyRing.getSecretSignId(); -                } else { -                    signKeyId = input.getSignatureSubKeyId(); -                } -                  // fetch the specific subkey to sign with, or just use the master key if none specified -                signingKey = signingKeyRing.getSecretKey(signKeyId); - -            } catch (ProviderHelper.NotFoundException | PgpGeneralException e) { -                log.add(LogType.MSG_PSE_ERROR_SIGN_KEY, indent); -                return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); -            } - -            // Make sure we are allowed to sign here! -            if (!signingKey.canSign()) { -                log.add(LogType.MSG_PSE_ERROR_KEY_SIGN, indent); -                return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); -            } +                signingKey = signingKeyRing.getSecretKey(input.getSignatureSubKeyId()); -            // if no passphrase was explicitly set try to get it from the cache service -            if (input.getSignaturePassphrase() == null) { -                try { -                    // returns "" if key has no passphrase -                    input.setSignaturePassphrase(getCachedPassphrase(signingKey.getKeyId())); -                    // TODO -//                    log.add(LogType.MSG_DC_PASS_CACHED, indent + 1); -                } catch (PassphraseCacheInterface.NoSecretKeyException e) { -                    // TODO -//                    log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1); +                // Make sure we are allowed to sign here! +                if (!signingKey.canSign()) { +                    log.add(LogType.MSG_PSE_ERROR_KEY_SIGN, indent);                      return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);                  } -                // if passphrase was not cached, return here indicating that a passphrase is missing! -                if (input.getSignaturePassphrase() == null) { -                    log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1); -                    PgpSignEncryptResult result = new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE, log); -                    result.setKeyIdPassphraseNeeded(signingKey.getKeyId()); -                    return result; +                if (signingKey.getSecretKeyType() != SecretKeyType.DIVERT_TO_CARD) { +                    if (cryptoInput.getPassphrase() == null) { +                        log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1); +                        return new PgpSignEncryptResult(log, RequiredInputParcel.createRequiredPassphrase( +                                signingKeyRing.getMasterKeyId(), signingKey.getKeyId(), +                                cryptoInput.getSignatureTime())); +                    }                  } -            } -            updateProgress(R.string.progress_extracting_signature_key, 0, 100); - -            try { -                if (!signingKey.unlock(input.getSignaturePassphrase())) { +                if (!signingKey.unlock(cryptoInput.getPassphrase())) {                      log.add(LogType.MSG_PSE_ERROR_BAD_PASSPHRASE, indent);                      return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);                  } + +            } catch (ProviderHelper.NotFoundException e) { +                log.add(LogType.MSG_PSE_ERROR_SIGN_KEY, indent); +                return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);              } catch (PgpGeneralException e) {                  log.add(LogType.MSG_PSE_ERROR_UNLOCK, indent);                  return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); @@ -283,7 +263,7 @@ public class PgpSignEncryptOperation extends BaseOperation {                  boolean cleartext = input.isCleartextSignature() && input.isEnableAsciiArmorOutput() && !enableEncryption;                  signatureGenerator = signingKey.getDataSignatureGenerator(                          input.getSignatureHashAlgorithm(), cleartext, -                        input.getCryptoData(), input.getSignatureTime()); +                        cryptoInput.getCryptoData(), cryptoInput.getSignatureTime());              } catch (PgpGeneralException e) {                  log.add(LogType.MSG_PSE_ERROR_NFC, indent);                  return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); @@ -486,20 +466,8 @@ public class PgpSignEncryptOperation extends BaseOperation {                  } catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) {                      // this secret key diverts to a OpenPGP card, throw exception with hash that will be signed                      log.add(LogType.MSG_PSE_PENDING_NFC, indent); -                    PgpSignEncryptResult result = -                            new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_PENDING_NFC, log); - -                    // SignatureSubKeyId can be null. -                    if (input.getSignatureSubKeyId() == null) { -                        return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); -                    } - -                    // Note that the checked key here is the master key, not the signing key -                    // (although these are always the same on Yubikeys) -                    result.setNfcData(signingKey.getKeyId(), e.hashToSign, e.hashAlgo, -                            input.getSignaturePassphrase()); -                    Log.d(Constants.TAG, "e.hashToSign" + Hex.toHexString(e.hashToSign)); -                    return result; +                    return new PgpSignEncryptResult(log, RequiredInputParcel.createNfcSignOperation( +                            e.hashToSign, e.hashAlgo, cryptoInput.getSignatureTime()));                  }              } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java index b178e9515..464de37f5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java @@ -21,12 +21,9 @@ package org.sufficientlysecure.keychain.pgp;  import android.net.Uri;  import android.os.Parcel; -import org.sufficientlysecure.keychain.util.Passphrase; -  import java.util.ArrayList;  import java.util.Collection;  import java.util.Collections; -import java.util.Date;  import java.util.List;  /** This parcel stores the input of one or more PgpSignEncrypt operations. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 204af1b67..4760412ea 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -18,6 +18,7 @@  package org.sufficientlysecure.keychain.remote;  import android.app.PendingIntent; +import android.content.Context;  import android.content.Intent;  import android.database.Cursor;  import android.net.Uri; @@ -31,7 +32,6 @@ import org.openintents.openpgp.OpenPgpMetadata;  import org.openintents.openpgp.OpenPgpSignatureResult;  import org.openintents.openpgp.util.OpenPgpApi;  import org.spongycastle.bcpg.CompressionAlgorithmTags; -import org.spongycastle.util.encoders.Hex;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;  import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel; @@ -49,19 +49,18 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;  import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;  import org.sufficientlysecure.keychain.remote.ui.SelectSignKeyIdActivity;  import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;  import org.sufficientlysecure.keychain.ui.ImportKeysActivity; -import org.sufficientlysecure.keychain.ui.NfcActivity; +import org.sufficientlysecure.keychain.ui.NfcOperationActivity;  import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;  import org.sufficientlysecure.keychain.ui.ViewKeyActivity;  import org.sufficientlysecure.keychain.util.InputData;  import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.Passphrase;  import java.io.IOException;  import java.io.InputStream;  import java.io.OutputStream;  import java.util.ArrayList; -import java.util.Date;  import java.util.Set;  public class OpenPgpService extends RemoteService { @@ -79,9 +78,6 @@ public class OpenPgpService extends RemoteService {      /**       * Search database for key ids based on emails. -     * -     * @param encryptionUserIds -     * @return       */      private Intent returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds) {          boolean noUserIdsCheck = (encryptionUserIds == null || encryptionUserIds.length == 0); @@ -164,52 +160,35 @@ public class OpenPgpService extends RemoteService {          }      } -    private Intent returnPassphraseIntent(Intent data, long keyId) { -        // build PendingIntent for passphrase input -        Intent intent = new Intent(getBaseContext(), PassphraseDialogActivity.class); -        intent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID, keyId); -        // pass params through to activity that it can be returned again later to repeat pgp operation -        intent.putExtra(PassphraseDialogActivity.EXTRA_DATA, data); -        PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, -                intent, -                PendingIntent.FLAG_CANCEL_CURRENT); - -        // return PendingIntent to be executed by client -        Intent result = new Intent(); -        result.putExtra(OpenPgpApi.RESULT_INTENT, pi); -        result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); -        return result; -    } +    private static PendingIntent getRequiredInputPendingIntent(Context context, +            Intent data, RequiredInputParcel requiredInput) { + +        switch (requiredInput.mType) { +            case NFC_DECRYPT: +            case NFC_SIGN: { +                // build PendingIntent for Yubikey NFC operations +                Intent intent = new Intent(context, NfcOperationActivity.class); +                // pass params through to activity that it can be returned again later to repeat pgp operation +                intent.putExtra(NfcOperationActivity.EXTRA_SERVICE_INTENT, data); +                intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, requiredInput); +                return PendingIntent.getActivity(context, 0, intent, +                        PendingIntent.FLAG_CANCEL_CURRENT); +            } -    private PendingIntent getNfcSignPendingIntent(Intent data, long keyId, Passphrase pin, byte[] hashToSign, int hashAlgo) { -        // build PendingIntent for Yubikey NFC operations -        Intent intent = new Intent(getBaseContext(), NfcActivity.class); -        intent.setAction(NfcActivity.ACTION_SIGN_HASH); -        // pass params through to activity that it can be returned again later to repeat pgp operation -        intent.putExtra(NfcActivity.EXTRA_DATA, data); -        intent.putExtra(NfcActivity.EXTRA_PIN, pin); -        intent.putExtra(NfcActivity.EXTRA_KEY_ID, keyId); - -        intent.putExtra(NfcActivity.EXTRA_NFC_HASH_TO_SIGN, hashToSign); -        intent.putExtra(NfcActivity.EXTRA_NFC_HASH_ALGO, hashAlgo); -        return PendingIntent.getActivity(getBaseContext(), 0, -                intent, -                PendingIntent.FLAG_CANCEL_CURRENT); -    } +            case PASSPHRASE: { +                // build PendingIntent for Passphrase request +                Intent intent = new Intent(context, PassphraseDialogActivity.class); +                // pass params through to activity that it can be returned again later to repeat pgp operation +                intent.putExtra(PassphraseDialogActivity.EXTRA_SERVICE_INTENT, data); +                intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput); +                return PendingIntent.getActivity(context, 0, intent, +                        PendingIntent.FLAG_CANCEL_CURRENT); +            } -    private PendingIntent getNfcDecryptPendingIntent(Intent data, long subKeyId, Passphrase pin, byte[] encryptedSessionKey) { -        // build PendingIntent for Yubikey NFC operations -        Intent intent = new Intent(getBaseContext(), NfcActivity.class); -        intent.setAction(NfcActivity.ACTION_DECRYPT_SESSION_KEY); -        // pass params through to activity that it can be returned again later to repeat pgp operation -        intent.putExtra(NfcActivity.EXTRA_DATA, data); -        intent.putExtra(NfcActivity.EXTRA_PIN, pin); -        intent.putExtra(NfcActivity.EXTRA_KEY_ID, subKeyId); +            default: +                throw new AssertionError("Unhandled required input type!"); +        } -        intent.putExtra(NfcActivity.EXTRA_NFC_ENC_SESSION_KEY, encryptedSessionKey); -        return PendingIntent.getActivity(getBaseContext(), 0, -                intent, -                PendingIntent.FLAG_CANCEL_CURRENT);      }      private PendingIntent getKeyserverPendingIntent(Intent data, long masterKeyId) { @@ -241,18 +220,6 @@ public class OpenPgpService extends RemoteService {          try {              boolean asciiArmor = cleartextSign || data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); -            Passphrase passphrase = null; -            if (data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE) != null) { -                passphrase = new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)); -            } - -            byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH); -            if (nfcSignedHash != null) { -                Log.d(Constants.TAG, "nfcSignedHash:" + Hex.toHexString(nfcSignedHash)); -            } else { -                Log.d(Constants.TAG, "nfcSignedHash: null"); -            } -              Intent signKeyIdIntent = getSignKeyMasterId(data);              // NOTE: Fallback to return account settings (Old API)              if (signKeyIdIntent.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR) @@ -264,16 +231,6 @@ public class OpenPgpService extends RemoteService {                  Log.e(Constants.TAG, "No signing key given!");              } -            // carefully: only set if timestamp exists -            Date nfcCreationDate; -            long nfcCreationTimestamp = data.getLongExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, -1); -            Log.d(Constants.TAG, "nfcCreationTimestamp: " + nfcCreationTimestamp); -            if (nfcCreationTimestamp != -1) { -                nfcCreationDate = new Date(nfcCreationTimestamp); -            } else { -                nfcCreationDate = new Date(); -            } -              // Get Input- and OutputStream from ParcelFileDescriptor              is = new ParcelFileDescriptor.AutoCloseInputStream(input);              if (cleartextSign) { @@ -284,45 +241,32 @@ public class OpenPgpService extends RemoteService {              long inputLength = is.available();              InputData inputData = new InputData(is, inputLength); -            CryptoInputParcel cryptoInput = new CryptoInputParcel(nfcCreationDate); -            cryptoInput.addCryptoData(null, nfcSignedHash); // TODO fix +            CryptoInputParcel cryptoInput = data.getParcelableExtra(OpenPgpApi.EXTRA_CRYPTO_INPUT);              // sign-only              PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel() -                    .setSignaturePassphrase(passphrase)                      .setEnableAsciiArmorOutput(asciiArmor)                      .setCleartextSignature(cleartextSign)                      .setDetachedSignature(!cleartextSign)                      .setVersionHeader(null)                      .setSignatureHashAlgorithm(PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED) -                    .setSignatureMasterKeyId(signKeyId) -                    .setCryptoInput(cryptoInput); +                    .setSignatureMasterKeyId(signKeyId);              // execute PGP operation!              PgpSignEncryptOperation pse = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null); -            PgpSignEncryptResult pgpResult = pse.execute(pseInput, inputData, os); +            PgpSignEncryptResult pgpResult = pse.execute(pseInput, cryptoInput, inputData, os);              if (pgpResult.isPending()) { -                if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) == -                        PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) { -                    return returnPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded()); -                } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) == -                        PgpSignEncryptResult.RESULT_PENDING_NFC) { -                    // return PendingIntent to execute NFC activity -                    // pass through the signature creation timestamp to be used again on second execution -                    // of PgpSignEncrypt when we have the signed hash! -                    data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, nfcCreationDate.getTime()); - -                    // return PendingIntent to be executed by client -                    Intent result = new Intent(); -                    result.putExtra(OpenPgpApi.RESULT_INTENT, -                            getNfcSignPendingIntent(data, pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcHash(), pgpResult.getNfcAlgo())); -                    result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); -                    return result; -                } else { -                    throw new PgpGeneralException( -                            "Encountered unhandled type of pending action not supported by API!"); -                } + +                RequiredInputParcel requiredInput = pgpResult.getRequiredInputParcel(); +                PendingIntent pIntent = getRequiredInputPendingIntent(getBaseContext(), data, requiredInput); + +                // return PendingIntent to be executed by client +                Intent result = new Intent(); +                result.putExtra(OpenPgpApi.RESULT_INTENT, pIntent); +                result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); +                return result; +              } else if (pgpResult.success()) {                  Intent result = new Intent();                  if (pgpResult.getDetachedSignature() != null && !cleartextSign) { @@ -378,11 +322,6 @@ public class OpenPgpService extends RemoteService {                  compressionId = CompressionAlgorithmTags.UNCOMPRESSED;              } -            Passphrase passphrase = null; -            if (data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE) != null) { -                passphrase = new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)); -            } -              // first try to get key ids from non-ambiguous key id extra              long[] keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);              if (keyIds == null) { @@ -408,8 +347,7 @@ public class OpenPgpService extends RemoteService {              InputData inputData = new InputData(is, inputLength, originalFilename);              PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(); -            pseInput.setSignaturePassphrase(passphrase) -                    .setEnableAsciiArmorOutput(asciiArmor) +            pseInput.setEnableAsciiArmorOutput(asciiArmor)                      .setVersionHeader(null)                      .setCompressionId(compressionId)                      .setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED) @@ -429,51 +367,28 @@ public class OpenPgpService extends RemoteService {                      Log.e(Constants.TAG, "No signing key given!");                  } -                byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH); -                // carefully: only set if timestamp exists -                Date nfcCreationDate; -                long nfcCreationTimestamp = data.getLongExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, -1); -                if (nfcCreationTimestamp != -1) { -                    nfcCreationDate = new Date(nfcCreationTimestamp); -                } else { -                    nfcCreationDate = new Date(); -                } - -                CryptoInputParcel cryptoInput = new CryptoInputParcel(nfcCreationDate); -                cryptoInput.addCryptoData(null, nfcSignedHash); // TODO fix! -                  // sign and encrypt                  pseInput.setSignatureHashAlgorithm(PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED)                          .setSignatureMasterKeyId(signKeyId) -                        .setCryptoInput(cryptoInput)                          .setAdditionalEncryptId(signKeyId); // add sign key for encryption              } +            CryptoInputParcel cryptoInput = data.getParcelableExtra(OpenPgpApi.EXTRA_CRYPTO_INPUT); +              PgpSignEncryptOperation op = new PgpSignEncryptOperation(this, new ProviderHelper(getContext()), null);              // execute PGP operation! -            PgpSignEncryptResult pgpResult = op.execute(pseInput, inputData, os); +            PgpSignEncryptResult pgpResult = op.execute(pseInput, cryptoInput, inputData, os);              if (pgpResult.isPending()) { -                if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) == -                        PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) { -                    return returnPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded()); -                } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) == -                        PgpSignEncryptResult.RESULT_PENDING_NFC) { -                    // return PendingIntent to execute NFC activity -                    // pass through the signature creation timestamp to be used again on second execution -                    // of PgpSignEncrypt when we have the signed hash! -                    data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, 0L); // TODO fix -                    // return PendingIntent to be executed by client -                    Intent result = new Intent(); -                    result.putExtra(OpenPgpApi.RESULT_INTENT, -                            getNfcSignPendingIntent(data, pgpResult.getNfcKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcHash(), pgpResult.getNfcAlgo())); -                    result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); -                    return result; -                } else { -                    throw new PgpGeneralException( -                            "Encountered unhandled type of pending action not supported by API!"); -                } +                RequiredInputParcel requiredInput = pgpResult.getRequiredInputParcel(); +                PendingIntent pIntent = getRequiredInputPendingIntent(getBaseContext(), data, requiredInput); + +                // return PendingIntent to be executed by client +                Intent result = new Intent(); +                result.putExtra(OpenPgpApi.RESULT_INTENT, pIntent); +                result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); +                return result;              } else if (pgpResult.success()) {                  Intent result = new Intent();                  result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); @@ -522,11 +437,6 @@ public class OpenPgpService extends RemoteService {                  os = new ParcelFileDescriptor.AutoCloseOutputStream(output);              } -            Passphrase passphrase = null; -            if (data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE) != null) { -                passphrase = new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE)); -            } -              String currentPkg = getCurrentCallingPackage();              Set<Long> allowedKeyIds;              if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) { @@ -544,17 +454,17 @@ public class OpenPgpService extends RemoteService {                      this, new ProviderHelper(getContext()), null, inputData, os              ); -            byte[] nfcDecryptedSessionKey = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_DECRYPTED_SESSION_KEY); +            CryptoInputParcel cryptoInput = data.getParcelableExtra(OpenPgpApi.EXTRA_CRYPTO_INPUT);              byte[] detachedSignature = data.getByteArrayExtra(OpenPgpApi.EXTRA_DETACHED_SIGNATURE);              // allow only private keys associated with accounts of this app              // no support for symmetric encryption -            builder.setPassphrase(passphrase) +            builder.setPassphrase(cryptoInput.getPassphrase()) // TODO proper CryptoInputParcel support                      .setAllowSymmetricDecryption(false)                      .setAllowedKeyIds(allowedKeyIds)                      .setDecryptMetadataOnly(decryptMetadataOnly) -                    .setNfcState(nfcDecryptedSessionKey) +                    .setNfcState(null) // TODO proper CryptoInputParcel support                      .setDetachedSignature(detachedSignature);              DecryptVerifyResult pgpResult = builder.build().execute(); @@ -562,20 +472,15 @@ public class OpenPgpService extends RemoteService {              if (pgpResult.isPending()) {                  if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) ==                          DecryptVerifyResult.RESULT_PENDING_ASYM_PASSPHRASE) { -                    return returnPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded()); +                    throw new AssertionError("not implemented"); // TODO +                    // return returnPassphraseIntent(data, pgpResult.getKeyIdPassphraseNeeded());                  } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) ==                          DecryptVerifyResult.RESULT_PENDING_SYM_PASSPHRASE) {                      throw new PgpGeneralException(                              "Decryption of symmetric content not supported by API!");                  } else if ((pgpResult.getResult() & DecryptVerifyResult.RESULT_PENDING_NFC) ==                          DecryptVerifyResult.RESULT_PENDING_NFC) { - -                    // return PendingIntent to be executed by client -                    Intent result = new Intent(); -                    result.putExtra(OpenPgpApi.RESULT_INTENT, -                            getNfcDecryptPendingIntent(data, pgpResult.getNfcSubKeyId(), pgpResult.getNfcPassphrase(), pgpResult.getNfcEncryptedSessionKey())); -                    result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); -                    return result; +                    throw new AssertionError("not implemented"); // TODO                  } else {                      throw new PgpGeneralException(                              "Encountered unhandled type of pending action not supported by API!"); @@ -765,7 +670,6 @@ public class OpenPgpService extends RemoteService {       * - has supported API version       * - is allowed to call the service (access has been granted)       * -     * @param data       * @return null if everything is okay, or a Bundle with an error/PendingIntent       */      private Intent checkRequirements(Intent data) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 1a94d70b7..c7d9d5e38 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -46,7 +46,6 @@ import org.sufficientlysecure.keychain.operations.results.CertifyResult;  import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;  import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;  import org.sufficientlysecure.keychain.operations.results.DeleteResult; -import org.sufficientlysecure.keychain.operations.results.EditKeyResult;  import org.sufficientlysecure.keychain.operations.results.ExportResult;  import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;  import org.sufficientlysecure.keychain.operations.results.OperationResult; @@ -284,14 +283,13 @@ public class KeychainIntentService extends IntentService implements Progressable              case ACTION_DECRYPT_METADATA: {                  try { -                /* Input */ +                    /* Input */                      Passphrase passphrase = data.getParcelable(DECRYPT_PASSPHRASE);                      byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);                      InputData inputData = createDecryptInputData(data); -                /* Operation */ - +                    /* Operation */                      Bundle resultData = new Bundle();                      // verifyText and decrypt returning additional resultData values for the @@ -549,11 +547,12 @@ public class KeychainIntentService extends IntentService implements Progressable                  // Input                  SignEncryptParcel inputParcel = data.getParcelable(SIGN_ENCRYPT_PARCEL); +                CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);                  // Operation                  SignEncryptOperation op = new SignEncryptOperation(                          this, new ProviderHelper(this), this, mActionCanceled); -                SignEncryptResult result = op.execute(inputParcel); +                SignEncryptResult result = op.execute(inputParcel, cryptoInput);                  // Result                  sendMessageToHandler(MessageStatus.OKAY, result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java index 471fc0ec9..5cc2607cc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java @@ -1,6 +1,7 @@  package org.sufficientlysecure.keychain.service.input;  import java.util.ArrayList; +import java.util.Arrays;  import java.util.Collections;  import java.util.Date; @@ -56,11 +57,11 @@ public class RequiredInputParcel implements Parcelable {      } -    public long getMasterKeyId() { +    public Long getMasterKeyId() {          return mMasterKeyId;      } -    public long getSubKeyId() { +    public Long getSubKeyId() {          return mSubKeyId;      } @@ -88,7 +89,6 @@ public class RequiredInputParcel implements Parcelable {                  null, null, req.mSignatureTime, req.mMasterKeyId, req.mSubKeyId);      } -      @Override      public int describeContents() {          return 0; @@ -142,10 +142,10 @@ public class RequiredInputParcel implements Parcelable {          Date mSignatureTime;          ArrayList<Integer> mSignAlgos = new ArrayList<>();          ArrayList<byte[]> mInputHashes = new ArrayList<>(); -        long mMasterKeyId; -        long mSubKeyId; +        Long mMasterKeyId; +        Long mSubKeyId; -        public NfcSignOperationsBuilder(Date signatureTime, long masterKeyId, long subKeyId) { +        public NfcSignOperationsBuilder(Date signatureTime, Long masterKeyId, Long subKeyId) {              mSignatureTime = signatureTime;              mMasterKeyId = masterKeyId;              mSubKeyId = subKeyId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CryptoOperationFragment.java index 5227c1477..b632509bb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CryptoOperationFragment.java @@ -66,7 +66,7 @@ public abstract class CryptoOperationFragment extends Fragment {              case REQUEST_CODE_PASSPHRASE: {                  if (resultCode == Activity.RESULT_OK && data != null) {                      CryptoInputParcel cryptoInput = -                            data.getParcelableExtra(PassphraseDialogActivity.RESULT_DATA); +                            data.getParcelableExtra(PassphraseDialogActivity.RESULT_CRYPTO_INPUT);                      cryptoOperation(cryptoInput);                      return;                  } @@ -110,6 +110,10 @@ public abstract class CryptoOperationFragment extends Fragment {          return false;      } +    protected void cryptoOperation() { +        cryptoOperation(new CryptoInputParcel()); +    } +      protected abstract void cryptoOperation(CryptoInputParcel cryptoInput);  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index ecc99b348..d1c005868 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -198,7 +198,7 @@ public class DecryptFilesFragment extends DecryptFragment {  //        data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase);  //        data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey);  // -//        intent.putExtra(KeychainIntentService.EXTRA_DATA, data); +//        intent.putExtra(KeychainIntentService.EXTRA_SERVICE_INTENT, data);  //  //        // Message is received after decrypting is done in KeychainIntentService  //        ServiceProgressHandler saveHandler = new ServiceProgressHandler( diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index f00136d5b..38ad54ad3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -105,7 +105,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment {  //        // build PendingIntent for Yubikey NFC operations  //        Intent intent = new Intent(getActivity(), NfcActivity.class);  //        intent.setAction(NfcActivity.ACTION_DECRYPT_SESSION_KEY); -//        intent.putExtra(NfcActivity.EXTRA_DATA, new Intent()); // not used, only relevant to OpenPgpService +//        intent.putExtra(NfcActivity.EXTRA_SERVICE_INTENT, new Intent()); // not used, only relevant to OpenPgpService  //        intent.putExtra(NfcActivity.EXTRA_KEY_ID, subKeyId);  //        intent.putExtra(NfcActivity.EXTRA_PIN, pin);  // diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java deleted file mode 100644 index a1edf808c..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> - * - * 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.ui; - -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.Intent; -import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.view.View; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; -import org.sufficientlysecure.keychain.operations.results.SignEncryptResult; -import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; -import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -import org.sufficientlysecure.keychain.ui.base.BaseActivity; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; -import org.sufficientlysecure.keychain.util.Passphrase; - -public abstract class EncryptActivity extends BaseActivity { - -    public static final int REQUEST_CODE_PASSPHRASE = 0x00008001; -    public static final int REQUEST_CODE_NFC = 0x00008002; - -    // For NFC data -    protected Passphrase mSigningKeyPassphrase = null; - -    @Override -    public void onCreate(Bundle savedInstanceState) { -        super.onCreate(savedInstanceState); - -        setFullScreenDialogClose(new View.OnClickListener() { -            @Override -            public void onClick(View v) { -                setResult(Activity.RESULT_CANCELED); -                finish(); -            } -        }, false); -    } - -    protected void startPassphraseDialog(long subkeyId) { -        Intent intent = new Intent(this, PassphraseDialogActivity.class); -        intent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID, subkeyId); -        startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); -    } - -    protected void startNfcSign(long keyId, RequiredInputParcel nfcOps) { - -        Intent intent = new Intent(this, NfcOperationActivity.class); -        intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, nfcOps); -        // TODO respect keyid(?) - -        startActivityForResult(intent, REQUEST_CODE_NFC); -    } - -    @Override -    protected void onActivityResult(int requestCode, int resultCode, Intent data) { -        switch (requestCode) { -            case REQUEST_CODE_PASSPHRASE: { -                if (resultCode == RESULT_OK && data != null) { -                    mSigningKeyPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); -                    startEncrypt(); -                    return; -                } -                break; -            } - -            case REQUEST_CODE_NFC: { -                if (resultCode == RESULT_OK && data != null) { -                    CryptoInputParcel cryptoInput = -                            data.getParcelableExtra(NfcOperationActivity.RESULT_DATA); -                    startEncrypt(cryptoInput); -                    return; -                } -                break; -            } - -            default: { -                super.onActivityResult(requestCode, resultCode, data); -                break; -            } -        } -    } - -    public void startEncrypt() { -        startEncrypt(null); -    } - -    public void startEncrypt(CryptoInputParcel cryptoInput) { -        if (!inputIsValid()) { -            // Notify was created by inputIsValid. -            return; -        } - -        // Send all information needed to service to edit key in other thread -        Intent intent = new Intent(this, KeychainIntentService.class); -        intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT); - -        final SignEncryptParcel input = createEncryptBundle(); -        if (cryptoInput != null) { -            input.setCryptoInput(cryptoInput); -        } - -        Bundle data = new Bundle(); -        data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input); -        intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - -        // Message is received after encrypting is done in KeychainIntentService -        ServiceProgressHandler serviceHandler = new ServiceProgressHandler( -                this, -                getString(R.string.progress_encrypting), -                ProgressDialog.STYLE_HORIZONTAL, -                ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) { -            public void handleMessage(Message message) { -                // handle messages by standard KeychainIntentServiceHandler first -                super.handleMessage(message); - -                if (message.arg1 == MessageStatus.OKAY.ordinal()) { -                    SignEncryptResult result = -                            message.getData().getParcelable(SignEncryptResult.EXTRA_RESULT); - -                    PgpSignEncryptResult pgpResult = result.getPending(); - -                    if (pgpResult != null && pgpResult.isPending()) { -                        if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) == -                                PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) { -                            startPassphraseDialog(pgpResult.getKeyIdPassphraseNeeded()); -                        } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) == -                                PgpSignEncryptResult.RESULT_PENDING_NFC) { - -                            RequiredInputParcel parcel = RequiredInputParcel.createNfcSignOperation( -                                    pgpResult.getNfcHash(), -                                    pgpResult.getNfcAlgo(), -                                    input.getSignatureTime()); -                            startNfcSign(pgpResult.getNfcKeyId(), parcel); - -                        } else { -                            throw new RuntimeException("Unhandled pending result!"); -                        } -                        return; -                    } - -                    if (result.success()) { -                        onEncryptSuccess(result); -                    } else { -                        result.createNotify(EncryptActivity.this).show(); -                    } - -                    // no matter the result, reset parameters -                    mSigningKeyPassphrase = null; -                } -            } -        }; -        // Create a new Messenger for the communication back -        Messenger messenger = new Messenger(serviceHandler); -        intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - -        // show progress dialog -        serviceHandler.showProgressDialog(this); - -        // start service with intent -        startService(intent); -    } - -    protected abstract boolean inputIsValid(); - -    protected abstract void onEncryptSuccess(SignEncryptResult result); - -    protected abstract SignEncryptParcel createEncryptBundle(); - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index dad8704fb..1a67bc8dd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -137,7 +137,7 @@ public class EncryptFilesFragment extends CryptoOperationFragment {          try {              mModeInterface = (IMode) activity;          } catch (ClassCastException e) { -            throw new ClassCastException(activity.toString() + " must be IMode"); +            throw new ClassCastException(activity + " must be IMode");          }      } @@ -369,11 +369,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment {          return true;      } -    public void startEncrypt(boolean share) { -        mShareAfterEncrypt = share; -        cryptoOperation(new CryptoInputParcel()); -    } -      public void onEncryptSuccess(final SignEncryptResult result) {          if (mDeleteAfterEncrypt) {              DeleteFileDialogFragment deleteFileDialog = @@ -479,6 +474,11 @@ public class EncryptFilesFragment extends CryptoOperationFragment {          return sendIntent;      } +    public void startEncrypt(boolean share) { +        mShareAfterEncrypt = share; +        cryptoOperation(); +    } +      @Override      protected void cryptoOperation(CryptoInputParcel cryptoInput) { @@ -494,12 +494,10 @@ public class EncryptFilesFragment extends CryptoOperationFragment {          intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);          final SignEncryptParcel input = createEncryptBundle(); -        if (cryptoInput != null) { -            input.setCryptoInput(cryptoInput); -        }          Bundle data = new Bundle();          data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input); +        data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);          intent.putExtra(KeychainIntentService.EXTRA_DATA, data);          // Message is received after encrypting is done in KeychainIntentService @@ -521,36 +519,11 @@ public class EncryptFilesFragment extends CryptoOperationFragment {                  if (message.arg1 == MessageStatus.OKAY.ordinal()) {                      SignEncryptResult result =                              message.getData().getParcelable(SignEncryptResult.EXTRA_RESULT); - -//                    PgpSignEncryptResult pgpResult = result.getPending(); -// -//                    if (pgpResult != null && pgpResult.isPending()) { -//                        if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) == -//                                PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) { -//                            startPassphraseDialog(pgpResult.getKeyIdPassphraseNeeded()); -//                        } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) == -//                                PgpSignEncryptResult.RESULT_PENDING_NFC) { -// -//                            RequiredInputParcel parcel = RequiredInputParcel.createNfcSignOperation( -//                                    pgpResult.getNfcHash(), -//                                    pgpResult.getNfcAlgo(), -//                                    input.getSignatureTime()); -//                            startNfcSign(pgpResult.getNfcKeyId(), parcel); -// -//                        } else { -//                            throw new RuntimeException("Unhandled pending result!"); -//                        } -//                        return; -//                    } -                      if (result.success()) {                          onEncryptSuccess(result);                      } else {                          result.createNotify(getActivity()).show();                      } - -                    // no matter the result, reset parameters -//                    mSigningKeyPassphrase = null;                  }              }          }; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java index 2ffb29b09..03ab48e23 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java @@ -160,6 +160,6 @@ public class EncryptTextActivity extends BaseActivity implements      @Override      public void onPassphraseChanged(Passphrase passphrase) { -        mEncryptFragment.setPassphrase(passphrase); +        mEncryptFragment.setSymmetricPassphrase(passphrase);      }  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index 3303b2c65..fecc9ef52 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -37,7 +37,6 @@ import org.spongycastle.bcpg.CompressionAlgorithmTags;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; -import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;  import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;  import org.sufficientlysecure.keychain.pgp.KeyRing;  import org.sufficientlysecure.keychain.pgp.PgpConstants; @@ -73,7 +72,7 @@ public class EncryptTextFragment extends CryptoOperationFragment {      private String mEncryptionUserIds[] = null;      // TODO Constants.key.none? What's wrong with a null value?      private long mSigningKeyId = Constants.key.none; -    private Passphrase mPassphrase = new Passphrase(); +    private Passphrase mSymmetricPassphrase = new Passphrase();      private String mMessage = "";      private TextView mText; @@ -90,8 +89,8 @@ public class EncryptTextFragment extends CryptoOperationFragment {          mSigningKeyId = signingKeyId;      } -    public void setPassphrase(Passphrase passphrase) { -        mPassphrase = passphrase; +    public void setSymmetricPassphrase(Passphrase passphrase) { +        mSymmetricPassphrase = passphrase;      }      /** @@ -233,7 +232,7 @@ public class EncryptTextFragment extends CryptoOperationFragment {          if (mSymmetricMode) {              Log.d(Constants.TAG, "Symmetric encryption enabled!"); -            Passphrase passphrase = mPassphrase; +            Passphrase passphrase = mSymmetricPassphrase;              if (passphrase.isEmpty()) {                  passphrase = null;              } @@ -241,7 +240,6 @@ public class EncryptTextFragment extends CryptoOperationFragment {          } else {              data.setEncryptionMasterKeyIds(mEncryptionKeyIds);              data.setSignatureMasterKeyId(mSigningKeyId); -//            data.setSignaturePassphrase(mSigningKeyPassphrase);          }          return data;      } @@ -296,12 +294,12 @@ public class EncryptTextFragment extends CryptoOperationFragment {          if (mSymmetricMode) {              // symmetric encryption checks -            if (mPassphrase == null) { +            if (mSymmetricPassphrase == null) {                  Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR)                          .show();                  return false;              } -            if (mPassphrase.isEmpty()) { +            if (mSymmetricPassphrase.isEmpty()) {                  Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)                          .show();                  return false; @@ -325,11 +323,7 @@ public class EncryptTextFragment extends CryptoOperationFragment {      public void startEncrypt(boolean share) {          mShareAfterEncrypt = share; -        startEncrypt(); -    } - -    public void startEncrypt() { -        cryptoOperation(null); +        cryptoOperation();      }      @Override @@ -344,12 +338,9 @@ public class EncryptTextFragment extends CryptoOperationFragment {          intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);          final SignEncryptParcel input = createEncryptBundle(); -        if (cryptoInput != null) { -            input.setCryptoInput(cryptoInput); -        } -          final Bundle data = new Bundle();          data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input); +        data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);          intent.putExtra(KeychainIntentService.EXTRA_DATA, data);          // Message is received after encrypting is done in KeychainIntentService @@ -362,45 +353,19 @@ public class EncryptTextFragment extends CryptoOperationFragment {                  // handle messages by standard KeychainIntentServiceHandler first                  super.handleMessage(message); -                // TODO: We need a InputPendingResult! -//                // handle pending messages -//                if (handlePendingMessage(message)) { -//                    return; -//                } +                if (handlePendingMessage(message)) { +                    return; +                }                  if (message.arg1 == MessageStatus.OKAY.ordinal()) {                      SignEncryptResult result =                              message.getData().getParcelable(SignEncryptResult.EXTRA_RESULT); -                    PgpSignEncryptResult pgpResult = result.getPending(); - -//                    if (pgpResult != null && pgpResult.isPending()) { -//                        if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) == -//                                PgpSignEncryptResult.RESULT_PENDING_PASSPHRASE) { -//                            startPassphraseDialog(pgpResult.getKeyIdPassphraseNeeded()); -//                        } else if ((pgpResult.getResult() & PgpSignEncryptResult.RESULT_PENDING_NFC) == -//                                PgpSignEncryptResult.RESULT_PENDING_NFC) { -// -//                            RequiredInputParcel parcel = RequiredInputParcel.createNfcSignOperation( -//                                    pgpResult.getNfcHash(), -//                                    pgpResult.getNfcAlgo(), -//                                    input.getSignatureTime()); -//                            startNfcSign(pgpResult.getNfcKeyId(), parcel); -// -//                        } else { -//                            throw new RuntimeException("Unhandled pending result!"); -//                        } -//                        return; -//                    } -                      if (result.success()) {                          onEncryptSuccess(result);                      } else {                          result.createNotify(getActivity()).show();                      } - -                    // no matter the result, reset parameters -//                    mSigningKeyPassphrase = null;                  }              }          }; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java deleted file mode 100644 index 57acf3e93..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcActivity.java +++ /dev/null @@ -1,569 +0,0 @@ -/** - * Copyright (c) 2013-2014 Philipp Jakubeit, Signe Rüsch, Dominik Schürmann - * - * Licensed under the Bouncy Castle License (MIT license). See LICENSE file for details. - */ - -package org.sufficientlysecure.keychain.ui; - -import android.annotation.TargetApi; -import android.app.PendingIntent; -import android.content.Intent; -import android.content.IntentFilter; -import android.nfc.NfcAdapter; -import android.nfc.Tag; -import android.nfc.tech.IsoDep; -import android.os.Build; -import android.os.Bundle; -import android.view.WindowManager; -import android.widget.Toast; - -import org.spongycastle.bcpg.HashAlgorithmTags; -import org.spongycastle.util.encoders.Hex; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.base.BaseActivity; -import org.sufficientlysecure.keychain.util.Iso7816TLV; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * This class provides a communication interface to OpenPGP applications on ISO SmartCard compliant - * NFC devices. - * - * For the full specs, see http://g10code.com/docs/openpgp-card-2.0.pdf - */ -@TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1) -public class NfcActivity extends BaseActivity { - -    // actions -    public static final String ACTION_SIGN_HASH = "sign_hash"; -    public static final String ACTION_DECRYPT_SESSION_KEY = "decrypt_session_key"; - -    // always -    public static final String EXTRA_KEY_ID = "key_id"; -    public static final String EXTRA_PIN = "pin"; -    // special extra for OpenPgpService -    public static final String EXTRA_DATA = "data"; - -    // sign -    public static final String EXTRA_NFC_HASH_TO_SIGN = "nfc_hash"; -    public static final String EXTRA_NFC_HASH_ALGO = "nfc_hash_algo"; - -    // decrypt -    public static final String EXTRA_NFC_ENC_SESSION_KEY = "encrypted_session_key"; - -    private Intent mServiceIntent; - -    private static final int TIMEOUT = 100000; - -    private NfcAdapter mNfcAdapter; -    private IsoDep mIsoDep; -    private String mAction; - -    private String mPin; -    private Long mKeyId; - -    // sign -    private byte[] mHashToSign; -    private int mHashAlgo; - -    // decrypt -    private byte[] mEncryptedSessionKey; - -    @Override -    protected void onCreate(Bundle savedInstanceState) { -        super.onCreate(savedInstanceState); -        Log.d(Constants.TAG, "NfcActivity.onCreate"); - -        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - -        Intent intent = getIntent(); -        Bundle data = intent.getExtras(); -        String action = intent.getAction(); - -        // if we get are passed a key id, save it for the check -        if (data.containsKey(EXTRA_KEY_ID)) { -            mKeyId = data.getLong(EXTRA_KEY_ID); -        } - -        switch (action) { -            case ACTION_SIGN_HASH: -                mAction = action; -                mPin = data.getString(EXTRA_PIN); -                mHashToSign = data.getByteArray(EXTRA_NFC_HASH_TO_SIGN); -                mHashAlgo = data.getInt(EXTRA_NFC_HASH_ALGO); -                mServiceIntent = data.getParcelable(EXTRA_DATA); - -                Log.d(Constants.TAG, "NfcActivity mAction: " + mAction); -                Log.d(Constants.TAG, "NfcActivity mPin: " + mPin); -                Log.d(Constants.TAG, "NfcActivity mHashToSign as hex: " + getHex(mHashToSign)); -                Log.d(Constants.TAG, "NfcActivity mServiceIntent: " + mServiceIntent.toString()); -                break; -            case ACTION_DECRYPT_SESSION_KEY: -                mAction = action; -                mPin = data.getString(EXTRA_PIN); -                mEncryptedSessionKey = data.getByteArray(EXTRA_NFC_ENC_SESSION_KEY); -                mServiceIntent = data.getParcelable(EXTRA_DATA); - -                Log.d(Constants.TAG, "NfcActivity mAction: " + mAction); -                Log.d(Constants.TAG, "NfcActivity mPin: " + mPin); -                Log.d(Constants.TAG, "NfcActivity mEncryptedSessionKey as hex: " + getHex(mEncryptedSessionKey)); -                Log.d(Constants.TAG, "NfcActivity mServiceIntent: " + mServiceIntent.toString()); -                break; -            case NfcAdapter.ACTION_TAG_DISCOVERED: -                Log.e(Constants.TAG, "This should not happen! NfcActivity.onCreate() is being called instead of onNewIntent()!"); -                toast("This should not happen! Please create a new bug report that the NFC screen is restarted!"); -                finish(); -                break; -            default: -                Log.d(Constants.TAG, "Action not supported: " + action); -                break; -        } -    } - -    @Override -    protected void initLayout() { -        setContentView(R.layout.nfc_activity); -    } - -    /** -     * Called when the system is about to start resuming a previous activity, -     * disables NFC Foreground Dispatch -     */ -    public void onPause() { -        super.onPause(); -        Log.d(Constants.TAG, "NfcActivity.onPause"); - -        disableNfcForegroundDispatch(); -    } - -    /** -     * Called when the activity will start interacting with the user, -     * enables NFC Foreground Dispatch -     */ -    public void onResume() { -        super.onResume(); -        Log.d(Constants.TAG, "NfcActivity.onResume"); - -        enableNfcForegroundDispatch(); -    } - -    /** -     * This activity is started as a singleTop activity. -     * All new NFC Intents which are delivered to this activity are handled here -     */ -    public void onNewIntent(Intent intent) { -        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { -            try { -                handleNdefDiscoveredIntent(intent); -            } catch (IOException e) { -                Log.e(Constants.TAG, "Connection error!", e); -                toast("Connection Error: " + e.getMessage()); -                setResult(RESULT_CANCELED, mServiceIntent); -                finish(); -            } -        } -    } - -    /** Handle NFC communication and return a result. -     * -     * This method is called by onNewIntent above upon discovery of an NFC tag. -     * It handles initialization and login to the application, subsequently -     * calls either nfcCalculateSignature() or nfcDecryptSessionKey(), then -     * finishes the activity with an appropiate result. -     * -     * On general communication, see also -     * http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a.aspx -     * -     * References to pages are generally related to the OpenPGP Application -     * on ISO SmartCard Systems specification. -     * -     */ -    private void handleNdefDiscoveredIntent(Intent intent) throws IOException { - -        Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); - -        // Connect to the detected tag, setting a couple of settings -        mIsoDep = IsoDep.get(detectedTag); -        mIsoDep.setTimeout(TIMEOUT); // timeout is set to 100 seconds to avoid cancellation during calculation -        mIsoDep.connect(); - -        // SW1/2 0x9000 is the generic "ok" response, which we expect most of the time. -        // See specification, page 51 -        String accepted = "9000"; - -        // Command APDU (page 51) for SELECT FILE command (page 29) -        String opening = -                  "00" // CLA -                + "A4" // INS -                + "04" // P1 -                + "00" // P2 -                + "06" // Lc (number of bytes) -                + "D27600012401" // Data (6 bytes) -                + "00"; // Le -        if ( ! card(opening).equals(accepted)) { // activate connection -            toast("Opening Error!"); -            setResult(RESULT_CANCELED, mServiceIntent); -            finish(); -            return; -        } - -        // Command APDU for VERIFY command (page 32) -        String login = -              "00" // CLA -            + "20" // INS -            + "00" // P1 -            + "82" // P2 (PW1) -            + String.format("%02x", mPin.length()) // Lc -            + Hex.toHexString(mPin.getBytes()); -        if ( ! card(login).equals(accepted)) { // login -            toast("Wrong PIN!"); -            setResult(RESULT_CANCELED, mServiceIntent); -            finish(); -            return; -        } - -        if (ACTION_SIGN_HASH.equals(mAction)) { - -            // If we were supplied with a key id for checking, do so -            if (mKeyId != null) { -                // For signing, we check the master key -                long keyId = nfcGetKeyId(mIsoDep, 0); -                // If it's wrong, just cancel -                if (keyId != mKeyId) { -                    toast("NFC Tag has wrong signing key id!"); -                    setResult(RESULT_CANCELED, mServiceIntent); -                    finish(); -                    return; -                } -            } - -            // returns signed hash -            byte[] signedHash = nfcCalculateSignature(mHashToSign, mHashAlgo); - -            if (signedHash == null) { -                setResult(RESULT_CANCELED, mServiceIntent); -                finish(); -                return; -            } - -            Log.d(Constants.TAG, "NfcActivity signedHash as hex: " + getHex(signedHash)); - -            // give data through for new service call -            // OpenPgpApi.EXTRA_NFC_SIGNED_HASH -            mServiceIntent.putExtra("nfc_signed_hash", signedHash); -            setResult(RESULT_OK, mServiceIntent); -            finish(); - -        } else if (ACTION_DECRYPT_SESSION_KEY.equals(mAction)) { - -            // If we were supplied with a key id for checking, do so -            if (mKeyId != null) { -                // For decryption, we check the confidentiality key -                long keyId = nfcGetKeyId(mIsoDep, 1); -                // If it's wrong, just cancel -                if (keyId != mKeyId) { -                    toast("NFC Tag has wrong encryption key id!"); -                    setResult(RESULT_CANCELED, mServiceIntent); -                    finish(); -                    return; -                } -            } - -            byte[] decryptedSessionKey = nfcDecryptSessionKey(mEncryptedSessionKey); - -            // give data through for new service call -            // OpenPgpApi.EXTRA_NFC_DECRYPTED_SESSION_KEY -            mServiceIntent.putExtra("nfc_decrypted_session_key", decryptedSessionKey); -            setResult(RESULT_OK, mServiceIntent); -            finish(); -        } - -    } - -    /** -     * Gets the user ID -     * -     * @return the user id as "name <email>" -     * @throws java.io.IOException -     */ -    public String getUserId() throws IOException { -        String info = "00CA006500"; -        String data = "00CA005E00"; -        return getName(card(info)) + " <" + (new String(Hex.decode(getDataField(card(data))))) + ">"; -    } - -    /** Return the key id from application specific data stored on tag, or null -     * if it doesn't exist. -     * -     * @param idx Index of the key to return the fingerprint from. -     * @return The long key id of the requested key, or null if not found. -     */ -    public static Long nfcGetKeyId(IsoDep isoDep, int idx) throws IOException { -        byte[] fp = nfcGetFingerprint(isoDep, idx); -        if (fp == null) { -            return null; -        } -        ByteBuffer buf = ByteBuffer.wrap(fp); -        // skip first 12 bytes of the fingerprint -        buf.position(12); -        // the last eight bytes are the key id (big endian, which is default order in ByteBuffer) -        return buf.getLong(); -    } - -    /** Return fingerprints of all keys from application specific data stored -     * on tag, or null if data not available. -     * -     * @return The fingerprints of all subkeys in a contiguous byte array. -     */ -    public static byte[] nfcGetFingerprints(IsoDep isoDep) throws IOException { -        String data = "00CA006E00"; -        byte[] buf = isoDep.transceive(Hex.decode(data)); - -        Iso7816TLV tlv = Iso7816TLV.readSingle(buf, true); -        Log.d(Constants.TAG, "nfc tlv data:\n" + tlv.prettyPrint()); - -        Iso7816TLV fptlv = Iso7816TLV.findRecursive(tlv, 0xc5); -        if (fptlv == null) { -            return null; -        } - -        return fptlv.mV; -    } - -    /** Return the fingerprint from application specific data stored on tag, or -     * null if it doesn't exist. -     * -     * @param idx Index of the key to return the fingerprint from. -     * @return The fingerprint of the requested key, or null if not found. -     */ -    public static byte[] nfcGetFingerprint(IsoDep isoDep, int idx) throws IOException { -        byte[] data = nfcGetFingerprints(isoDep); - -        // return the master key fingerprint -        ByteBuffer fpbuf = ByteBuffer.wrap(data); -        byte[] fp = new byte[20]; -        fpbuf.position(idx*20); -        fpbuf.get(fp, 0, 20); - -        return fp; -    } - -    /** -     * Calls to calculate the signature and returns the MPI value -     * -     * @param hash the hash for signing -     * @return a big integer representing the MPI for the given hash -     * @throws java.io.IOException -     */ -    public byte[] nfcCalculateSignature(byte[] hash, int hashAlgo) throws IOException { - -        // dsi, including Lc -        String dsi; - -        Log.i(Constants.TAG, "Hash: " + hashAlgo); -        switch (hashAlgo) { -            case HashAlgorithmTags.SHA1: -                if (hash.length != 20) { -                    throw new RuntimeException("Bad hash length (" + hash.length + ", expected 10!"); -                } -                dsi = "23" // Lc -                        + "3021" // Tag/Length of Sequence, the 0x21 includes all following 33 bytes -                        + "3009" // Tag/Length of Sequence, the 0x09 are the following header bytes -                        + "0605" + "2B0E03021A" // OID of SHA1 -                        + "0500" // TLV coding of ZERO -                        + "0414" + getHex(hash); // 0x14 are 20 hash bytes -                break; -            case HashAlgorithmTags.RIPEMD160: -                if (hash.length != 20) { -                    throw new RuntimeException("Bad hash length (" + hash.length + ", expected 20!"); -                } -                dsi = "233021300906052B2403020105000414" + getHex(hash); -                break; -            case HashAlgorithmTags.SHA224: -                if (hash.length != 28) { -                    throw new RuntimeException("Bad hash length (" + hash.length + ", expected 28!"); -                } -                dsi = "2F302D300D06096086480165030402040500041C" + getHex(hash); -                break; -            case HashAlgorithmTags.SHA256: -                if (hash.length != 32) { -                    throw new RuntimeException("Bad hash length (" + hash.length + ", expected 32!"); -                } -                dsi = "333031300D060960864801650304020105000420" + getHex(hash); -                break; -            case HashAlgorithmTags.SHA384: -                if (hash.length != 48) { -                    throw new RuntimeException("Bad hash length (" + hash.length + ", expected 48!"); -                } -                dsi = "433041300D060960864801650304020205000430" + getHex(hash); -                break; -            case HashAlgorithmTags.SHA512: -                if (hash.length != 64) { -                    throw new RuntimeException("Bad hash length (" + hash.length + ", expected 64!"); -                } -                dsi = "533051300D060960864801650304020305000440" + getHex(hash); -                break; -            default: -                throw new RuntimeException("Not supported hash algo!"); -        } - -        // Command APDU for PERFORM SECURITY OPERATION: COMPUTE DIGITAL SIGNATURE (page 37) -        String apdu  = -                  "002A9E9A" // CLA, INS, P1, P2 -                + dsi // digital signature input -                + "00"; // Le - -        String response = card(apdu); - -        // split up response into signature and status -        String status = response.substring(response.length()-4); -        String signature = response.substring(0, response.length() - 4); - -        // while we are getting 0x61 status codes, retrieve more data -        while (status.substring(0, 2).equals("61")) { -            Log.d(Constants.TAG, "requesting more data, status " + status); -            // Send GET RESPONSE command -            response = card("00C00000" + status.substring(2)); -            status = response.substring(response.length()-4); -            signature += response.substring(0, response.length()-4); -        } - -        Log.d(Constants.TAG, "final response:" + status); - -        if ( ! status.equals("9000")) { -            toast("Bad NFC response code: " + status); -            return null; -        } - -        // Make sure the signature we received is actually the expected number of bytes long! -        if (signature.length() != 256 && signature.length() != 512) { -            toast("Bad signature length! Expected 128 or 256 bytes, got " + signature.length() / 2); -            return null; -        } - -        return Hex.decode(signature); -    } - -    /** -     * Calls to calculate the signature and returns the MPI value -     * -     * @param encryptedSessionKey the encoded session key -     * @return the decoded session key -     * @throws java.io.IOException -     */ -    public byte[] nfcDecryptSessionKey(byte[] encryptedSessionKey) throws IOException { -        String firstApdu = "102a8086fe"; -        String secondApdu = "002a808603"; -        String le = "00"; - -        byte[] one = new byte[254]; -        // leave out first byte: -        System.arraycopy(encryptedSessionKey, 1, one, 0, one.length); - -        byte[] two = new byte[encryptedSessionKey.length - 1 - one.length]; -        for (int i = 0; i < two.length; i++) { -            two[i] = encryptedSessionKey[i + one.length + 1]; -        } - -        String first = card(firstApdu + getHex(one)); -        String second = card(secondApdu + getHex(two) + le); - -        String decryptedSessionKey = getDataField(second); - -        Log.d(Constants.TAG, "decryptedSessionKey: " + decryptedSessionKey); - -        return Hex.decode(decryptedSessionKey); -    } - -    /** -     * Prints a message to the screen -     * -     * @param text the text which should be contained within the toast -     */ -    private void toast(String text) { -        Toast.makeText(this, text, Toast.LENGTH_LONG).show(); -    } - -    /** -     * Receive new NFC Intents to this activity only by enabling foreground dispatch. -     * This can only be done in onResume! -     */ -    public void enableNfcForegroundDispatch() { -        mNfcAdapter = NfcAdapter.getDefaultAdapter(this); -        Intent nfcI = new Intent(this, NfcActivity.class) -                .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); -        PendingIntent nfcPendingIntent = PendingIntent.getActivity(this, 0, nfcI, PendingIntent.FLAG_CANCEL_CURRENT); -        IntentFilter[] writeTagFilters = new IntentFilter[]{ -                new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED) -        }; - -        // https://code.google.com/p/android/issues/detail?id=62918 -        // maybe mNfcAdapter.enableReaderMode(); ? -        try { -            mNfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null); -        } catch (IllegalStateException e) { -            Log.i(Constants.TAG, "NfcForegroundDispatch Error!", e); -        } -        Log.d(Constants.TAG, "NfcForegroundDispatch has been enabled!"); -    } - -    /** -     * Disable foreground dispatch in onPause! -     */ -    public void disableNfcForegroundDispatch() { -        mNfcAdapter.disableForegroundDispatch(this); -        Log.d(Constants.TAG, "NfcForegroundDispatch has been disabled!"); -    } - -    /** -     * Gets the name of the user out of the raw card output regarding card holder related data -     * -     * @param name the raw card holder related data from the card -     * @return the name given in this data -     */ -    public String getName(String name) { -        String slength; -        int ilength; -        name = name.substring(6); -        slength = name.substring(0, 2); -        ilength = Integer.parseInt(slength, 16) * 2; -        name = name.substring(2, ilength + 2); -        name = (new String(Hex.decode(name))).replace('<', ' '); -        return (name); -    } - -    /** -     * Reduces the raw data from the card by four characters -     * -     * @param output the raw data from the card -     * @return the data field of that data -     */ -    private String getDataField(String output) { -        return output.substring(0, output.length() - 4); -    } - -    /** -     * Communicates with the OpenPgpCard via the APDU -     * -     * @param hex the hexadecimal APDU -     * @return The answer from the card -     * @throws java.io.IOException throws an exception if something goes wrong -     */ -    public String card(String hex) throws IOException { -        return getHex(mIsoDep.transceive(Hex.decode(hex))); -    } - -    /** -     * Converts a byte array into an hex string -     * -     * @param raw the byte array representation -     * @return the  hexadecimal string representation -     */ -    public static String getHex(byte[] raw) { -        return new String(Hex.encode(raw)); -    } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java index 511183b04..d70b0aad1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java @@ -10,8 +10,10 @@ import android.annotation.TargetApi;  import android.content.Intent;  import android.os.Build;  import android.os.Bundle; +import android.os.Parcelable;  import android.view.WindowManager; +import org.openintents.openpgp.util.OpenPgpApi;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -34,9 +36,13 @@ public class NfcOperationActivity extends BaseNfcActivity {      public static final String EXTRA_REQUIRED_INPUT = "required_input"; +    // passthrough for OpenPgpService +    public static final String EXTRA_SERVICE_INTENT = "data"; +      public static final String RESULT_DATA = "result_data"; -    RequiredInputParcel mRequiredInput; +    private RequiredInputParcel mRequiredInput; +    private Intent mServiceIntent;      @Override      protected void onCreate(Bundle savedInstanceState) { @@ -49,6 +55,7 @@ public class NfcOperationActivity extends BaseNfcActivity {          Bundle data = intent.getExtras();          mRequiredInput = data.getParcelable(EXTRA_REQUIRED_INPUT); +        mServiceIntent = data.getParcelable(EXTRA_SERVICE_INTENT);          // obtain passphrase for this subkey          obtainYubikeyPin(RequiredInputParcel.createRequiredPassphrase(mRequiredInput)); @@ -84,10 +91,15 @@ public class NfcOperationActivity extends BaseNfcActivity {                  break;          } -        // give data through for new service call -        Intent result = new Intent(); -        result.putExtra(NfcOperationActivity.RESULT_DATA, resultData); -        setResult(RESULT_OK, result); +        if (mServiceIntent != null) { +            mServiceIntent.putExtra(OpenPgpApi.EXTRA_CRYPTO_INPUT, resultData); +            setResult(RESULT_OK, mServiceIntent); +        } else { +            Intent result = new Intent(); +            result.putExtra(NfcOperationActivity.RESULT_DATA, resultData); +            setResult(RESULT_OK, result); +        } +          finish();      } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java index 9e04426eb..c1771ce57 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java @@ -41,7 +41,7 @@ import android.widget.EditText;  import android.widget.TextView;  import android.widget.Toast; -import junit.framework.Assert; +import org.openintents.openpgp.util.OpenPgpApi;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; @@ -67,14 +67,13 @@ import org.sufficientlysecure.keychain.util.Preferences;   * This activity encapsulates a DialogFragment to emulate a dialog.   */  public class PassphraseDialogActivity extends FragmentActivity { -    public static final String MESSAGE_DATA_PASSPHRASE = "passphrase"; -    public static final String RESULT_DATA = "result_data"; +    public static final String RESULT_CRYPTO_INPUT = "result_data";      public static final String EXTRA_REQUIRED_INPUT = "required_input";      public static final String EXTRA_SUBKEY_ID = "secret_key_id";      // special extra for OpenPgpService -    public static final String EXTRA_DATA = "data"; +    public static final String EXTRA_SERVICE_INTENT = "data";      private static final int REQUEST_CODE_ENTER_PATTERN = 2; @@ -104,7 +103,7 @@ public class PassphraseDialogActivity extends FragmentActivity {              keyId = requiredInput.getSubKeyId();          } -        Intent serviceIntent = getIntent().getParcelableExtra(EXTRA_DATA); +        Intent serviceIntent = getIntent().getParcelableExtra(EXTRA_SERVICE_INTENT);          show(this, keyId, serviceIntent);      } @@ -155,7 +154,7 @@ public class PassphraseDialogActivity extends FragmentActivity {                  PassphraseDialogFragment frag = new PassphraseDialogFragment();                  Bundle args = new Bundle();                  args.putLong(EXTRA_SUBKEY_ID, keyId); -                args.putParcelable(EXTRA_DATA, serviceIntent); +                args.putParcelable(EXTRA_SERVICE_INTENT, serviceIntent);                  frag.setArguments(args); @@ -188,7 +187,7 @@ public class PassphraseDialogActivity extends FragmentActivity {                      R.style.Theme_AppCompat_Light_Dialog);              mSubKeyId = getArguments().getLong(EXTRA_SUBKEY_ID); -            mServiceIntent = getArguments().getParcelable(EXTRA_DATA); +            mServiceIntent = getArguments().getParcelable(EXTRA_SERVICE_INTENT);              CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(theme); @@ -418,15 +417,13 @@ public class PassphraseDialogActivity extends FragmentActivity {              }              if (mServiceIntent != null) { -                // TODO: Not routing passphrase through OpenPGP API currently -                // due to security concerns... -                // BUT this means you need to _cache_ passphrases! +                // TODO really pass this through the PendingIntent? +                mServiceIntent.putExtra(OpenPgpApi.EXTRA_CRYPTO_INPUT, new CryptoInputParcel(null, passphrase));                  getActivity().setResult(RESULT_OK, mServiceIntent);              } else {                  // also return passphrase back to activity                  Intent returnIntent = new Intent(); -                returnIntent.putExtra(MESSAGE_DATA_PASSPHRASE, passphrase); -                returnIntent.putExtra(RESULT_DATA, new CryptoInputParcel(null, passphrase)); +                returnIntent.putExtra(RESULT_CRYPTO_INPUT, new CryptoInputParcel(null, passphrase));                  getActivity().setResult(RESULT_OK, returnIntent);              } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java index a8a5a1f28..0b22ecdaf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java @@ -130,7 +130,7 @@ public abstract class BaseNfcActivity extends BaseActivity {      protected void onActivityResult(int requestCode, int resultCode, Intent data) {          switch (requestCode) {              case REQUEST_CODE_PASSPHRASE: -                CryptoInputParcel input = data.getParcelableExtra(PassphraseDialogActivity.RESULT_DATA); +                CryptoInputParcel input = data.getParcelableExtra(PassphraseDialogActivity.RESULT_CRYPTO_INPUT);                  mPin = input.getPassphrase();                  break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java index 943b913d7..3bbd86d6a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/KeyUpdateHelper.java @@ -57,7 +57,7 @@ public class KeyUpdateHelper {                  Bundle importData = new Bundle();                  importData.putParcelableArrayList(KeychainIntentService.DOWNLOAD_KEY_LIST,                          new ArrayList<ImportKeysListEntry>(keys)); -                importIntent.putExtra(KeychainIntentService.EXTRA_DATA, importData); +                importIntent.putExtra(KeychainIntentService.EXTRA_SERVICE_INTENT, importData);                  importIntent.putExtra(KeychainIntentService.EXTRA_MESSENGER, new Messenger(mHandler)); diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 78940aa9e..6d29ce3fd 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1048,7 +1048,6 @@      <string name="msg_se_error_input_uri_not_found">"Error opening URI for reading!"</string>      <string name="msg_se_error_output_uri_not_found">"Error opening URI for writing!"</string>      <string name="msg_se_error_too_many_inputs">"More inputs than outputs specified! This is probably a programming error, please report!"</string> -    <string name="msg_se_warn_output_left">"Got outputs left but no inputs. This is probably a programming error, please report!"</string>      <string name="msg_se_success">"Sign/encrypt operation successful"</string>      <!-- Messages for PgpSignEncrypt operation -->  | 
