introduce key signatures table

This commit is contained in:
Vincent Breitmoser 2017-09-22 04:18:14 +02:00
parent 2cd995526e
commit e23045aeb8
3 changed files with 83 additions and 3 deletions

View file

@ -58,6 +58,11 @@ public class KeychainContract {
String SEEN_ON_KEYSERVERS = "seen_on_keyservers";
}
interface KeySignaturesColumns {
String MASTER_KEY_ID = "master_key_id"; // not a database id
String SIGNER_KEY_ID = "signer_key_id";
}
interface UserPacketsColumns {
String MASTER_KEY_ID = "master_key_id"; // foreign key to key_rings._ID
String TYPE = "type"; // not a database id
@ -113,6 +118,8 @@ public class KeychainContract {
public static final String BASE_UPDATED_KEYS = "updated_keys";
public static final String BASE_KEY_SIGNATURES = "key_signatures";
public static final String PATH_UNIFIED = "unified";
public static final String PATH_FIND = "find";
@ -120,6 +127,9 @@ public class KeychainContract {
public static final String PATH_BY_SUBKEY = "subkey";
public static final String PATH_BY_USER_ID = "user_id";
public static final String PATH_FILTER = "filter";
public static final String PATH_BY_SIGNER = "signer";
public static final String PATH_PUBLIC = "public";
public static final String PATH_SECRET = "secret";
public static final String PATH_USER_IDS = "user_ids";
@ -198,6 +208,9 @@ public class KeychainContract {
.appendPath(PATH_BY_SUBKEY).appendPath(Long.toString(subkey)).build();
}
public static Uri buildUnifiedKeyRingsFilterBySigner() {
return CONTENT_URI.buildUpon().appendPath(PATH_FILTER).appendPath(PATH_BY_SIGNER).build();
}
}
public static class KeyRingData implements KeyRingsColumns, BaseColumns {
@ -271,6 +284,14 @@ public class KeychainContract {
= "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.provider.updated_keys";
}
public static class KeySignatures implements KeySignaturesColumns, BaseColumns {
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
.appendPath(BASE_KEY_SIGNATURES).build();
public static final String CONTENT_TYPE
= "vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.key_signatures";
}
public static class UserPackets implements UserPacketsColumns, BaseColumns {
public static final String VERIFIED = "verified";
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()

View file

@ -38,6 +38,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAutocryptPee
import org.sufficientlysecure.keychain.provider.KeychainContract.CertsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeySignaturesColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.OverriddenWarnings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPacketsColumns;
@ -54,7 +55,7 @@ import org.sufficientlysecure.keychain.util.Log;
*/
public class KeychainDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "openkeychain.db";
private static final int DATABASE_VERSION = 23;
private static final int DATABASE_VERSION = 24;
private Context mContext;
public interface Tables {
@ -62,6 +63,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
String KEY_RINGS_SECRET = "keyrings_secret";
String KEYS = "keys";
String UPDATED_KEYS = "updated_keys";
String KEY_SIGNATURES = "key_signatures";
String USER_PACKETS = "user_packets";
String CERTS = "certs";
String API_APPS = "api_apps";
@ -159,6 +161,15 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
+ ")";
private static final String CREATE_KEY_SIGNATURES =
"CREATE TABLE IF NOT EXISTS " + Tables.KEY_SIGNATURES + " ("
+ KeySignaturesColumns.MASTER_KEY_ID + " INTEGER NOT NULL, "
+ KeySignaturesColumns.SIGNER_KEY_ID + " INTEGER NOT NULL, "
+ "PRIMARY KEY(" + KeySignaturesColumns.MASTER_KEY_ID + ", " + KeySignaturesColumns.SIGNER_KEY_ID + "), "
+ "FOREIGN KEY(" + KeySignaturesColumns.MASTER_KEY_ID + ") REFERENCES "
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
+ ")";
private static final String CREATE_API_AUTOCRYPT_PEERS =
"CREATE TABLE IF NOT EXISTS " + Tables.API_AUTOCRYPT_PEERS + " ("
+ ApiAutocryptPeerColumns.PACKAGE_NAME + " TEXT NOT NULL, "
@ -213,6 +224,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
db.execSQL(CREATE_USER_PACKETS);
db.execSQL(CREATE_CERTS);
db.execSQL(CREATE_UPDATE_KEYS);
db.execSQL(CREATE_KEY_SIGNATURES);
db.execSQL(CREATE_API_APPS);
db.execSQL(CREATE_API_APPS_ALLOWED_KEYS);
db.execSQL(CREATE_OVERRIDDEN_WARNINGS);
@ -387,7 +399,16 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ "FOREIGN KEY(package_name) REFERENCES api_apps(package_name) ON DELETE CASCADE"
+ ")");
if (oldVersion == 18 || oldVersion == 19 || oldVersion == 20 || oldVersion == 21 || oldVersion == 22) {
case 23:
db.execSQL("CREATE TABLE IF NOT EXISTS key_signatures ("
+ "master_key_id INTEGER NOT NULL, "
+ "signer_key_id INTEGER NOT NULL, "
+ "PRIMARY KEY(master_key_id, signer_key_id), "
+ "FOREIGN KEY(master_key_id) REFERENCES keyrings_public(master_key_id) ON DELETE CASCADE"
+ ")");
if (oldVersion == 18 || oldVersion == 19 || oldVersion == 20 || oldVersion == 21 || oldVersion == 22 ||
oldVersion == 23) {
return;
}
}

View file

@ -46,6 +46,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAutocryptPee
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeySignatures;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
@ -77,6 +78,7 @@ public class KeychainProvider extends ContentProvider {
private static final int KEY_RINGS_FIND_BY_EMAIL = 400;
private static final int KEY_RINGS_FIND_BY_SUBKEY = 401;
private static final int KEY_RINGS_FIND_BY_USER_ID = 402;
private static final int KEY_RINGS_FILTER_BY_SIGNER = 403;
private static final int UPDATED_KEYS = 500;
private static final int UPDATED_KEYS_SPECIFIC = 501;
@ -85,6 +87,8 @@ public class KeychainProvider extends ContentProvider {
private static final int AUTOCRYPT_PEERS_BY_PACKAGE_NAME = 602;
private static final int AUTOCRYPT_PEERS_BY_PACKAGE_NAME_AND_TRUST_ID = 603;
private static final int KEY_SIGNATURES = 700;
protected UriMatcher mUriMatcher;
/**
@ -135,6 +139,9 @@ public class KeychainProvider extends ContentProvider {
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ KeychainContract.PATH_FIND + "/" + KeychainContract.PATH_BY_USER_ID + "/*",
KEY_RINGS_FIND_BY_USER_ID);
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ KeychainContract.PATH_FILTER + "/" + KeychainContract.PATH_BY_SIGNER,
KEY_RINGS_FILTER_BY_SIGNER);
/**
* list key_ring specifics
@ -219,6 +226,10 @@ public class KeychainProvider extends ContentProvider {
matcher.addURI(authority, KeychainContract.BASE_UPDATED_KEYS, UPDATED_KEYS);
matcher.addURI(authority, KeychainContract.BASE_UPDATED_KEYS + "/*", UPDATED_KEYS_SPECIFIC);
matcher.addURI(authority, KeychainContract.BASE_KEY_SIGNATURES, KEY_SIGNATURES);
return matcher;
}
@ -260,9 +271,13 @@ public class KeychainProvider extends ContentProvider {
case UPDATED_KEYS:
return UpdatedKeys.CONTENT_TYPE;
case UPDATED_KEYS_SPECIFIC:
return UpdatedKeys.CONTENT_ITEM_TYPE;
case KEY_SIGNATURES:
return KeySignatures.CONTENT_TYPE;
case API_APPS:
return ApiApps.CONTENT_TYPE;
@ -297,7 +312,8 @@ public class KeychainProvider extends ContentProvider {
case KEY_RINGS_UNIFIED:
case KEY_RINGS_FIND_BY_EMAIL:
case KEY_RINGS_FIND_BY_SUBKEY:
case KEY_RINGS_FIND_BY_USER_ID: {
case KEY_RINGS_FIND_BY_USER_ID:
case KEY_RINGS_FILTER_BY_SIGNER: {
HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(KeyRings._ID, Tables.KEYS + ".oid AS _id");
projectionMap.put(KeyRings.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
@ -446,6 +462,23 @@ public class KeychainProvider extends ContentProvider {
}
break;
}
case KEY_RINGS_FILTER_BY_SIGNER: {
StringBuilder signerKeyIds = new StringBuilder();
signerKeyIds.append(selectionArgs[0]);
for (int i = 1; i < selectionArgs.length; i++) {
signerKeyIds.append(',').append(selectionArgs[i]);
}
qb.appendWhere(" AND EXISTS (SELECT 1 FROM " + Tables.KEY_SIGNATURES + " WHERE " +
Tables.KEY_SIGNATURES + "." + KeySignatures.MASTER_KEY_ID + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID +
" AND " +
Tables.KEY_SIGNATURES + "." + KeySignatures.SIGNER_KEY_ID + " IN (" + signerKeyIds + ")" +
")");
selection = null;
selectionArgs = null;
break;
}
case KEY_RINGS_FIND_BY_EMAIL:
case KEY_RINGS_FIND_BY_USER_ID: {
String chunks[] = uri.getLastPathSegment().split(" *, *");
@ -860,6 +893,11 @@ public class KeychainProvider extends ContentProvider {
rowUri = UpdatedKeys.CONTENT_URI;
break;
}
case KEY_SIGNATURES: {
db.insert(Tables.KEY_SIGNATURES, null, values);
rowUri = KeySignatures.CONTENT_URI;
break;
}
case API_APPS: {
db.insertOrThrow(Tables.API_APPS, null, values);
break;