mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 19:22:14 -05:00
more work on streamlining uris, and stripping ProviderHelper
This commit is contained in:
parent
428e94bb57
commit
dedcfd8a72
@ -256,6 +256,9 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
+ Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
+ Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uri to watch is all /key_rings/
|
||||||
|
uri = KeyRings.CONTENT_URI;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*case SECRET_KEY_RING_BY_EMAILS:
|
/*case SECRET_KEY_RING_BY_EMAILS:
|
||||||
@ -503,6 +506,7 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
// corresponding keys and userIds are deleted by ON DELETE CASCADE
|
// corresponding keys and userIds are deleted by ON DELETE CASCADE
|
||||||
count = db.delete(Tables.KEY_RINGS_PUBLIC, selection, selectionArgs);
|
count = db.delete(Tables.KEY_RINGS_PUBLIC, selection, selectionArgs);
|
||||||
|
uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KEY_RING_SECRET: {
|
case KEY_RING_SECRET: {
|
||||||
@ -512,6 +516,7 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
selection += " AND (" + additionalSelection + ")";
|
selection += " AND (" + additionalSelection + ")";
|
||||||
}
|
}
|
||||||
count = db.delete(Tables.KEY_RINGS_SECRET, selection, selectionArgs);
|
count = db.delete(Tables.KEY_RINGS_SECRET, selection, selectionArgs);
|
||||||
|
uri = KeyRings.buildGenericKeyRingUri(uri.getPathSegments().get(1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,10 @@ import android.content.ContentValues;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.OperationApplicationException;
|
import android.content.OperationApplicationException;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.database.CursorWindow;
|
||||||
|
import android.database.CursorWrapper;
|
||||||
import android.database.DatabaseUtils;
|
import android.database.DatabaseUtils;
|
||||||
|
import android.database.sqlite.SQLiteCursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
||||||
@ -42,7 +45,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
|
|||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
|
|
||||||
import org.sufficientlysecure.keychain.remote.AccountSettings;
|
import org.sufficientlysecure.keychain.remote.AccountSettings;
|
||||||
import org.sufficientlysecure.keychain.remote.AppSettings;
|
import org.sufficientlysecure.keychain.remote.AppSettings;
|
||||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
@ -52,6 +54,7 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -81,6 +84,57 @@ public class ProviderHelper {
|
|||||||
return keyRing;
|
return keyRing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object getUnifiedData(Context context, long masterKeyId, String column) {
|
||||||
|
return getUnifiedData(context, masterKeyId, new String[] { column }).get(column);
|
||||||
|
}
|
||||||
|
public static Object getUnifiedData(Context context, Uri uri, String column) {
|
||||||
|
return getUnifiedData(context, uri, new String[] { column }).get(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String,Object> getUnifiedData(Context context, long masterKeyId, String[] proj) {
|
||||||
|
return getUnifiedData(context, KeyRings.buildGenericKeyRingUri(Long.toString(masterKeyId)), proj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<String,Object> getUnifiedData(Context context, Uri uri, String[] proj) {
|
||||||
|
uri = KeyRings.buildUnifiedKeyRingUri(uri);
|
||||||
|
|
||||||
|
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
|
||||||
|
|
||||||
|
HashMap<String, Object> result = new HashMap<String, Object>(proj.length);
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
// this is a HACK because we don't have Cursor.getType (which is api level 11)
|
||||||
|
CursorWindow cursorWindow;
|
||||||
|
if(cursor instanceof CursorWrapper) {
|
||||||
|
cursorWindow = ((SQLiteCursor) ((CursorWrapper) cursor).getWrappedCursor()).getWindow();
|
||||||
|
} else {
|
||||||
|
cursorWindow = ((SQLiteCursor) cursor).getWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
for(String p : proj) {
|
||||||
|
if (cursorWindow.isNull(0, pos)) {
|
||||||
|
result.put(p, cursor.isNull(pos));
|
||||||
|
} else if (cursorWindow.isLong(0, pos)) {
|
||||||
|
result.put(p, cursor.getLong(pos));
|
||||||
|
} else if (cursorWindow.isFloat(0, pos)) {
|
||||||
|
result.put(p, cursor.getFloat(pos));
|
||||||
|
} else if (cursorWindow.isString(0, pos)) {
|
||||||
|
result.put(p, cursor.getString(pos));
|
||||||
|
} else if (cursorWindow.isBlob(0, pos)) {
|
||||||
|
result.put(p, cursor.getBlob(pos));
|
||||||
|
}
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
|
public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
|
||||||
return getPGPPublicKeyRingWithKeyId(context, keyId).getPublicKey(keyId);
|
return getPGPPublicKeyRingWithKeyId(context, keyId).getPublicKey(keyId);
|
||||||
}
|
}
|
||||||
@ -307,84 +361,6 @@ public class ProviderHelper {
|
|||||||
return masterKeyId;
|
return masterKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getRowId(Context context, Uri queryUri) {
|
|
||||||
String[] projection = new String[]{KeyRings._ID};
|
|
||||||
Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
|
|
||||||
|
|
||||||
long rowId = 0;
|
|
||||||
try {
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
int idCol = cursor.getColumnIndexOrThrow(KeyRings._ID);
|
|
||||||
|
|
||||||
rowId = cursor.getLong(idCol);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rowId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get fingerprint of key
|
|
||||||
*/
|
|
||||||
public static byte[] getFingerprint(Context context, Uri queryUri) {
|
|
||||||
String[] projection = new String[]{Keys.FINGERPRINT};
|
|
||||||
Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
|
|
||||||
|
|
||||||
byte[] fingerprint = null;
|
|
||||||
try {
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
int col = cursor.getColumnIndexOrThrow(Keys.FINGERPRINT);
|
|
||||||
|
|
||||||
fingerprint = cursor.getBlob(col);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FALLBACK: If fingerprint is not in database, get it from key blob!
|
|
||||||
// this could happen if the key was saved by a previous version of Keychain!
|
|
||||||
if (fingerprint == null) {
|
|
||||||
Log.d(Constants.TAG, "FALLBACK: fingerprint is not in database, get it from key blob!");
|
|
||||||
|
|
||||||
// get master key id
|
|
||||||
projection = new String[]{KeyRings.MASTER_KEY_ID};
|
|
||||||
cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
|
|
||||||
long masterKeyId = 0;
|
|
||||||
try {
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
int col = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID);
|
|
||||||
|
|
||||||
masterKeyId = cursor.getLong(col);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PGPPublicKey key = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId).getPublicKey();
|
|
||||||
// if it is no public key get it from your own keys...
|
|
||||||
if (key == null) {
|
|
||||||
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId).getSecretKey();
|
|
||||||
if (secretKey == null) {
|
|
||||||
Log.e(Constants.TAG, "Key could not be found!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
key = secretKey.getPublicKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
fingerprint = key.getFingerprint();
|
|
||||||
}
|
|
||||||
|
|
||||||
return fingerprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri,
|
public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri,
|
||||||
long[] masterKeyIds) {
|
long[] masterKeyIds) {
|
||||||
ArrayList<String> output = new ArrayList<String>();
|
ArrayList<String> output = new ArrayList<String>();
|
||||||
|
@ -34,6 +34,7 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
|
|||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.remote.AccountSettings;
|
import org.sufficientlysecure.keychain.remote.AccountSettings;
|
||||||
import org.sufficientlysecure.keychain.ui.EditKeyActivity;
|
import org.sufficientlysecure.keychain.ui.EditKeyActivity;
|
||||||
import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment;
|
import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment;
|
||||||
@ -176,9 +177,8 @@ public class AccountSettingsFragment extends Fragment implements
|
|||||||
case REQUEST_CODE_CREATE_KEY: {
|
case REQUEST_CODE_CREATE_KEY: {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
// select newly created key
|
// select newly created key
|
||||||
Uri newKeyUri = data.getData();
|
long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), data.getData());
|
||||||
// TODO helper method for this?
|
mSelectKeyFragment.selectKey(masterKeyId);
|
||||||
mSelectKeyFragment.selectKey(Long.parseLong(newKeyUri.getPathSegments().get(1)));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,10 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
|
|||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
public class EncryptAsymmetricFragment extends Fragment {
|
public class EncryptAsymmetricFragment extends Fragment {
|
||||||
@ -202,20 +204,17 @@ public class EncryptAsymmetricFragment extends Fragment {
|
|||||||
} else {
|
} else {
|
||||||
String uid = getResources().getString(R.string.user_id_no_name);
|
String uid = getResources().getString(R.string.user_id_no_name);
|
||||||
String uidExtra = "";
|
String uidExtra = "";
|
||||||
// TODO: don't use bouncy castle objects!
|
// See if we can get a user_id from a unified query
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(),
|
Object data = ProviderHelper.getUnifiedData(
|
||||||
mSecretKeyId);
|
getActivity(), mSecretKeyId, KeychainContract.UserIds.USER_ID);
|
||||||
if (keyRing != null) {
|
if(data instanceof String) {
|
||||||
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
|
String chunks[] = ((String) data).split(" <", 2);
|
||||||
if (key != null) {
|
uid = chunks[0];
|
||||||
String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key);
|
if (chunks.length > 1) {
|
||||||
String chunks[] = userId.split(" <", 2);
|
uidExtra = "<" + chunks[1];
|
||||||
uid = chunks[0];
|
|
||||||
if (chunks.length > 1) {
|
|
||||||
uidExtra = "<" + chunks[1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mMainUserId.setText(uid);
|
mMainUserId.setText(uid);
|
||||||
mMainUserIdRest.setText(uidExtra);
|
mMainUserIdRest.setText(uidExtra);
|
||||||
mSign.setChecked(true);
|
mSign.setChecked(true);
|
||||||
|
@ -193,28 +193,15 @@ public class KeyListFragment extends Fragment
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.menu_key_list_multi_delete: {
|
case R.id.menu_key_list_multi_delete: {
|
||||||
ids = mStickyList.getWrappedList().getCheckedItemIds();
|
ids = mAdapter.getCurrentSelectedMasterKeyIds();
|
||||||
showDeleteKeyDialog(mode, ids);
|
showDeleteKeyDialog(mode, ids);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case R.id.menu_key_list_multi_export: {
|
case R.id.menu_key_list_multi_export: {
|
||||||
ids = mStickyList.getWrappedList().getCheckedItemIds();
|
ids = mAdapter.getCurrentSelectedMasterKeyIds();
|
||||||
long[] masterKeyIds = new long[2*ids.length];
|
|
||||||
/* TODO! redo
|
|
||||||
ArrayList<Long> allPubRowIds =
|
|
||||||
ProviderHelper.getPublicKeyRingsRowIds(getActivity());
|
|
||||||
for (int i = 0; i < ids.length; i++) {
|
|
||||||
if (allPubRowIds.contains(ids[i])) {
|
|
||||||
masterKeyIds[i] =
|
|
||||||
ProviderHelper.getPublicMasterKeyId(getActivity(), ids[i]);
|
|
||||||
} else {
|
|
||||||
masterKeyIds[i] =
|
|
||||||
ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
|
ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
|
||||||
mExportHelper
|
mExportHelper
|
||||||
.showExportKeysDialog(masterKeyIds, Id.type.public_key,
|
.showExportKeysDialog(ids, Id.type.public_key,
|
||||||
Constants.Path.APP_DIR_FILE_PUB,
|
Constants.Path.APP_DIR_FILE_PUB,
|
||||||
getString(R.string.also_export_secret_keys));
|
getString(R.string.also_export_secret_keys));
|
||||||
break;
|
break;
|
||||||
@ -343,7 +330,7 @@ public class KeyListFragment extends Fragment
|
|||||||
}
|
}
|
||||||
viewIntent.setData(
|
viewIntent.setData(
|
||||||
KeychainContract
|
KeychainContract
|
||||||
.KeyRings.buildPublicKeyRingUri(
|
.KeyRings.buildGenericKeyRingUri(
|
||||||
Long.toString(mAdapter.getMasterKeyId(position))));
|
Long.toString(mAdapter.getMasterKeyId(position))));
|
||||||
startActivity(viewIntent);
|
startActivity(viewIntent);
|
||||||
}
|
}
|
||||||
@ -362,11 +349,11 @@ public class KeyListFragment extends Fragment
|
|||||||
/**
|
/**
|
||||||
* Show dialog to delete key
|
* Show dialog to delete key
|
||||||
*
|
*
|
||||||
* @param keyRingRowIds
|
* @param masterKeyIds
|
||||||
*/
|
*/
|
||||||
@TargetApi(11)
|
@TargetApi(11)
|
||||||
// TODO: this method needs an overhaul to handle both public and secret keys gracefully!
|
// TODO: this method needs an overhaul to handle both public and secret keys gracefully!
|
||||||
public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) {
|
public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds) {
|
||||||
// Message is received after key is deleted
|
// Message is received after key is deleted
|
||||||
Handler returnHandler = new Handler() {
|
Handler returnHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
@ -381,7 +368,7 @@ public class KeyListFragment extends Fragment
|
|||||||
Messenger messenger = new Messenger(returnHandler);
|
Messenger messenger = new Messenger(returnHandler);
|
||||||
|
|
||||||
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
|
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
|
||||||
keyRingRowIds);
|
masterKeyIds);
|
||||||
|
|
||||||
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
|
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
|
||||||
}
|
}
|
||||||
|
@ -173,10 +173,15 @@ public class ViewKeyActivity extends ActionBarActivity {
|
|||||||
private void shareKey(Uri dataUri, boolean fingerprintOnly) {
|
private void shareKey(Uri dataUri, boolean fingerprintOnly) {
|
||||||
String content;
|
String content;
|
||||||
if (fingerprintOnly) {
|
if (fingerprintOnly) {
|
||||||
byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
|
Object blob = ProviderHelper.getUnifiedData(this, dataUri, KeychainContract.Keys.FINGERPRINT);
|
||||||
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
|
if(blob instanceof byte[]) {
|
||||||
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob);
|
||||||
content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
|
content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getApplicationContext(), "Bad key selected!",
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// get public keyring as ascii armored string
|
// get public keyring as ascii armored string
|
||||||
long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
|
long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
|
||||||
|
@ -34,6 +34,9 @@ import android.widget.Toast;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||||
public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
|
public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
|
||||||
@ -64,13 +67,17 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
|
|||||||
|
|
||||||
// get public keyring as byte array
|
// get public keyring as byte array
|
||||||
long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
|
long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
|
||||||
mSharedKeyringBytes = ProviderHelper.getKeyRingsAsByteArray(this, dataUri,
|
try {
|
||||||
new long[]{masterKeyId});
|
mSharedKeyringBytes = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId).getEncoded();
|
||||||
|
|
||||||
// Register callback to set NDEF message
|
// Register callback to set NDEF message
|
||||||
mNfcAdapter.setNdefPushMessageCallback(this, this);
|
mNfcAdapter.setNdefPushMessageCallback(this, this);
|
||||||
// Register callback to listen for message-sent success
|
// Register callback to listen for message-sent success
|
||||||
mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
|
mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
|
||||||
|
} catch(IOException e) {
|
||||||
|
// not much trouble, but leave a note
|
||||||
|
Log.e(Constants.TAG, "Error parsing keyring: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,10 +298,6 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
mAlgorithm.setText(algorithmStr);
|
mAlgorithm.setText(algorithmStr);
|
||||||
|
|
||||||
byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
|
byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
|
||||||
if (fingerprintBlob == null) {
|
|
||||||
// FALLBACK for old database entries
|
|
||||||
fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
|
|
||||||
}
|
|
||||||
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
|
||||||
|
|
||||||
mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
|
mFingerprint.setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
|
||||||
|
@ -43,10 +43,11 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
|||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class DeleteKeyDialogFragment extends DialogFragment {
|
public class DeleteKeyDialogFragment extends DialogFragment {
|
||||||
private static final String ARG_MESSENGER = "messenger";
|
private static final String ARG_MESSENGER = "messenger";
|
||||||
private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_key_ring_row_ids";
|
private static final String ARG_DELETE_MASTER_KEY_IDS = "delete_master_key_ids";
|
||||||
|
|
||||||
public static final int MESSAGE_OKAY = 1;
|
public static final int MESSAGE_OKAY = 1;
|
||||||
public static final int MESSAGE_ERROR = 0;
|
public static final int MESSAGE_ERROR = 0;
|
||||||
@ -63,13 +64,13 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
/**
|
/**
|
||||||
* Creates new instance of this delete file dialog fragment
|
* Creates new instance of this delete file dialog fragment
|
||||||
*/
|
*/
|
||||||
public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds
|
public static DeleteKeyDialogFragment newInstance(Messenger messenger,
|
||||||
) {
|
long[] masterKeyIds) {
|
||||||
DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
|
DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
|
|
||||||
args.putParcelable(ARG_MESSENGER, messenger);
|
args.putParcelable(ARG_MESSENGER, messenger);
|
||||||
args.putLongArray(ARG_DELETE_KEY_RING_ROW_IDS, keyRingRowIds);
|
args.putLongArray(ARG_DELETE_MASTER_KEY_IDS, masterKeyIds);
|
||||||
//We don't need the key type
|
//We don't need the key type
|
||||||
|
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
@ -84,7 +85,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
final FragmentActivity activity = getActivity();
|
final FragmentActivity activity = getActivity();
|
||||||
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
|
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||||
|
|
||||||
final long[] keyRingRowIds = getArguments().getLongArray(ARG_DELETE_KEY_RING_ROW_IDS);
|
final long[] masterKeyIds = getArguments().getLongArray(ARG_DELETE_MASTER_KEY_IDS);
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
|
|
||||||
@ -98,35 +99,29 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
mCheckDeleteSecret = (CheckBox) mInflateView.findViewById(R.id.checkDeleteSecret);
|
mCheckDeleteSecret = (CheckBox) mInflateView.findViewById(R.id.checkDeleteSecret);
|
||||||
|
|
||||||
builder.setTitle(R.string.warning);
|
builder.setTitle(R.string.warning);
|
||||||
/* TODO! redo
|
|
||||||
|
|
||||||
//If only a single key has been selected
|
// If only a single key has been selected
|
||||||
if (keyRingRowIds.length == 1) {
|
if (masterKeyIds.length == 1) {
|
||||||
Uri dataUri;
|
|
||||||
ArrayList<Long> publicKeyRings; //Any one will do
|
|
||||||
mIsSingleSelection = true;
|
mIsSingleSelection = true;
|
||||||
|
|
||||||
long selectedRow = keyRingRowIds[0];
|
long masterKeyId = masterKeyIds[0];
|
||||||
long keyType;
|
|
||||||
publicKeyRings = ProviderHelper.getPublicKeyRingsRowIds(activity);
|
|
||||||
|
|
||||||
if (publicKeyRings.contains(selectedRow)) {
|
HashMap<String, Object> data = ProviderHelper.getUnifiedData(activity, masterKeyId, new String[]{
|
||||||
//TODO Should be a better method to do this other than getting all the KeyRings
|
KeychainContract.UserIds.USER_ID,
|
||||||
dataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(String.valueOf(selectedRow));
|
KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID
|
||||||
keyType = Id.type.public_key;
|
});
|
||||||
} else {
|
String userId = (String) data.get(KeychainContract.UserIds.USER_ID);
|
||||||
dataUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(String.valueOf(selectedRow));
|
boolean hasSecret = data.get(
|
||||||
keyType = Id.type.secret_key;
|
KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID
|
||||||
}
|
) instanceof Long;
|
||||||
|
|
||||||
String userId = ProviderHelper.getUserId(activity, dataUri);
|
// Hide the Checkbox and TextView since this is a single selection,user will be notified through message
|
||||||
// Hide the Checkbox and TextView since this is a single selection,
|
|
||||||
// user will be notified thru message
|
|
||||||
mDeleteSecretKeyView.setVisibility(View.GONE);
|
mDeleteSecretKeyView.setVisibility(View.GONE);
|
||||||
// Set message depending on which key it is.
|
// Set message depending on which key it is.
|
||||||
mMainMessage.setText(getString(keyType == Id.type.secret_key ?
|
mMainMessage.setText(getString(
|
||||||
R.string.secret_key_deletion_confirmation :
|
hasSecret ? R.string.secret_key_deletion_confirmation
|
||||||
R.string.public_key_deletetion_confirmation, userId));
|
: R.string.public_key_deletetion_confirmation,
|
||||||
|
userId));
|
||||||
} else {
|
} else {
|
||||||
mDeleteSecretKeyView.setVisibility(View.VISIBLE);
|
mDeleteSecretKeyView.setVisibility(View.VISIBLE);
|
||||||
mMainMessage.setText(R.string.key_deletion_confirmation_multi);
|
mMainMessage.setText(R.string.key_deletion_confirmation_multi);
|
||||||
@ -137,75 +132,27 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
Uri queryUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri();
|
|
||||||
String[] projection = new String[]{
|
|
||||||
KeychainContract.KeyRings.MASTER_KEY_ID, // 0
|
|
||||||
KeychainContract.KeyRings.TYPE// 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// make selection with all entries where _ID is one of the given row ids
|
boolean success = false;
|
||||||
String selection = KeychainDatabase.Tables.KEY_RINGS + "." +
|
for(long masterKeyId : masterKeyIds) {
|
||||||
KeychainContract.KeyRings._ID + " IN(";
|
int count = activity.getContentResolver().delete(
|
||||||
String selectionIDs = "";
|
KeychainContract.KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null
|
||||||
for (int i = 0; i < keyRingRowIds.length; i++) {
|
);
|
||||||
selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'";
|
if(count > 0)
|
||||||
if (i + 1 < keyRingRowIds.length) {
|
success = true;
|
||||||
selectionIDs += ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selection += selectionIDs + ")";
|
|
||||||
|
|
||||||
Cursor cursor = activity.getContentResolver().query(queryUri, projection,
|
|
||||||
selection, null, null);
|
|
||||||
|
|
||||||
|
|
||||||
long masterKeyId;
|
|
||||||
long keyType;
|
|
||||||
boolean isSuccessfullyDeleted;
|
|
||||||
try {
|
|
||||||
isSuccessfullyDeleted = false;
|
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
|
||||||
masterKeyId = cursor.getLong(0);
|
|
||||||
keyType = cursor.getLong(1);
|
|
||||||
|
|
||||||
Log.d(Constants.TAG, "masterKeyId: " + masterKeyId +
|
|
||||||
", keyType:" +
|
|
||||||
(keyType == KeychainContract.KeyTypes.PUBLIC ?
|
|
||||||
"Public" : "Private"));
|
|
||||||
|
|
||||||
if (keyType == KeychainContract.KeyTypes.SECRET) {
|
|
||||||
if (mCheckDeleteSecret.isChecked() || mIsSingleSelection) {
|
|
||||||
ProviderHelper.deleteUnifiedKeyRing(activity,
|
|
||||||
String.valueOf(masterKeyId), true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ProviderHelper.deleteUnifiedKeyRing(activity,
|
|
||||||
String.valueOf(masterKeyId), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check if the selected rows have actually been deleted
|
|
||||||
cursor = activity.getContentResolver().query(
|
|
||||||
queryUri, projection, selection, null, null);
|
|
||||||
if (cursor == null || cursor.getCount() == 0 ||
|
|
||||||
!mCheckDeleteSecret.isChecked()) {
|
|
||||||
isSuccessfullyDeleted = true;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
|
|
||||||
if (isSuccessfullyDeleted) {
|
if (success) {
|
||||||
sendMessageToHandler(MESSAGE_OKAY, null);
|
sendMessageToHandler(MESSAGE_OKAY, null);
|
||||||
} else {
|
} else {
|
||||||
sendMessageToHandler(MESSAGE_ERROR, null);
|
sendMessageToHandler(MESSAGE_ERROR, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
}
|
||||||
|
);
|
||||||
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -213,7 +160,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import android.widget.TextView;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.util.QrCodeUtils;
|
import org.sufficientlysecure.keychain.util.QrCodeUtils;
|
||||||
|
|
||||||
@ -89,22 +90,24 @@ public class ShareQrCodeDialogFragment extends DialogFragment {
|
|||||||
if (mFingerprintOnly) {
|
if (mFingerprintOnly) {
|
||||||
alert.setPositiveButton(R.string.btn_okay, null);
|
alert.setPositiveButton(R.string.btn_okay, null);
|
||||||
|
|
||||||
byte[] fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), dataUri);
|
Object blob = ProviderHelper.getUnifiedData(getActivity(), dataUri, KeychainContract.Keys.FINGERPRINT);
|
||||||
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
|
if(!(blob instanceof byte[])) {
|
||||||
|
// TODO error handling?!
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex((byte[]) blob);
|
||||||
mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint);
|
mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint);
|
||||||
|
|
||||||
content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
|
content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
|
||||||
setQrCode(content);
|
setQrCode(content);
|
||||||
} else {
|
} else {
|
||||||
mText.setText(R.string.share_qr_code_dialog_start);
|
mText.setText(R.string.share_qr_code_dialog_start);
|
||||||
|
|
||||||
// TODO
|
// TODO works, but
|
||||||
long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
|
long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
|
||||||
|
|
||||||
// get public keyring as ascii armored string
|
// get public keyring as ascii armored string
|
||||||
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
|
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
|
||||||
getActivity(), dataUri, new long[]{masterKeyId});
|
getActivity(), dataUri, new long[] { masterKeyId });
|
||||||
|
|
||||||
// TODO: binary?
|
// TODO: binary?
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user