extract subkey loading from KeychainProvider

This commit is contained in:
Vincent Breitmoser
2018-06-22 19:23:00 +02:00
parent 500c219fa0
commit 6cd065a3bd
17 changed files with 248 additions and 421 deletions

View File

@@ -25,7 +25,6 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeyRepository.NotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import timber.log.Timber;
@@ -227,10 +226,6 @@ public class CachedPublicKeyRing extends KeyRing {
}
}
public boolean hasSecretAuthentication() throws PgpKeyNotFoundException {
return getSecretAuthenticationId() != 0;
}
public long getAuthenticationId() throws PgpKeyNotFoundException {
try {
Object data = mKeyRepository.getGenericData(mUri,
@@ -242,10 +237,6 @@ public class CachedPublicKeyRing extends KeyRing {
}
}
public boolean hasAuthentication() throws PgpKeyNotFoundException {
return getAuthenticationId() != 0;
}
@Override
public int getVerified() throws PgpKeyNotFoundException {
try {
@@ -270,11 +261,11 @@ public class CachedPublicKeyRing extends KeyRing {
}
public SecretKeyType getSecretKeyType(long keyId) throws NotFoundException {
Object data = mKeyRepository.getGenericData(Keys.buildKeysUri(mUri),
KeyRings.HAS_SECRET,
KeyRepository.FIELD_TYPE_INTEGER,
KeyRings.KEY_ID + " = " + Long.toString(keyId));
return SecretKeyType.fromNum(((Long) data).intValue());
SecretKeyType secretKeyType = mKeyRepository.getSecretKeyType(keyId);
if (secretKeyType == null) {
throw new NotFoundException();
}
return secretKeyType;
}
public byte[] getEncoded() throws PgpKeyNotFoundException {

View File

@@ -32,11 +32,13 @@ import android.net.Uri;
import com.squareup.sqldelight.SqlDelightQuery;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.sufficientlysecure.keychain.model.KeyRingPublic;
import org.sufficientlysecure.keychain.model.SubKey;
import org.sufficientlysecure.keychain.model.UserPacket;
import org.sufficientlysecure.keychain.model.UserPacket.UserId;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
@@ -119,11 +121,6 @@ public class KeyRepository extends AbstractDao {
return result;
}
Object getGenericData(Uri uri, String column, int type, String selection)
throws NotFoundException {
return getGenericData(uri, new String[]{column}, new int[]{type}, selection).get(column);
}
private HashMap<String, Object> getGenericData(Uri uri, String[] proj, int[] types)
throws NotFoundException {
return getGenericData(uri, proj, types, null);
@@ -246,7 +243,7 @@ public class KeyRepository extends AbstractDao {
return mapAllRows(query, UserPacket.USER_ID_MAPPER::map);
}
public ArrayList<String> getConfirmedUserIds(long masterKeyId) {
public List<String> getConfirmedUserIds(long masterKeyId) {
ArrayList<String> userIds = new ArrayList<>();
SqlDelightQuery query =
UserPacket.FACTORY.selectUserIdsByMasterKeyIdAndVerification(masterKeyId, Certs.VERIFIED_SECRET);
@@ -256,6 +253,21 @@ public class KeyRepository extends AbstractDao {
return userIds;
}
public List<SubKey> getSubKeysByMasterKeyId(long masterKeyId) {
SqlDelightQuery query = SubKey.FACTORY.selectSubkeysByMasterKeyId(masterKeyId);
return mapAllRows(query, SubKey.SUBKEY_MAPPER::map);
}
public SecretKeyType getSecretKeyType(long keyId) {
SqlDelightQuery query = SubKey.FACTORY.selectSecretKeyType(keyId);
try (Cursor cursor = getReadableDb().query(query)) {
if (cursor.moveToFirst()) {
return SubKey.SKT_MAPPER.map(cursor);
}
return null;
}
}
private byte[] getKeyRingAsArmoredData(byte[] data) throws IOException, PgpGeneralException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ArmoredOutputStream aos = new ArmoredOutputStream(bos);

View File

@@ -130,11 +130,6 @@ public class KeychainContract {
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
.appendPath(BASE_KEY_RINGS).build();
public static final String CONTENT_TYPE
= "vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.key_rings";
public static final String CONTENT_ITEM_TYPE
= "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.provider.key_rings";
public static Uri buildUnifiedKeyRingsUri() {
return CONTENT_URI.buildUpon().appendPath(PATH_UNIFIED).build();
}
@@ -194,34 +189,15 @@ public class KeychainContract {
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
.appendPath(BASE_KEY_RINGS).build();
/**
* Use if multiple items get returned
*/
public static final String CONTENT_TYPE
= "vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.keychain.keys";
/**
* Use if a single item is returned
*/
public static final String CONTENT_ITEM_TYPE
= "vnd.android.cursor.item/vnd.org.sufficientlysecure.keychain.provider.keychain.keys";
public static Uri buildKeysUri(long masterKeyId) {
return CONTENT_URI.buildUpon().appendPath(Long.toString(masterKeyId)).appendPath(PATH_KEYS).build();
}
public static Uri buildKeysUri(Uri uri) {
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_KEYS).build();
}
}
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 {
@@ -235,11 +211,6 @@ public class KeychainContract {
}
public static class Certs implements CertsColumns, BaseColumns {
public static final String USER_ID = UserPacketsColumns.USER_ID;
public static final String NAME = UserPacketsColumns.NAME;
public static final String EMAIL = UserPacketsColumns.EMAIL;
public static final String COMMENT = UserPacketsColumns.COMMENT;
public static final int UNVERIFIED = 0;
public static final int VERIFIED_SECRET = 1;
public static final int VERIFIED_SELF = 2;

View File

@@ -168,17 +168,7 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
*/
@Override
public String getType(@NonNull Uri uri) {
final int match = mUriMatcher.match(uri);
switch (match) {
case KEY_RING_KEYS:
return Keys.CONTENT_TYPE;
case KEY_SIGNATURES:
return KeySignatures.CONTENT_TYPE;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
throw new UnsupportedOperationException();
}
/**
@@ -194,7 +184,7 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
int match = mUriMatcher.match(uri);
// all query() parameters, for good measure
String groupBy = null, having = null;
String groupBy;
switch (match) {
case KEY_RING_UNIFIED:
@@ -431,34 +421,6 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
break;
}
case KEY_RING_KEYS: {
HashMap<String, String> projectionMap = new HashMap<>();
projectionMap.put(Keys._ID, Tables.KEYS + ".oid AS _id");
projectionMap.put(Keys.MASTER_KEY_ID, Tables.KEYS + "." + Keys.MASTER_KEY_ID);
projectionMap.put(Keys.RANK, Tables.KEYS + "." + Keys.RANK);
projectionMap.put(Keys.KEY_ID, Keys.KEY_ID);
projectionMap.put(Keys.KEY_SIZE, Keys.KEY_SIZE);
projectionMap.put(Keys.KEY_CURVE_OID, Keys.KEY_CURVE_OID);
projectionMap.put(Keys.IS_REVOKED, Tables.KEYS + "." + Keys.IS_REVOKED);
projectionMap.put(Keys.IS_SECURE, Tables.KEYS + "." + Keys.IS_SECURE);
projectionMap.put(Keys.CAN_CERTIFY, Keys.CAN_CERTIFY);
projectionMap.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT);
projectionMap.put(Keys.CAN_SIGN, Keys.CAN_SIGN);
projectionMap.put(Keys.CAN_AUTHENTICATE, Keys.CAN_AUTHENTICATE);
projectionMap.put(Keys.HAS_SECRET, Keys.HAS_SECRET);
projectionMap.put(Keys.CREATION, Keys.CREATION);
projectionMap.put(Keys.EXPIRY, Keys.EXPIRY);
projectionMap.put(Keys.ALGORITHM, Keys.ALGORITHM);
projectionMap.put(Keys.FINGERPRINT, Keys.FINGERPRINT);
qb.setProjectionMap(projectionMap);
qb.setTables(Tables.KEYS);
qb.appendWhere(Keys.MASTER_KEY_ID + " = ");
qb.appendWhereEscapeString(uri.getPathSegments().get(1));
break;
}
default: {
throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")");
}
@@ -489,7 +451,7 @@ public class KeychainProvider extends ContentProvider implements SimpleContentRe
}
if (Constants.DEBUG && Constants.DEBUG_EXPLAIN_QUERIES) {
String rawQuery = qb.buildQuery(projection, selection, groupBy, having, orderBy, null);
String rawQuery = qb.buildQuery(projection, selection, groupBy, null, orderBy, null);
DatabaseUtil.explainQuery(db, rawQuery);
}