support yubikeys in (some) edit key operations
This commit is contained in:
@@ -9,6 +9,7 @@ import android.support.v4.app.Fragment;
|
||||
|
||||
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.InputPendingResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler.MessageStatus;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||
@@ -25,7 +26,6 @@ public abstract class CryptoOperationFragment extends Fragment {
|
||||
case NFC_DECRYPT:
|
||||
case NFC_SIGN: {
|
||||
Intent intent = new Intent(getActivity(), NfcOperationActivity.class);
|
||||
intent.putExtra(NfcOperationActivity.EXTRA_PIN, "123456");
|
||||
intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, requiredInput);
|
||||
startActivityForResult(intent, REQUEST_CODE_NFC);
|
||||
return;
|
||||
@@ -76,10 +76,14 @@ public abstract class CryptoOperationFragment extends Fragment {
|
||||
if (message.arg1 == MessageStatus.OKAY.ordinal()) {
|
||||
Bundle data = message.getData();
|
||||
|
||||
InputPendingResult result = data.getParcelable(CertifyResult.EXTRA_RESULT);
|
||||
OperationResult result = data.getParcelable(CertifyResult.EXTRA_RESULT);
|
||||
if (result == null || ! (result instanceof InputPendingResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result != null && result.isPending()) {
|
||||
RequiredInputParcel requiredInput = result.getRequiredInputParcel();
|
||||
InputPendingResult pendingResult = (InputPendingResult) result;
|
||||
if (pendingResult.isPending()) {
|
||||
RequiredInputParcel requiredInput = pendingResult.getRequiredInputParcel();
|
||||
initiateInputActivity(requiredInput);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Intent;
|
||||
@@ -51,10 +53,10 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
|
||||
@@ -68,14 +70,12 @@ import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
public class EditKeyFragment extends LoaderFragment implements
|
||||
public class EditKeyFragment extends CryptoOperationFragment implements
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
public static final String ARG_DATA_URI = "uri";
|
||||
public static final String ARG_SAVE_KEYRING_PARCEL = "save_keyring_parcel";
|
||||
|
||||
public static final int REQUEST_CODE_PASSPHRASE = 0x00008001;
|
||||
|
||||
private ListView mUserIdsList;
|
||||
private ListView mSubkeysList;
|
||||
private ListView mUserIdsAddedList;
|
||||
@@ -100,7 +100,6 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
private SaveKeyringParcel mSaveKeyringParcel;
|
||||
|
||||
private String mPrimaryUserId;
|
||||
private String mCurrentPassphrase;
|
||||
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
@@ -129,8 +128,7 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
|
||||
View root = super.onCreateView(inflater, superContainer, savedInstanceState);
|
||||
View view = inflater.inflate(R.layout.edit_key_fragment, getContainer());
|
||||
View view = inflater.inflate(R.layout.edit_key_fragment, null);
|
||||
|
||||
mUserIdsList = (ListView) view.findViewById(R.id.edit_key_user_ids);
|
||||
mSubkeysList = (ListView) view.findViewById(R.id.edit_key_keys);
|
||||
@@ -140,7 +138,7 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
mAddUserId = view.findViewById(R.id.edit_key_action_add_user_id);
|
||||
mAddSubkey = view.findViewById(R.id.edit_key_action_add_key);
|
||||
|
||||
return root;
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,7 +153,7 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
if (mDataUri == null) {
|
||||
returnKeyringParcel();
|
||||
} else {
|
||||
saveInDatabase(mCurrentPassphrase);
|
||||
cryptoOperation(new CryptoInputParcel(new Date()));
|
||||
}
|
||||
}
|
||||
}, new OnClickListener() {
|
||||
@@ -185,18 +183,12 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
private void loadSaveKeyringParcel(SaveKeyringParcel saveKeyringParcel) {
|
||||
mSaveKeyringParcel = saveKeyringParcel;
|
||||
mPrimaryUserId = saveKeyringParcel.mChangePrimaryUserId;
|
||||
if (saveKeyringParcel.mNewUnlock != null) {
|
||||
mCurrentPassphrase = saveKeyringParcel.mNewUnlock.mNewPassphrase;
|
||||
}
|
||||
|
||||
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds, true);
|
||||
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
|
||||
|
||||
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys, true);
|
||||
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
|
||||
|
||||
// show directly
|
||||
setContentShown(true);
|
||||
}
|
||||
|
||||
private void loadData(Uri dataUri) {
|
||||
@@ -216,9 +208,6 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
case GNU_DUMMY:
|
||||
finishWithError(LogType.MSG_EK_ERROR_DUMMY);
|
||||
return;
|
||||
case DIVERT_TO_CARD:
|
||||
finishWithError(LogType.MSG_EK_ERROR_DIVERT);
|
||||
break;
|
||||
}
|
||||
|
||||
mSaveKeyringParcel = new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint());
|
||||
@@ -229,24 +218,10 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mCurrentPassphrase = PassphraseCacheService.getCachedPassphrase(getActivity(),
|
||||
mSaveKeyringParcel.mMasterKeyId, mSaveKeyringParcel.mMasterKeyId);
|
||||
} catch (PassphraseCacheService.KeyNotFoundException e) {
|
||||
finishWithError(LogType.MSG_EK_ERROR_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCurrentPassphrase == null) {
|
||||
Intent intent = new Intent(getActivity(), PassphraseDialogActivity.class);
|
||||
intent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID, mSaveKeyringParcel.mMasterKeyId);
|
||||
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
|
||||
} else {
|
||||
// Prepare the loaders. Either re-connect with an existing ones,
|
||||
// or start new ones.
|
||||
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, EditKeyFragment.this);
|
||||
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, EditKeyFragment.this);
|
||||
}
|
||||
// Prepare the loaders. Either re-connect with an existing ones,
|
||||
// or start new ones.
|
||||
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, EditKeyFragment.this);
|
||||
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, EditKeyFragment.this);
|
||||
|
||||
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, mSaveKeyringParcel);
|
||||
mUserIdsList.setAdapter(mUserIdsAdapter);
|
||||
@@ -262,28 +237,6 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_PASSPHRASE: {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
mCurrentPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
|
||||
// Prepare the loaders. Either re-connect with an existing ones,
|
||||
// or start new ones.
|
||||
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, EditKeyFragment.this);
|
||||
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, EditKeyFragment.this);
|
||||
} else {
|
||||
getActivity().finish();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
default: {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
mChangePassphrase.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -322,7 +275,6 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
}
|
||||
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
setContentShown(false);
|
||||
|
||||
switch (id) {
|
||||
case LOADER_ID_USER_IDS: {
|
||||
@@ -355,7 +307,6 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
break;
|
||||
|
||||
}
|
||||
setContentShown(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,7 +348,7 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
Messenger messenger = new Messenger(returnHandler);
|
||||
|
||||
SetPassphraseDialogFragment setPassphraseDialog = SetPassphraseDialogFragment.newInstance(
|
||||
messenger, mCurrentPassphrase, R.string.title_change_passphrase);
|
||||
messenger, R.string.title_change_passphrase);
|
||||
|
||||
setPassphraseDialog.show(getActivity().getSupportFragmentManager(), "setPassphraseDialog");
|
||||
}
|
||||
@@ -593,8 +544,11 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
private void saveInDatabase(String passphrase) {
|
||||
Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel.toString());
|
||||
@Override
|
||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
||||
|
||||
Log.d(Constants.TAG, "cryptoInput:\n" + cryptoInput);
|
||||
Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel);
|
||||
|
||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
||||
getActivity(),
|
||||
@@ -605,6 +559,10 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
if (handlePendingMessage(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.arg1 == MessageStatus.OKAY.ordinal()) {
|
||||
|
||||
// get returned data bundle
|
||||
@@ -640,7 +598,7 @@ public class EditKeyFragment extends LoaderFragment implements
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
data.putString(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
|
||||
|
||||
@@ -62,10 +62,9 @@ public abstract class EncryptActivity extends BaseActivity {
|
||||
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
|
||||
}
|
||||
|
||||
protected void startNfcSign(long keyId, String pin, RequiredInputParcel nfcOps) {
|
||||
protected void startNfcSign(long keyId, RequiredInputParcel nfcOps) {
|
||||
|
||||
Intent intent = new Intent(this, NfcOperationActivity.class);
|
||||
intent.putExtra(NfcOperationActivity.EXTRA_PIN, pin);
|
||||
intent.putExtra(NfcOperationActivity.EXTRA_REQUIRED_INPUT, nfcOps);
|
||||
// TODO respect keyid(?)
|
||||
|
||||
@@ -148,8 +147,7 @@ public abstract class EncryptActivity extends BaseActivity {
|
||||
pgpResult.getNfcHash(),
|
||||
pgpResult.getNfcAlgo(),
|
||||
input.getSignatureTime());
|
||||
startNfcSign(pgpResult.getNfcKeyId(),
|
||||
pgpResult.getNfcPassphrase(), parcel);
|
||||
startNfcSign(pgpResult.getNfcKeyId(), parcel);
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled pending result!");
|
||||
|
||||
@@ -40,7 +40,6 @@ import java.nio.ByteBuffer;
|
||||
@TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
|
||||
public class NfcOperationActivity extends BaseActivity {
|
||||
|
||||
public static final String EXTRA_PIN = "pin";
|
||||
public static final String EXTRA_REQUIRED_INPUT = "required_input";
|
||||
|
||||
public static final String RESULT_DATA = "result_data";
|
||||
@@ -50,8 +49,6 @@ public class NfcOperationActivity extends BaseActivity {
|
||||
private NfcAdapter mNfcAdapter;
|
||||
private IsoDep mIsoDep;
|
||||
|
||||
private String mPin;
|
||||
|
||||
RequiredInputParcel mNfcOperations;
|
||||
|
||||
@Override
|
||||
@@ -70,7 +67,6 @@ public class NfcOperationActivity extends BaseActivity {
|
||||
Bundle data = intent.getExtras();
|
||||
|
||||
mNfcOperations = data.getParcelable(EXTRA_REQUIRED_INPUT);
|
||||
mPin = data.getString(EXTRA_PIN);
|
||||
|
||||
}
|
||||
|
||||
@@ -161,14 +157,16 @@ public class NfcOperationActivity extends BaseActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
String pin = mNfcOperations.mNfcPin;
|
||||
|
||||
// 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());
|
||||
+ String.format("%02x", pin.length()) // Lc
|
||||
+ Hex.toHexString(pin.getBytes());
|
||||
if ( ! card(login).equals(accepted)) { // login
|
||||
toast("Wrong PIN!");
|
||||
setResult(RESULT_CANCELED);
|
||||
|
||||
@@ -49,7 +49,6 @@ import org.sufficientlysecure.keychain.util.Log;
|
||||
public class SetPassphraseDialogFragment extends DialogFragment implements OnEditorActionListener {
|
||||
private static final String ARG_MESSENGER = "messenger";
|
||||
private static final String ARG_TITLE = "title";
|
||||
private static final String ARG_OLD_PASSPHRASE = "old_passphrase";
|
||||
|
||||
public static final int MESSAGE_OKAY = 1;
|
||||
|
||||
@@ -67,12 +66,11 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
|
||||
* @param messenger to communicate back after setting the passphrase
|
||||
* @return
|
||||
*/
|
||||
public static SetPassphraseDialogFragment newInstance(Messenger messenger, String oldPassphrase, int title) {
|
||||
public static SetPassphraseDialogFragment newInstance(Messenger messenger, int title) {
|
||||
SetPassphraseDialogFragment frag = new SetPassphraseDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_TITLE, title);
|
||||
args.putParcelable(ARG_MESSENGER, messenger);
|
||||
args.putString(ARG_OLD_PASSPHRASE, oldPassphrase);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
@@ -88,7 +86,6 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
|
||||
|
||||
int title = getArguments().getInt(ARG_TITLE);
|
||||
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||
String oldPassphrase = getArguments().getString(ARG_OLD_PASSPHRASE);
|
||||
|
||||
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
|
||||
|
||||
@@ -102,13 +99,6 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
|
||||
mPassphraseAgainEditText = (EditText) view.findViewById(R.id.passphrase_passphrase_again);
|
||||
mNoPassphraseCheckBox = (CheckBox) view.findViewById(R.id.passphrase_no_passphrase);
|
||||
|
||||
|
||||
if (TextUtils.isEmpty(oldPassphrase)) {
|
||||
mNoPassphraseCheckBox.setChecked(true);
|
||||
mPassphraseEditText.setEnabled(false);
|
||||
mPassphraseAgainEditText.setEnabled(false);
|
||||
}
|
||||
|
||||
mNoPassphraseCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
|
||||
Reference in New Issue
Block a user