fixed sql quieries in select pub/secret key

This commit is contained in:
Dominik 2012-11-17 19:54:49 +01:00
parent 56cfb6bc5a
commit 0123bef9ce
7 changed files with 82 additions and 45 deletions

View File

@ -260,8 +260,8 @@
<string name="error_wrongPassPhrase">wrong passphrase</string> <string name="error_wrongPassPhrase">wrong passphrase</string>
<string name="error_savingKeys">error saving some key(s)</string> <string name="error_savingKeys">error saving some key(s)</string>
<string name="error_couldNotExtractPrivateKey">could not extract private key</string> <string name="error_couldNotExtractPrivateKey">could not extract private key</string>
<string name="error_onlyFilesAreSupported">Direct binary data without actual file in filesystem is not supported</string> <string name="error_onlyFilesAreSupported">Direct binary data without actual file in filesystem is not supported. This is only supported by ACTION_ENCRYPT_STREAM_AND_RETURN.</string>
<!-- progress_lowerCase: lowercase, phrases, usually ending in '…' --> <!-- progress_lowerCase: lowercase, phrases, usually ending in '…' -->
<string name="progress_done">done.</string> <string name="progress_done">done.</string>
<string name="progress_initializing">initializing…</string> <string name="progress_initializing">initializing…</string>
@ -305,7 +305,7 @@
<string name="permission_read_key_database_description">Read key details of public and secret keys stored in APG, such as key ID and user IDs. The keys themselves can NOT be read.</string> <string name="permission_read_key_database_description">Read key details of public and secret keys stored in APG, such as key ID and user IDs. The keys themselves can NOT be read.</string>
<string name="permission_access_api_label">Encrypt/Sign/Decrypt/Create keys without user interaction</string> <string name="permission_access_api_label">Encrypt/Sign/Decrypt/Create keys without user interaction</string>
<string name="permission_access_api_description">Encrypt/Sign/Decrypt/Create keys (by using Intents or Remote Service) without user interaction</string> <string name="permission_access_api_description">Encrypt/Sign/Decrypt/Create keys (by using Intents or Remote Service) without user interaction</string>
<!-- action strings --> <!-- action strings -->
<string name="action_encrypt">Encrypt</string> <string name="action_encrypt">Encrypt</string>
<string name="action_decrypt">Decrypt</string> <string name="action_decrypt">Decrypt</string>

View File

@ -193,10 +193,12 @@ public class PGPHelper {
public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) { public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) {
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, masterKeyId); PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context, masterKeyId);
if (keyRing == null) { if (keyRing == null) {
Log.e(Constants.TAG, "keyRing is null!");
return null; return null;
} }
Vector<PGPPublicKey> encryptKeys = getUsableEncryptKeys(keyRing); Vector<PGPPublicKey> encryptKeys = getUsableEncryptKeys(keyRing);
if (encryptKeys.size() == 0) { if (encryptKeys.size() == 0) {
Log.e(Constants.TAG, "encryptKeys is null!");
return null; return null;
} }
return encryptKeys.get(0); return encryptKeys.get(0);

View File

@ -348,22 +348,41 @@ public class ApgProvider extends ContentProvider {
* @param sortOrder * @param sortOrder
* @return * @return
*/ */
private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match, private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match, String sortOrder) {
boolean isMasterKey, String sortOrder) {
qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = ");
qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
String isMasterKeyQuery = ""; qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.USER_IDS + " ON " + "("
if (isMasterKey) { + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "."
isMasterKeyQuery = " AND " + Tables.KEYS + "." + KeysColumns.IS_MASTER_KEY + " = '1'"; + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "."
} + UserIdsColumns.RANK + " = '0')");
qb.setProjectionMap(getProjectionMapForKeyRings());
return qb;
}
/**
* Builds default query for keyRings: KeyRings table is joined with Keys and UserIds
*
* @param qb
* @param match
* @param isMasterKey
* @param sortOrder
* @return
*/
private SQLiteQueryBuilder buildKeyRingQueryWithKeys(SQLiteQueryBuilder qb, int match,
String sortOrder) {
qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = ");
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "("
+ Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "."
+ KeysColumns.KEY_RING_ROW_ID + isMasterKeyQuery + ") " + " INNER JOIN " + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "."
+ Tables.USER_IDS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + KeysColumns.IS_MASTER_KEY + " = '1') " + " INNER JOIN " + Tables.USER_IDS
+ Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS
+ Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0')"); + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "."
+ UserIdsColumns.RANK + " = '0')");
qb.setProjectionMap(getProjectionMapForKeyRings()); qb.setProjectionMap(getProjectionMapForKeyRings());
@ -385,7 +404,7 @@ public class ApgProvider extends ContentProvider {
switch (match) { switch (match) {
case PUBLIC_KEY_RING: case PUBLIC_KEY_RING:
case SECRET_KEY_RING: case SECRET_KEY_RING:
qb = buildKeyRingQuery(qb, match, true, sortOrder); qb = buildKeyRingQuery(qb, match, sortOrder);
if (TextUtils.isEmpty(sortOrder)) { if (TextUtils.isEmpty(sortOrder)) {
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
@ -395,7 +414,7 @@ public class ApgProvider extends ContentProvider {
case PUBLIC_KEY_RING_BY_ROW_ID: case PUBLIC_KEY_RING_BY_ROW_ID:
case SECRET_KEY_RING_BY_ROW_ID: case SECRET_KEY_RING_BY_ROW_ID:
qb = buildKeyRingQuery(qb, match, true, sortOrder); qb = buildKeyRingQuery(qb, match, sortOrder);
qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = "); qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = ");
qb.appendWhereEscapeString(uri.getLastPathSegment()); qb.appendWhereEscapeString(uri.getLastPathSegment());
@ -408,7 +427,7 @@ public class ApgProvider extends ContentProvider {
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
case SECRET_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID:
qb = buildKeyRingQuery(qb, match, true, sortOrder); qb = buildKeyRingQuery(qb, match, sortOrder);
qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = ");
qb.appendWhereEscapeString(uri.getLastPathSegment()); qb.appendWhereEscapeString(uri.getLastPathSegment());
@ -421,7 +440,7 @@ public class ApgProvider extends ContentProvider {
case SECRET_KEY_RING_BY_KEY_ID: case SECRET_KEY_RING_BY_KEY_ID:
case PUBLIC_KEY_RING_BY_KEY_ID: case PUBLIC_KEY_RING_BY_KEY_ID:
qb = buildKeyRingQuery(qb, match, false, sortOrder); qb = buildKeyRingQueryWithKeys(qb, match, sortOrder);
qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.KEY_ID + " = "); qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.KEY_ID + " = ");
qb.appendWhereEscapeString(uri.getLastPathSegment()); qb.appendWhereEscapeString(uri.getLastPathSegment());

View File

@ -77,7 +77,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
public static final String ACTION_GENERATE_SIGNATURE_AND_RETURN = Constants.INTENT_PREFIX public static final String ACTION_GENERATE_SIGNATURE_AND_RETURN = Constants.INTENT_PREFIX
+ "GENERATE_SIGNATURE"; + "GENERATE_SIGNATURE";
public static final String ACTION_ENCRYPT_STREAM = Constants.INTENT_PREFIX + "ENCRYPT_STREAM"; public static final String ACTION_ENCRYPT_FILE = Constants.INTENT_PREFIX + "ENCRYPT_FILE";
public static final String ACTION_ENCRYPT_STREAM_AND_RETURN = Constants.INTENT_PREFIX public static final String ACTION_ENCRYPT_STREAM_AND_RETURN = Constants.INTENT_PREFIX
+ "ENCRYPT_STREAM_AND_RETURN"; + "ENCRYPT_STREAM_AND_RETURN";
@ -132,9 +132,9 @@ public class EncryptActivity extends SherlockFragmentActivity {
private String mInputFilename = null; private String mInputFilename = null;
private String mOutputFilename = null; private String mOutputFilename = null;
private boolean mAsciiArmourDemand = false; private boolean mAsciiArmorDemand = false;
private boolean mOverrideAsciiArmour = false; private boolean mOverrideAsciiArmour = false;
private Uri mIntentDataUri = null; private Uri mStreamAndReturnUri = null;
private byte[] mData = null; private byte[] mData = null;
private boolean mGenerateSignature = false; private boolean mGenerateSignature = false;
@ -265,7 +265,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
} else { } else {
// files via content provider, override uri and action // files via content provider, override uri and action
uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
action = ACTION_ENCRYPT_STREAM; action = ACTION_ENCRYPT_FILE;
} }
} }
@ -277,13 +277,13 @@ public class EncryptActivity extends SherlockFragmentActivity {
if (ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) { if (ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) {
mGenerateSignature = true; mGenerateSignature = true;
mOverrideAsciiArmour = true; mOverrideAsciiArmour = true;
mAsciiArmourDemand = false; mAsciiArmorDemand = false;
} }
if (extras.containsKey(EXTRA_ASCII_ARMOUR)) { if (extras.containsKey(EXTRA_ASCII_ARMOUR)) {
mAsciiArmourDemand = extras.getBoolean(EXTRA_ASCII_ARMOUR, true); mAsciiArmorDemand = extras.getBoolean(EXTRA_ASCII_ARMOUR, true);
mOverrideAsciiArmour = true; mOverrideAsciiArmour = true;
mAsciiArmour.setChecked(mAsciiArmourDemand); mAsciiArmour.setChecked(mAsciiArmorDemand);
} }
mData = extras.getByteArray(EXTRA_DATA); mData = extras.getByteArray(EXTRA_DATA);
@ -309,7 +309,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
while (mSource.getCurrentView().getId() != R.id.sourceMessage) { while (mSource.getCurrentView().getId() != R.id.sourceMessage) {
mSource.showNext(); mSource.showNext();
} }
} else if (ACTION_ENCRYPT_STREAM.equals(action)) { } else if (ACTION_ENCRYPT_FILE.equals(action)) {
// get file path from uri // get file path from uri
String path = FileHelper.getPath(this, uri); String path = FileHelper.getPath(this, uri);
@ -324,7 +324,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
} }
} else { } else {
Log.e(Constants.TAG, Log.e(Constants.TAG,
"Direct binary data without actual file in filesystem is not supported"); "Direct binary data without actual file in filesystem is not supported. This is only supported by ACTION_ENCRYPT_STREAM_AND_RETURN.");
Toast.makeText(this, R.string.error_onlyFilesAreSupported, Toast.LENGTH_LONG) Toast.makeText(this, R.string.error_onlyFilesAreSupported, Toast.LENGTH_LONG)
.show(); .show();
// end activity // end activity
@ -334,6 +334,8 @@ public class EncryptActivity extends SherlockFragmentActivity {
} else if (ACTION_ENCRYPT_STREAM_AND_RETURN.equals(action)) { } else if (ACTION_ENCRYPT_STREAM_AND_RETURN.equals(action)) {
// use mIntentDataUri to encrypt any stream and return // use mIntentDataUri to encrypt any stream and return
// TODO // TODO
mStreamAndReturnUri = null;
} }
} }
@ -687,9 +689,10 @@ public class EncryptActivity extends SherlockFragmentActivity {
intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_ENCRYPT_SIGN); intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_ENCRYPT_SIGN);
// choose default settings, target and data bundle by target // choose default settings, target and data bundle by target
if (mIntentDataUri != null) { if (mStreamAndReturnUri != null) {
// mIntentDataUri is only defined when ACTION_ENCRYPT_STREAM_AND_RETURN is used
data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_STREAM); data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_STREAM);
data.putParcelable(ApgIntentService.PROVIDER_URI, mIntentDataUri); data.putParcelable(ApgIntentService.PROVIDER_URI, mStreamAndReturnUri);
} else if (mEncryptTarget == Id.target.file) { } else if (mEncryptTarget == Id.target.file) {
useAsciiArmor = mAsciiArmour.isChecked(); useAsciiArmor = mAsciiArmour.isChecked();
@ -721,7 +724,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
} }
if (mOverrideAsciiArmour) { if (mOverrideAsciiArmour) {
useAsciiArmor = mAsciiArmourDemand; useAsciiArmor = mAsciiArmorDemand;
} }
data.putLong(ApgIntentService.SECRET_KEY_ID, mSecretKeyId); data.putLong(ApgIntentService.SECRET_KEY_ID, mSecretKeyId);

View File

@ -22,6 +22,7 @@ import java.util.Vector;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.provider.ApgDatabase;
import org.thialfihar.android.apg.provider.ApgContract.KeyRings; import org.thialfihar.android.apg.provider.ApgContract.KeyRings;
import org.thialfihar.android.apg.provider.ApgContract.Keys; import org.thialfihar.android.apg.provider.ApgContract.Keys;
import org.thialfihar.android.apg.provider.ApgContract.UserIds; import org.thialfihar.android.apg.provider.ApgContract.UserIds;
@ -162,14 +163,19 @@ public class SelectPublicKeyFragment extends SherlockListFragment implements
KeyRings._ID, KeyRings._ID,
KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID,
UserIds.USER_ID, UserIds.USER_ID,
"(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Tables.KEYS + " AS tmp WHERE tmp." "(SELECT COUNT(available_keys." + Keys._ID + ") FROM " + Tables.KEYS
+ Keys.IS_REVOKED + " = '0' AND tmp." + Keys.CAN_ENCRYPT + " = '1') AS " + " AS available_keys WHERE available_keys." + Keys.KEY_RING_ROW_ID + " = "
+ ApgDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
+ " AND available_keys." + Keys.IS_REVOKED + " = '0' AND available_keys."
+ Keys.CAN_ENCRYPT + " = '1') AS "
+ SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE, + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
"(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Tables.KEYS + " AS tmp WHERE tmp." "(SELECT COUNT(valid_keys." + Keys._ID + ") FROM " + Tables.KEYS
+ Keys.IS_REVOKED + " = '0' AND " + Keys.CAN_ENCRYPT + " = '1' AND tmp." + " AS valid_keys WHERE valid_keys." + Keys.KEY_RING_ROW_ID + " = "
+ Keys.CREATION + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + ApgDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND valid_keys."
+ " IS NULL OR tmp." + Keys.EXPIRY + " >= '" + now + "')) AS " + Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_ENCRYPT
+ SelectKeyCursorAdapter.PROJECTION_ROW_VALID, }; + " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND "
+ "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY
+ " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
String inMasterKeyList = null; String inMasterKeyList = null;
if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) { if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) {

View File

@ -21,6 +21,7 @@ import java.util.Date;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.provider.ApgDatabase;
import org.thialfihar.android.apg.provider.ApgContract.KeyRings; import org.thialfihar.android.apg.provider.ApgContract.KeyRings;
import org.thialfihar.android.apg.provider.ApgContract.Keys; import org.thialfihar.android.apg.provider.ApgContract.Keys;
import org.thialfihar.android.apg.provider.ApgContract.UserIds; import org.thialfihar.android.apg.provider.ApgContract.UserIds;
@ -96,14 +97,19 @@ public class SelectSecretKeyFragment extends SherlockListFragment implements
KeyRings._ID, KeyRings._ID,
KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID,
UserIds.USER_ID, UserIds.USER_ID,
"(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Tables.KEYS + " AS tmp WHERE tmp." "(SELECT COUNT(available_keys." + Keys._ID + ") FROM " + Tables.KEYS
+ Keys.IS_REVOKED + " = '0' AND tmp." + Keys.CAN_SIGN + " = '1') AS " + " AS available_keys WHERE available_keys." + Keys.KEY_RING_ROW_ID + " = "
+ ApgDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
+ " AND available_keys." + Keys.IS_REVOKED + " = '0' AND available_keys."
+ Keys.CAN_SIGN + " = '1') AS "
+ SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE, + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
"(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Tables.KEYS + " AS tmp WHERE tmp." "(SELECT COUNT(valid_keys." + Keys._ID + ") FROM " + Tables.KEYS
+ Keys.IS_REVOKED + " = '0' AND " + Keys.CAN_SIGN + " = '1' AND tmp." + " AS valid_keys WHERE valid_keys." + Keys.KEY_RING_ROW_ID + " = "
+ Keys.CREATION + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + ApgDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND valid_keys."
+ " IS NULL OR tmp." + Keys.EXPIRY + " >= '" + now + "')) AS " + Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_SIGN
+ SelectKeyCursorAdapter.PROJECTION_ROW_VALID, }; + " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND "
+ "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY
+ " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
// if (searchString != null && searchString.trim().length() > 0) { // if (searchString != null && searchString.trim().length() > 0) {
// String[] chunks = searchString.trim().split(" +"); // String[] chunks = searchString.trim().split(" +");

View File

@ -140,15 +140,16 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
Vector<Choice> choices = new Vector<Choice>(); Vector<Choice> choices = new Vector<Choice>();
boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT); boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT);
boolean isDSAKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.DSA);
if (!isElGamalKey) { if (!isElGamalKey) {
choices.add(new Choice(Id.choice.usage.sign_only, getResources().getString( choices.add(new Choice(Id.choice.usage.sign_only, getResources().getString(
R.string.choice_signOnly))); R.string.choice_signOnly)));
} }
if (!mIsMasterKey) { if (!mIsMasterKey && !isDSAKey) {
choices.add(new Choice(Id.choice.usage.encrypt_only, getResources().getString( choices.add(new Choice(Id.choice.usage.encrypt_only, getResources().getString(
R.string.choice_encryptOnly))); R.string.choice_encryptOnly)));
} }
if (!isElGamalKey) { if (!isElGamalKey && !isDSAKey) {
choices.add(new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( choices.add(new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString(
R.string.choice_signAndEncrypt))); R.string.choice_signAndEncrypt)));
} }