Feature to change key configuration in create key

This commit is contained in:
Dominik Schürmann 2014-09-21 21:50:56 +02:00
parent d4387c0179
commit bf0104af2e
9 changed files with 208 additions and 53 deletions

View File

@ -18,7 +18,6 @@
package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;

View File

@ -217,7 +217,7 @@ public class SaveKeyringParcel implements Parcelable {
out += "mChangeSubKeys: " + mChangeSubKeys + "\n";
out += "mChangePrimaryUserId: " + mChangePrimaryUserId + "\n";
out += "mRevokeUserIds: " + mRevokeUserIds + "\n";
out += "mRevokeSubKeys: " + mRevokeSubKeys;
out += "mRevokeSubKeys: " + mRevokeSubKeys + "\n";
out += "mStripSubKeys: " + mStripSubKeys;
return out;

View File

@ -47,6 +47,8 @@ import org.sufficientlysecure.keychain.util.Log;
public class CreateKeyFinalFragment extends Fragment {
public static final int REQUEST_EDIT_KEY = 0x00008007;
CreateKeyActivity mCreateKeyActivity;
TextView mNameEdit;
@ -54,6 +56,8 @@ public class CreateKeyFinalFragment extends Fragment {
CheckBox mUploadCheckbox;
View mBackButton;
View mCreateButton;
TextView mEditText;
View mEditButton;
public static final String ARG_NAME = "name";
public static final String ARG_EMAIL = "email";
@ -63,6 +67,8 @@ public class CreateKeyFinalFragment extends Fragment {
String mEmail;
String mPassphrase;
SaveKeyringParcel mSaveKeyringParcel;
/**
* Creates new instance of this fragment
*/
@ -88,6 +94,8 @@ public class CreateKeyFinalFragment extends Fragment {
mUploadCheckbox = (CheckBox) view.findViewById(R.id.create_key_upload);
mBackButton = view.findViewById(R.id.create_key_back_button);
mCreateButton = view.findViewById(R.id.create_key_create_button);
mEditText = (TextView) view.findViewById(R.id.create_key_edit_text);
mEditButton = view.findViewById(R.id.create_key_edit_button);
// get args
mName = getArguments().getString(ARG_NAME);
@ -112,14 +120,53 @@ public class CreateKeyFinalFragment extends Fragment {
}
});
mEditButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent edit = new Intent(getActivity(), EditKeyActivity.class);
edit.putExtra(EditKeyActivity.EXTRA_SAVE_KEYRING_PARCEL, mSaveKeyringParcel);
startActivityForResult(edit, REQUEST_EDIT_KEY);
}
});
return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_EDIT_KEY: {
if (resultCode == Activity.RESULT_OK) {
mSaveKeyringParcel = data.getParcelableExtra(EditKeyActivity.EXTRA_SAVE_KEYRING_PARCEL);
mEditText.setText(R.string.create_key_custom);
}
break;
}
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mCreateKeyActivity = (CreateKeyActivity) getActivity();
if (mSaveKeyringParcel == null) {
mSaveKeyringParcel = new SaveKeyringParcel();
mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 4096, null, KeyFlags.CERTIFY_OTHER, 0L));
mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 4096, null, KeyFlags.SIGN_DATA, 0L));
mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 4096, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L));
String userId = KeyRing.createUserId(mName, mEmail, null);
mSaveKeyringParcel.mAddUserIds.add(userId);
mSaveKeyringParcel.mChangePrimaryUserId = userId;
mSaveKeyringParcel.mNewPassphrase = mPassphrase;
}
}
private void createKey() {
@ -163,20 +210,8 @@ public class CreateKeyFinalFragment extends Fragment {
// fill values for this action
Bundle data = new Bundle();
SaveKeyringParcel parcel = new SaveKeyringParcel();
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 4096, null, KeyFlags.CERTIFY_OTHER, 0L));
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 4096, null, KeyFlags.SIGN_DATA, 0L));
parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
Algorithm.RSA, 4096, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L));
String userId = KeyRing.createUserId(mName, mEmail, null);
parcel.mAddUserIds.add(userId);
parcel.mChangePrimaryUserId = userId;
parcel.mNewPassphrase = mPassphrase;
// get selected key entries
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, parcel);
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@ -23,10 +23,13 @@ import android.support.v7.app.ActionBarActivity;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.util.Log;
public class EditKeyActivity extends ActionBarActivity {
public static final String EXTRA_SAVE_KEYRING_PARCEL = "save_keyring_parcel";
private EditKeyFragment mEditKeyFragment;
@Override
@ -36,16 +39,17 @@ public class EditKeyActivity extends ActionBarActivity {
setContentView(R.layout.edit_key_activity);
Uri dataUri = getIntent().getData();
if (dataUri == null) {
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
SaveKeyringParcel saveKeyringParcel = getIntent().getParcelableExtra(EXTRA_SAVE_KEYRING_PARCEL);
if (dataUri == null && saveKeyringParcel == null) {
Log.e(Constants.TAG, "Either a key Uri or EXTRA_SAVE_KEYRING_PARCEL is required!");
finish();
return;
}
loadFragment(savedInstanceState, dataUri);
loadFragment(savedInstanceState, dataUri, saveKeyringParcel);
}
private void loadFragment(Bundle savedInstanceState, Uri dataUri) {
private void loadFragment(Bundle savedInstanceState, Uri dataUri, SaveKeyringParcel saveKeyringParcel) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
@ -54,7 +58,11 @@ public class EditKeyActivity extends ActionBarActivity {
}
// Create an instance of the fragment
if (dataUri != null) {
mEditKeyFragment = EditKeyFragment.newInstance(dataUri);
} else {
mEditKeyFragment = EditKeyFragment.newInstance(saveKeyringParcel);
}
// Add the fragment to the 'fragment_container' FrameLayout
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!

View File

@ -17,6 +17,7 @@
package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
@ -71,6 +72,7 @@ public class EditKeyFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_DATA_URI = "uri";
public static final String ARG_SAVE_KEYRING_PARCEL = "save_keyring_parcel";
private ListView mUserIdsList;
private ListView mSubkeysList;
@ -112,6 +114,17 @@ public class EditKeyFragment extends LoaderFragment implements
return frag;
}
public static EditKeyFragment newInstance(SaveKeyringParcel saveKeyringParcel) {
EditKeyFragment frag = new EditKeyFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_SAVE_KEYRING_PARCEL, saveKeyringParcel);
frag.setArguments(args);
return frag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
View root = super.onCreateView(inflater, superContainer, savedInstanceState);
@ -138,29 +151,54 @@ public class EditKeyFragment extends LoaderFragment implements
new OnClickListener() {
@Override
public void onClick(View v) {
// Save
save(mCurrentPassphrase);
// if we are working on an Uri, save directly
if (mDataUri == null) {
returnKeyringParcel();
} else {
saveInDatabase(mCurrentPassphrase);
}
}
}, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
new OnClickListener() {
@Override
public void onClick(View v) {
// Cancel
// cancel
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
}
);
Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
if (dataUri == null) {
Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
SaveKeyringParcel saveKeyringParcel = getArguments().getParcelable(ARG_SAVE_KEYRING_PARCEL);
if (dataUri == null && saveKeyringParcel == null) {
Log.e(Constants.TAG, "Either a key Uri or ARG_SAVE_KEYRING_PARCEL is required!");
getActivity().finish();
return;
}
initView();
if (dataUri != null) {
loadData(dataUri);
} else {
loadSaveKeyringParcel(saveKeyringParcel);
}
}
private void loadSaveKeyringParcel(SaveKeyringParcel saveKeyringParcel) {
mSaveKeyringParcel = saveKeyringParcel;
mPrimaryUserId = saveKeyringParcel.mChangePrimaryUserId;
mCurrentPassphrase = saveKeyringParcel.mNewPassphrase;
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
// show directly
setContentShown(true);
}
private void loadData(Uri dataUri) {
mDataUri = dataUri;
@ -228,6 +266,21 @@ public class EditKeyFragment extends LoaderFragment implements
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, EditKeyFragment.this);
}
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, mSaveKeyringParcel);
mUserIdsList.setAdapter(mUserIdsAdapter);
// TODO: SaveParcel from savedInstance?!
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0, mSaveKeyringParcel);
mSubkeysList.setAdapter(mSubkeysAdapter);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
}
private void initView() {
mChangePassphrase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -249,23 +302,6 @@ public class EditKeyFragment extends LoaderFragment implements
}
});
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, mSaveKeyringParcel);
mUserIdsList.setAdapter(mUserIdsAdapter);
mUserIdsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
editUserId(position);
}
});
// TODO: SaveParcel from savedInstance?!
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0, mSaveKeyringParcel);
mSubkeysList.setAdapter(mSubkeysAdapter);
mSubkeysList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@ -273,9 +309,12 @@ public class EditKeyFragment extends LoaderFragment implements
}
});
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
mUserIdsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
editUserId(position);
}
});
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@ -505,8 +544,12 @@ public class EditKeyFragment extends LoaderFragment implements
}
private void addSubkey() {
boolean willBeMasterKey = mSubkeysAdapter.getCount() == 0
&& mSubkeysAddedAdapter.getCount() == 0;
boolean willBeMasterKey;
if (mSubkeysAdapter != null) {
willBeMasterKey = mSubkeysAdapter.getCount() == 0 && mSubkeysAddedAdapter.getCount() == 0;
} else {
willBeMasterKey = mSubkeysAddedAdapter.getCount() == 0;
}
AddSubkeyDialogFragment addSubkeyDialogFragment =
AddSubkeyDialogFragment.newInstance(willBeMasterKey);
@ -522,7 +565,14 @@ public class EditKeyFragment extends LoaderFragment implements
addSubkeyDialogFragment.show(getActivity().getSupportFragmentManager(), "addSubkeyDialog");
}
private void save(String passphrase) {
private void returnKeyringParcel() {
Intent returnIntent = new Intent();
returnIntent.putExtra(EditKeyActivity.EXTRA_SAVE_KEYRING_PARCEL, mSaveKeyringParcel);
getActivity().setResult(Activity.RESULT_OK, returnIntent);
getActivity().finish();
}
private void saveInDatabase(String passphrase) {
Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel.toString());
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
@ -582,10 +632,11 @@ public class EditKeyFragment extends LoaderFragment implements
// start service with intent
getActivity().startService(intent);
}
/** Closes this activity, returning a result parcel with a single error log entry. */
/**
* Closes this activity, returning a result parcel with a single error log entry.
*/
void finishWithError(LogType reason) {
// Prepare an intent with an EXTRA_RESULT

View File

@ -89,6 +89,8 @@ public class LogDisplayFragment extends ListFragment implements OnTouchListener
}
});
getListView().setFastScrollEnabled(true);
}
public void decreaseLogLevel() {

View File

@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.adapter;
import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
@ -105,6 +106,14 @@ public class SubkeysAddedAdapter extends ArrayAdapter<SaveKeyringParcel.SubkeyAd
holder.mModel.mKeySize,
holder.mModel.mCurve
);
boolean isMasterKey = position == 0;
if (isMasterKey) {
holder.vKeyId.setTypeface(null, Typeface.BOLD);
} else {
holder.vKeyId.setTypeface(null, Typeface.NORMAL);
}
holder.vKeyId.setText(R.string.edit_key_new_subkey);
holder.vKeyDetails.setText(algorithmStr);

View File

@ -69,6 +69,54 @@
android:text="@string/create_key_upload"
android:id="@+id/create_key_upload" />
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/create_key_edit_text"
android:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/create_key_rsa"
android:textColor="@color/android_green_dark"
android:textAppearance="?android:attr/textAppearanceMedium"
android:minHeight="?android:attr/listPreferredItemHeight"
android:clickable="true"
android:gravity="center_vertical"
android:layout_gravity="center_vertical" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider" />
<TextView
android:id="@+id/create_key_edit_button"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/create_key_edit"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:clickable="true"
style="@style/SelectableItem"
android:layout_gravity="center_vertical" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dip"

View File

@ -495,7 +495,7 @@
<item>"Revoke Subkey"</item>
<item>"Strip Subkey"</item>
</string-array>
<string name="edit_key_new_subkey">"new"</string>
<string name="edit_key_new_subkey">"new subkey"</string>
<string name="edit_key_select_flag">"Please select at least one flag!"</string>
<!-- Create key -->
@ -503,9 +503,12 @@
<string name="create_key_empty">"This field is required"</string>
<string name="create_key_passphrases_not_equal">"Passphrases do not match"</string>
<string name="create_key_final_text">"You entered the following identity:"</string>
<string name="create_key_final_robot_text">"Creating a key may take a while, have a cup of coffee in the meantime…\n(3 subkeys, RSA, 4096 bit)"</string>
<string name="create_key_final_robot_text">"Creating a key may take a while, have a cup of coffee in the meantime…"</string>
<string name="create_key_rsa">"(3 subkeys, RSA, 4096 bit)"</string>
<string name="create_key_custom">"(custom key configuration)"</string>
<string name="create_key_text">"Enter your full name, email address, and choose a passhrase."</string>
<string name="create_key_hint_full_name">"Full Name, e.g. Max Mustermann"</string>
<string name="create_key_edit">"Change key configuration"</string>
<!-- View key -->
<string name="view_key_revoked">"This key has been revoked!"</string>