add trust-id info in external query

This commit is contained in:
Vincent Breitmoser
2017-06-13 18:16:22 +02:00
parent 0edbe9f1b2
commit 4e4912bd6d
4 changed files with 69 additions and 15 deletions

View File

@@ -166,8 +166,6 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ ApiTrustIdentityColumns.MASTER_KEY_ID + " INTEGER NOT NULL, "
+ "PRIMARY KEY(" + ApiTrustIdentityColumns.PACKAGE_NAME + ", "
+ ApiTrustIdentityColumns.IDENTIFIER + "), "
+ "FOREIGN KEY(" + ApiTrustIdentityColumns.MASTER_KEY_ID + ") REFERENCES "
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE, "
+ "FOREIGN KEY(" + ApiTrustIdentityColumns.PACKAGE_NAME + ") REFERENCES "
+ Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE"
+ ")";

View File

@@ -44,6 +44,7 @@ public class KeychainExternalContract {
public static final String USER_ID_STATUS = "email_status";
public static final String MASTER_KEY_ID = "master_key_id";
public static final String TRUST_ID_LAST_UPDATE = "trust_id_last_update";
public static final String TRUST_ID_STATUS = "trust_id_status";
public static final Uri CONTENT_URI = BASE_CONTENT_URI_EXTERNAL.buildUpon()
.appendPath(BASE_EMAIL_STATUS).build();

View File

@@ -174,12 +174,18 @@ public class KeychainExternalProvider extends ContentProvider implements SimpleC
projectionMap.put(EmailStatus.USER_ID,
Tables.USER_PACKETS + "." + UserPackets.USER_ID + " AS " + EmailStatus.USER_ID);
// we take the minimum (>0) here, where "1" is "verified by known secret key", "2" is "self-certified"
projectionMap.put(EmailStatus.USER_ID_STATUS, "CASE ( MIN (" + Certs.VERIFIED + " ) ) "
projectionMap.put(EmailStatus.USER_ID_STATUS, "CASE ( MIN (certs_user_id." + Certs.VERIFIED + " ) ) "
// remap to keep this provider contract independent from our internal representation
+ " WHEN " + Certs.VERIFIED_SELF + " THEN " + KeychainExternalContract.KEY_STATUS_UNVERIFIED
+ " WHEN " + Certs.VERIFIED_SECRET + " THEN " + KeychainExternalContract.KEY_STATUS_VERIFIED
+ " WHEN NULL THEN " + KeychainExternalContract.KEY_STATUS_UNVERIFIED
+ " WHEN NULL THEN NULL"
+ " END AS " + EmailStatus.USER_ID_STATUS);
projectionMap.put(EmailStatus.TRUST_ID_STATUS, "CASE ( MIN (certs_trust_id." + Certs.VERIFIED + " ) ) "
// remap to keep this provider contract independent from our internal representation
+ " WHEN " + Certs.VERIFIED_SELF + " THEN " + KeychainExternalContract.KEY_STATUS_UNVERIFIED
+ " WHEN " + Certs.VERIFIED_SECRET + " THEN " + KeychainExternalContract.KEY_STATUS_VERIFIED
+ " WHEN NULL THEN NULL"
+ " END AS " + EmailStatus.TRUST_ID_STATUS);
projectionMap.put(EmailStatus.MASTER_KEY_ID,
Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " AS " + EmailStatus.MASTER_KEY_ID);
projectionMap.put(EmailStatus.USER_ID,
@@ -198,28 +204,25 @@ public class KeychainExternalProvider extends ContentProvider implements SimpleC
+ Tables.USER_PACKETS + "." + UserPackets.USER_ID + " IS NOT NULL"
+ " AND " + Tables.USER_PACKETS + "." + UserPackets.EMAIL + " LIKE " + TEMP_TABLE_QUERIED_ADDRESSES + "." + TEMP_TABLE_COLUMN_ADDRES
+ ")"
+ " LEFT JOIN " + Tables.CERTS + " AS certs_user_id ON ("
+ Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = certs_user_id." + Certs.MASTER_KEY_ID
+ " AND " + Tables.USER_PACKETS + "." + UserPackets.RANK + " = certs_user_id." + Certs.RANK
+ ")"
+ " LEFT JOIN " + Tables.API_TRUST_IDENTITIES + " ON ("
+ Tables.API_TRUST_IDENTITIES + "." + ApiTrustIdentity.IDENTIFIER + " LIKE queried_addresses.address"
+ " AND " + Tables.API_TRUST_IDENTITIES + "." + ApiTrustIdentity.PACKAGE_NAME + " = \"" + callingPackageName + "\""
+ ")"
+ " JOIN " + Tables.CERTS + " ON ("
+ "(" + Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = " + Tables.CERTS + "." + Certs.MASTER_KEY_ID
+ " AND " + Tables.USER_PACKETS + "." + UserPackets.RANK + " = " + Tables.CERTS + "." + Certs.RANK + ")"
+ " OR " + Tables.API_TRUST_IDENTITIES + "." + ApiTrustIdentity.MASTER_KEY_ID + " = " + Tables.CERTS + "." + Certs.MASTER_KEY_ID
+ " LEFT JOIN " + Tables.CERTS + " AS certs_trust_id ON ("
+ Tables.API_TRUST_IDENTITIES + "." + ApiTrustIdentity.MASTER_KEY_ID + " = certs_trust_id." + Certs.MASTER_KEY_ID
+ ")"
);
// in case there are multiple verifying certificates
groupBy = TEMP_TABLE_QUERIED_ADDRESSES + "." + TEMP_TABLE_COLUMN_ADDRES
+ ", " + Tables.CERTS + "." + UserPackets.MASTER_KEY_ID;
groupBy = TEMP_TABLE_QUERIED_ADDRESSES + "." + TEMP_TABLE_COLUMN_ADDRES;
List<String> plist = Arrays.asList(projection);
if (plist.contains(EmailStatus.USER_ID)) {
groupBy += ", " + Tables.USER_PACKETS + "." + UserPackets.USER_ID;
}
// verified == 0 has no self-cert, which is basically an error case. never return that!
// verified == null is fine, because it means there was no join partner
qb.appendWhere(Tables.CERTS + "." + Certs.VERIFIED + " IS NULL OR " + Tables.CERTS + "." + Certs.VERIFIED + " > 0");
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = EmailStatus.EMAIL_ADDRESS;
}

View File

@@ -3,6 +3,7 @@ package org.sufficientlysecure.keychain.remote;
import java.security.AccessControlException;
import java.util.Collections;
import java.util.Date;
import android.content.ContentResolver;
import android.content.pm.PackageInfo;
@@ -23,6 +24,7 @@ import org.sufficientlysecure.keychain.provider.ApiDataAccessObject;
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
import org.sufficientlysecure.keychain.provider.KeychainExternalContract.EmailStatus;
import org.sufficientlysecure.keychain.provider.KeyRepositorySaveTest;
import org.sufficientlysecure.keychain.provider.TrustIdentityDataAccessObject;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
@@ -43,6 +45,7 @@ public class KeychainExternalProviderTest {
static final String USER_ID_SEC_1 = "twi <twi-sec@openkeychain.org>";
static final long KEY_ID_SECRET = 0x5D4DA4423C39122FL;
static final long KEY_ID_PUBLIC = 0x9A282CE2AB44A382L;
public static final String TRUST_ID = "tid";
KeyWritableRepository databaseInteractor =
@@ -50,6 +53,7 @@ public class KeychainExternalProviderTest {
ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver();
ApiPermissionHelper apiPermissionHelper;
ApiDataAccessObject apiDao;
private TrustIdentityDataAccessObject trustIdDao;
@Before
@@ -63,6 +67,7 @@ public class KeychainExternalProviderTest {
apiDao = new ApiDataAccessObject(RuntimeEnvironment.application);
apiPermissionHelper = new ApiPermissionHelper(RuntimeEnvironment.application, apiDao);
trustIdDao = new TrustIdentityDataAccessObject(RuntimeEnvironment.application, PACKAGE_NAME);
apiDao.insertApiApp(new AppSettings(PACKAGE_NAME, PACKAGE_SIGNATURE));
}
@@ -173,7 +178,54 @@ public class KeychainExternalProviderTest {
}
@Test
public void testQuery__withConfirmedKey() throws Exception {
public void testQuery__trustId__withUnconfirmedKey() throws Exception {
insertSecretKeyringFrom("/test-keys/testring.sec");
insertPublicKeyringFrom("/test-keys/testring.pub");
trustIdDao.setMasterKeyIdForTrustId("tid", KEY_ID_PUBLIC, new Date());
Cursor cursor = contentResolver.query(
EmailStatus.CONTENT_URI, new String[] {
EmailStatus.EMAIL_ADDRESS, EmailStatus.USER_ID_STATUS, EmailStatus.USER_ID,
EmailStatus.TRUST_ID_STATUS },
null, new String [] { TRUST_ID }, null
);
assertNotNull(cursor);
assertTrue(cursor.moveToFirst());
assertEquals("tid", cursor.getString(0));
assertEquals(null, cursor.getString(2));
assertEquals(0, cursor.getInt(1));
assertEquals(1, cursor.getInt(3));
assertFalse(cursor.moveToNext());
}
@Test
public void testQuery__trustId__withConfirmedKey() throws Exception {
insertSecretKeyringFrom("/test-keys/testring.sec");
insertPublicKeyringFrom("/test-keys/testring.pub");
trustIdDao.setMasterKeyIdForTrustId("tid", KEY_ID_PUBLIC, new Date());
certifyKey(KEY_ID_SECRET, KEY_ID_PUBLIC, USER_ID_1);
Cursor cursor = contentResolver.query(
EmailStatus.CONTENT_URI, new String[] {
EmailStatus.EMAIL_ADDRESS, EmailStatus.USER_ID_STATUS, EmailStatus.USER_ID,
EmailStatus.TRUST_ID_STATUS },
null, new String [] { TRUST_ID }, null
);
assertNotNull(cursor);
assertTrue(cursor.moveToFirst());
assertEquals("tid", cursor.getString(0));
assertEquals(null, cursor.getString(2));
assertEquals(0, cursor.getInt(1));
assertEquals(2, cursor.getInt(3));
assertFalse(cursor.moveToNext());
}
@Test
public void testQuery__withTrustId() throws Exception {
insertSecretKeyringFrom("/test-keys/testring.sec");
insertPublicKeyringFrom("/test-keys/testring.pub");