/**
   * Checks if key has a passphrase
   *
   * @param secretKeyId
   * @return true if it has a passphrase
   */
  private static boolean hasPassphrase(Context context, long secretKeyId) {
    // check if the key has no passphrase
    try {
      PGPSecretKey secretKey =
          PGPHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(context, secretKeyId));
      // PGPSecretKey secretKey =
      // PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));

      Log.d(Constants.TAG, "Check if key has no passphrase...");
      PBESecretKeyDecryptor keyDecryptor =
          new JcePBESecretKeyDecryptorBuilder().setProvider("SC").build("".toCharArray());
      PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
      if (testKey != null) {
        Log.d(Constants.TAG, "Key has no passphrase! Caches empty passphrase!");

        // cache empty passphrase
        PassphraseCacheService.addCachedPassphrase(context, secretKey.getKeyID(), "");

        return false;
      }
    } catch (PGPException e) {
      // silently catch
    }

    return true;
  }
Beispiel #2
0
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit_key);

    mActionBar = getSupportActionBar();
    mActionBar.setDisplayShowTitleEnabled(true);

    // set actionbar without home button if called from another app
    if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) {
      mActionBar.setDisplayHomeAsUpEnabled(true);
      mActionBar.setHomeButtonEnabled(true);
    } else {
      mActionBar.setDisplayHomeAsUpEnabled(false);
      mActionBar.setHomeButtonEnabled(false);
    }

    // find views
    mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase);
    mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);

    mUserIds = new Vector<String>();
    mKeys = new Vector<PGPSecretKey>();
    mKeysUsages = new Vector<Integer>();

    // Catch Intents opened from other apps
    mIntent = getIntent();

    // Handle intents
    Bundle extras = mIntent.getExtras();
    if (ACTION_CREATE_KEY.equals(mIntent.getAction())) {
      mActionBar.setTitle(R.string.title_createKey);

      mCurrentPassPhrase = "";

      if (extras != null) {
        // if userId is given, prefill the fields
        if (extras.containsKey(EXTRA_USER_IDS)) {
          Log.d(Constants.TAG, "UserIds are given!");
          mUserIds.add(extras.getString(EXTRA_USER_IDS));
        }

        // if no passphrase is given
        if (extras.containsKey(EXTRA_NO_PASSPHRASE)) {
          boolean noPassphrase = extras.getBoolean(EXTRA_NO_PASSPHRASE);
          if (noPassphrase) {
            // check "no passphrase" checkbox and remove button
            mNoPassphrase.setChecked(true);
            mChangePassPhrase.setVisibility(View.GONE);
          }
        }

        // generate key
        if (extras.containsKey(EXTRA_GENERATE_DEFAULT_KEYS)) {
          boolean generateDefaultKeys = extras.getBoolean(EXTRA_GENERATE_DEFAULT_KEYS);
          if (generateDefaultKeys) {

            // build layout in handler after generating keys not directly in onCreate
            mBuildLayout = false;

            // Send all information needed to service generate keys in other thread
            Intent intent = new Intent(this, ApgService.class);
            intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_GENERATE_DEFAULT_RSA_KEYS);

            // fill values for this action
            Bundle data = new Bundle();
            data.putString(ApgService.SYMMETRIC_PASSPHRASE, mCurrentPassPhrase);

            intent.putExtra(ApgService.EXTRA_DATA, data);

            // show progress dialog
            mGeneratingDialog =
                ProgressDialogFragment.newInstance(
                    R.string.progress_generating, ProgressDialog.STYLE_SPINNER);

            // Message is received after generating is done in ApgService
            ApgHandler saveHandler =
                new ApgHandler(this, mGeneratingDialog) {
                  public void handleMessage(Message message) {
                    // handle messages by standard ApgHandler first
                    super.handleMessage(message);

                    if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
                      // get new key from data bundle returned from service
                      Bundle data = message.getData();
                      PGPSecretKeyRing masterKeyRing =
                          PGPConversionHelper.BytesToPGPSecretKeyRing(
                              data.getByteArray(ApgService.RESULT_NEW_KEY));
                      PGPSecretKeyRing subKeyRing =
                          PGPConversionHelper.BytesToPGPSecretKeyRing(
                              data.getByteArray(ApgService.RESULT_NEW_KEY2));

                      // add master key
                      Iterator<PGPSecretKey> masterIt = masterKeyRing.getSecretKeys();
                      mKeys.add(masterIt.next());
                      mKeysUsages.add(Id.choice.usage.sign_only);

                      // add sub key
                      Iterator<PGPSecretKey> subIt = subKeyRing.getSecretKeys();
                      subIt.next(); // masterkey
                      mKeys.add(subIt.next());
                      mKeysUsages.add(Id.choice.usage.encrypt_only);

                      buildLayout();
                    }
                  };
                };

            // Create a new Messenger for the communication back
            Messenger messenger = new Messenger(saveHandler);
            intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);

            mGeneratingDialog.show(getSupportFragmentManager(), "dialog");

            // start service with intent
            startService(intent);
          }
        }
      }
    } else if (ACTION_EDIT_KEY.equals(mIntent.getAction())) {
      mActionBar.setTitle(R.string.title_editKey);

      mCurrentPassPhrase = PGPMain.getEditPassPhrase();
      if (mCurrentPassPhrase == null) {
        mCurrentPassPhrase = "";
      }

      if (mCurrentPassPhrase.equals("")) {
        // check "no passphrase" checkbox and remove button
        mNoPassphrase.setChecked(true);
        mChangePassPhrase.setVisibility(View.GONE);
      }

      if (extras != null) {

        if (extras.containsKey(EXTRA_KEY_ID)) {
          long keyId = mIntent.getExtras().getLong(EXTRA_KEY_ID);

          if (keyId != 0) {
            PGPSecretKey masterKey = null;
            mKeyRing = PGPMain.getSecretKeyRing(keyId);
            if (mKeyRing != null) {
              masterKey = PGPHelper.getMasterKey(mKeyRing);
              for (PGPSecretKey key :
                  new IterableIterator<PGPSecretKey>(mKeyRing.getSecretKeys())) {
                mKeys.add(key);
                mKeysUsages.add(-1); // get usage when view is created
              }
            }
            if (masterKey != null) {
              for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
                mUserIds.add(userId);
              }
            }
          }
        }
      }
    }

    mChangePassPhrase.setOnClickListener(
        new OnClickListener() {
          public void onClick(View v) {
            showDialog(Id.dialog.new_pass_phrase);
          }
        });

    // disable passphrase when no passphrase checkobox is checked!
    mNoPassphrase.setOnCheckedChangeListener(
        new OnCheckedChangeListener() {

          @Override
          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
              // remove passphrase
              mNewPassPhrase = null;

              mChangePassPhrase.setVisibility(View.GONE);
            } else {
              mChangePassPhrase.setVisibility(View.VISIBLE);
            }
          }
        });

    if (mBuildLayout) {
      buildLayout();
    }
  }
  /** Creates dialog */
  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {
    final Activity activity = getActivity();

    long secretKeyId = getArguments().getLong(ARG_SECRET_KEY_ID);
    mMessenger = getArguments().getParcelable(ARG_MESSENGER);

    AlertDialog.Builder alert = new AlertDialog.Builder(activity);

    alert.setTitle(R.string.title_authentication);

    final PGPSecretKey secretKey;

    if (secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none) {
      secretKey = null;
      alert.setMessage(R.string.passPhraseForSymmetricEncryption);
    } else {
      // TODO: by master key id???
      secretKey =
          PGPHelper.getMasterKey(
              ProviderHelper.getPGPSecretKeyRingByMasterKeyId(activity, secretKeyId));
      // secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));

      if (secretKey == null) {
        alert.setTitle(R.string.title_keyNotFound);
        alert.setMessage(getString(R.string.keyNotFound, secretKeyId));
        alert.setPositiveButton(
            android.R.string.ok,
            new OnClickListener() {
              public void onClick(DialogInterface dialog, int which) {
                dismiss();
              }
            });
        alert.setCancelable(false);
        return alert.create();
      }
      String userId = PGPHelper.getMainUserIdSafe(activity, secretKey);

      Log.d(Constants.TAG, "User id: '" + userId + "'");
      alert.setMessage(getString(R.string.passPhraseFor, userId));
    }

    LayoutInflater inflater = activity.getLayoutInflater();
    View view = inflater.inflate(R.layout.passphrase, null);
    alert.setView(view);

    mPassphraseEditText = (EditText) view.findViewById(R.id.passphrase_passphrase);

    alert.setPositiveButton(
        android.R.string.ok,
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            dismiss();

            String passPhrase = mPassphraseEditText.getText().toString();
            long keyId;
            if (secretKey != null) {
              try {
                PBESecretKeyDecryptor keyDecryptor =
                    new JcePBESecretKeyDecryptorBuilder()
                        .setProvider(PGPMain.BOUNCY_CASTLE_PROVIDER_NAME)
                        .build(passPhrase.toCharArray());
                PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
                if (testKey == null) {
                  Toast.makeText(
                          activity, R.string.error_couldNotExtractPrivateKey, Toast.LENGTH_SHORT)
                      .show();
                  return;
                }
              } catch (PGPException e) {
                Toast.makeText(activity, R.string.wrongPassPhrase, Toast.LENGTH_SHORT).show();
                return;
              }
              keyId = secretKey.getKeyID();
            } else {
              keyId = Id.key.symmetric;
            }

            // cache the new passphrase
            Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
            PassphraseCacheService.addCachedPassphrase(activity, keyId, passPhrase);

            sendMessageToHandler(MESSAGE_OKAY);
          }
        });

    alert.setNegativeButton(
        android.R.string.cancel,
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            dismiss();
          }
        });

    return alert.create();
  }