Merge pull request #2254 from hagau/export_pub_ssh_keys

Make predicate names in KeychainProvider consistent and allow export of SSH public keys without associated private key in keyring
This commit is contained in:
Dominik Schürmann 2018-01-22 12:44:13 +01:00 committed by GitHub
commit 8d01e40123
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 48 additions and 20 deletions

View file

@ -158,7 +158,7 @@ public class CachedPublicKeyRing extends KeyRing {
public boolean canCertify() throws PgpKeyNotFoundException { public boolean canCertify() throws PgpKeyNotFoundException {
try { try {
Object data = mKeyRepository.getGenericData(mUri, Object data = mKeyRepository.getGenericData(mUri,
KeychainContract.KeyRings.HAS_CERTIFY, KeychainContract.KeyRings.HAS_CERTIFY_SECRET,
KeyRepository.FIELD_TYPE_NULL); KeyRepository.FIELD_TYPE_NULL);
return !((Boolean) data); return !((Boolean) data);
} catch(KeyWritableRepository.NotFoundException e) { } catch(KeyWritableRepository.NotFoundException e) {
@ -192,7 +192,7 @@ public class CachedPublicKeyRing extends KeyRing {
public long getSecretSignId() throws PgpKeyNotFoundException { public long getSecretSignId() throws PgpKeyNotFoundException {
try { try {
Object data = mKeyRepository.getGenericData(mUri, Object data = mKeyRepository.getGenericData(mUri,
KeyRings.HAS_SIGN, KeyRings.HAS_SIGN_SECRET,
KeyRepository.FIELD_TYPE_INTEGER); KeyRepository.FIELD_TYPE_INTEGER);
return (Long) data; return (Long) data;
} catch(KeyWritableRepository.NotFoundException e) { } catch(KeyWritableRepository.NotFoundException e) {
@ -207,6 +207,21 @@ public class CachedPublicKeyRing extends KeyRing {
* *
*/ */
public long getSecretAuthenticationId() throws PgpKeyNotFoundException { public long getSecretAuthenticationId() throws PgpKeyNotFoundException {
try {
Object data = mKeyRepository.getGenericData(mUri,
KeyRings.HAS_AUTHENTICATE_SECRET,
KeyRepository.FIELD_TYPE_INTEGER);
return (Long) data;
} catch(KeyWritableRepository.NotFoundException e) {
throw new PgpKeyNotFoundException(e);
}
}
public boolean hasSecretAuthentication() throws PgpKeyNotFoundException {
return getSecretAuthenticationId() != 0;
}
public long getAuthenticationId() throws PgpKeyNotFoundException {
try { try {
Object data = mKeyRepository.getGenericData(mUri, Object data = mKeyRepository.getGenericData(mUri,
KeyRings.HAS_AUTHENTICATE, KeyRings.HAS_AUTHENTICATE,
@ -218,7 +233,7 @@ public class CachedPublicKeyRing extends KeyRing {
} }
public boolean hasAuthentication() throws PgpKeyNotFoundException { public boolean hasAuthentication() throws PgpKeyNotFoundException {
return getSecretAuthenticationId() != 0; return getAuthenticationId() != 0;
} }
@Override @Override

View file

@ -152,9 +152,10 @@ public class KeychainContract {
public static final String IS_EXPIRED = "is_expired"; public static final String IS_EXPIRED = "is_expired";
public static final String HAS_ANY_SECRET = "has_any_secret"; public static final String HAS_ANY_SECRET = "has_any_secret";
public static final String HAS_ENCRYPT = "has_encrypt"; public static final String HAS_ENCRYPT = "has_encrypt";
public static final String HAS_SIGN = "has_sign"; public static final String HAS_SIGN_SECRET = "has_sign_secret";
public static final String HAS_CERTIFY = "has_certify"; public static final String HAS_CERTIFY_SECRET = "has_certify_secret";
public static final String HAS_AUTHENTICATE = "has_authenticate"; public static final String HAS_AUTHENTICATE = "has_authenticate";
public static final String HAS_AUTHENTICATE_SECRET = "has_authenticate_secret";
public static final String HAS_DUPLICATE_USER_ID = "has_duplicate_user_id"; public static final String HAS_DUPLICATE_USER_ID = "has_duplicate_user_id";
public static final String API_KNOWN_TO_PACKAGE_NAMES = "known_to_apps"; public static final String API_KNOWN_TO_PACKAGE_NAMES = "known_to_apps";

View file

@ -354,12 +354,14 @@ public class KeychainProvider extends ContentProvider {
+ ")) AS " + KeyRings.HAS_ANY_SECRET); + ")) AS " + KeyRings.HAS_ANY_SECRET);
projectionMap.put(KeyRings.HAS_ENCRYPT, projectionMap.put(KeyRings.HAS_ENCRYPT,
"kE." + Keys.KEY_ID + " AS " + KeyRings.HAS_ENCRYPT); "kE." + Keys.KEY_ID + " AS " + KeyRings.HAS_ENCRYPT);
projectionMap.put(KeyRings.HAS_SIGN, projectionMap.put(KeyRings.HAS_SIGN_SECRET,
"kS." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN); "kS." + Keys.KEY_ID + " AS " + KeyRings.HAS_SIGN_SECRET);
projectionMap.put(KeyRings.HAS_AUTHENTICATE, projectionMap.put(KeyRings.HAS_AUTHENTICATE,
"kA." + Keys.KEY_ID + " AS " + KeyRings.HAS_AUTHENTICATE); "kA." + Keys.KEY_ID + " AS " + KeyRings.HAS_AUTHENTICATE);
projectionMap.put(KeyRings.HAS_CERTIFY, projectionMap.put(KeyRings.HAS_AUTHENTICATE_SECRET,
"kC." + Keys.KEY_ID + " AS " + KeyRings.HAS_CERTIFY); "kA." + Keys.KEY_ID + " AS " + KeyRings.HAS_AUTHENTICATE_SECRET);
projectionMap.put(KeyRings.HAS_CERTIFY_SECRET,
"kC." + Keys.KEY_ID + " AS " + KeyRings.HAS_CERTIFY_SECRET);
projectionMap.put(KeyRings.IS_EXPIRED, projectionMap.put(KeyRings.IS_EXPIRED,
"(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY "(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY
+ " < " + new Date().getTime() / 1000 + ") AS " + KeyRings.IS_EXPIRED); + " < " + new Date().getTime() / 1000 + ") AS " + KeyRings.IS_EXPIRED);
@ -401,7 +403,7 @@ public class KeychainProvider extends ContentProvider {
+ " AND ( kE." + Keys.EXPIRY + " IS NULL OR kE." + Keys.EXPIRY + " AND ( kE." + Keys.EXPIRY + " IS NULL OR kE." + Keys.EXPIRY
+ " >= " + new Date().getTime() / 1000 + " )" + " >= " + new Date().getTime() / 1000 + " )"
+ ")" : "") + ")" : "")
+ (plist.contains(KeyRings.HAS_SIGN) ? + (plist.contains(KeyRings.HAS_SIGN_SECRET) ?
" LEFT JOIN " + Tables.KEYS + " AS kS ON (" " LEFT JOIN " + Tables.KEYS + " AS kS ON ("
+"kS." + Keys.MASTER_KEY_ID +"kS." + Keys.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
@ -413,6 +415,16 @@ public class KeychainProvider extends ContentProvider {
+ " >= " + new Date().getTime() / 1000 + " )" + " >= " + new Date().getTime() / 1000 + " )"
+ ")" : "") + ")" : "")
+ (plist.contains(KeyRings.HAS_AUTHENTICATE) ? + (plist.contains(KeyRings.HAS_AUTHENTICATE) ?
" LEFT JOIN " + Tables.KEYS + " AS kA ON ("
+"kA." + Keys.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
+ " AND kA." + Keys.IS_REVOKED + " = 0"
+ " AND kA." + Keys.IS_SECURE + " = 1"
+ " AND kA." + Keys.CAN_AUTHENTICATE + " = 1"
+ " AND ( kA." + Keys.EXPIRY + " IS NULL OR kA." + Keys.EXPIRY
+ " >= " + new Date().getTime() / 1000 + " )"
+ ")" : "")
+ (plist.contains(KeyRings.HAS_AUTHENTICATE_SECRET) ?
" LEFT JOIN " + Tables.KEYS + " AS kA ON (" " LEFT JOIN " + Tables.KEYS + " AS kA ON ("
+"kA." + Keys.MASTER_KEY_ID +"kA." + Keys.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
@ -423,7 +435,7 @@ public class KeychainProvider extends ContentProvider {
+ " AND ( kA." + Keys.EXPIRY + " IS NULL OR kA." + Keys.EXPIRY + " AND ( kA." + Keys.EXPIRY + " IS NULL OR kA." + Keys.EXPIRY
+ " >= " + new Date().getTime() / 1000 + " )" + " >= " + new Date().getTime() / 1000 + " )"
+ ")" : "") + ")" : "")
+ (plist.contains(KeyRings.HAS_CERTIFY) ? + (plist.contains(KeyRings.HAS_CERTIFY_SECRET) ?
" LEFT JOIN " + Tables.KEYS + " AS kC ON (" " LEFT JOIN " + Tables.KEYS + " AS kC ON ("
+"kC." + Keys.MASTER_KEY_ID +"kC." + Keys.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID

View file

@ -364,7 +364,7 @@ public class SshAuthenticationService extends Service {
throws PgpKeyNotFoundException, KeyRepository.NotFoundException { throws PgpKeyNotFoundException, KeyRepository.NotFoundException {
KeyRepository keyRepository = KeyRepository.create(getApplicationContext()); KeyRepository keyRepository = KeyRepository.create(getApplicationContext());
long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId) long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId)
.getSecretAuthenticationId(); .getAuthenticationId();
return keyRepository.getCanonicalizedPublicKeyRing(masterKeyId) return keyRepository.getCanonicalizedPublicKeyRing(masterKeyId)
.getPublicKey(authSubKeyId); .getPublicKey(authSubKeyId);
} }

View file

@ -42,7 +42,7 @@ public class KeyLoader extends AsyncTaskLoader<List<KeyInfo>> {
KeyRings.MASTER_KEY_ID, KeyRings.MASTER_KEY_ID,
KeyRings.CREATION, KeyRings.CREATION,
KeyRings.HAS_ENCRYPT, KeyRings.HAS_ENCRYPT,
KeyRings.HAS_AUTHENTICATE, KeyRings.HAS_AUTHENTICATE_SECRET,
KeyRings.HAS_ANY_SECRET, KeyRings.HAS_ANY_SECRET,
KeyRings.VERIFIED, KeyRings.VERIFIED,
KeyRings.NAME, KeyRings.NAME,

View file

@ -81,7 +81,7 @@ class RemoteSelectAuthenticationKeyPresenter implements LoaderCallbacks<List<Key
@Override @Override
public Loader<List<KeyInfo>> onCreateLoader(int id, Bundle args) { public Loader<List<KeyInfo>> onCreateLoader(int id, Bundle args) {
String selection = KeyRings.HAS_ANY_SECRET + " != 0 AND " + KeyRings.HAS_AUTHENTICATE + " != 0"; String selection = KeyRings.HAS_AUTHENTICATE_SECRET + " != 0";
KeySelector keySelector = KeySelector.create( KeySelector keySelector = KeySelector.create(
KeyRings.buildUnifiedKeyRingsUri(), selection); KeyRings.buildUnifiedKeyRingsUri(), selection);
return new KeyLoader(context, context.getContentResolver(), keySelector); return new KeyLoader(context, context.getContentResolver(), keySelector);

View file

@ -216,7 +216,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
try { try {
masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId(); masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId();
CachedPublicKeyRing cachedPublicKeyRing = keyRepository.getCachedPublicKeyRing(masterKeyId); CachedPublicKeyRing cachedPublicKeyRing = keyRepository.getCachedPublicKeyRing(masterKeyId);
authSubKeyId = cachedPublicKeyRing.getSecretAuthenticationId(); authSubKeyId = cachedPublicKeyRing.getAuthenticationId();
} catch (PgpKeyNotFoundException e) { } catch (PgpKeyNotFoundException e) {
Timber.e(e, "key not found!"); Timber.e(e, "key not found!");
} }
@ -232,7 +232,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
String content; String content;
long masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId(); long masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId();
if (asSshKey) { if (asSshKey) {
long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId(); long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getAuthenticationId();
CanonicalizedPublicKey publicKey = keyRepository.getCanonicalizedPublicKeyRing(masterKeyId) CanonicalizedPublicKey publicKey = keyRepository.getCanonicalizedPublicKeyRing(masterKeyId)
.getPublicKey(authSubKeyId); .getPublicKey(authSubKeyId);
SshPublicKey sshPublicKey = new SshPublicKey(publicKey); SshPublicKey sshPublicKey = new SshPublicKey(publicKey);

View file

@ -60,7 +60,7 @@ public class CertifyKeySpinner extends KeySpinner {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri();
String[] projection = KeyAdapter.getProjectionWith(new String[] { String[] projection = KeyAdapter.getProjectionWith(new String[] {
KeychainContract.KeyRings.HAS_CERTIFY, KeychainContract.KeyRings.HAS_CERTIFY_SECRET,
}); });
String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1 AND " String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1 AND "
@ -79,7 +79,7 @@ public class CertifyKeySpinner extends KeySpinner {
super.onLoadFinished(loader, data); super.onLoadFinished(loader, data);
if (loader.getId() == LOADER_ID) { if (loader.getId() == LOADER_ID) {
mIndexHasCertify = data.getColumnIndex(KeychainContract.KeyRings.HAS_CERTIFY); mIndexHasCertify = data.getColumnIndex(KeychainContract.KeyRings.HAS_CERTIFY_SECRET);
// If: // If:
// - no key has been pre-selected (e.g. by SageSlinger) // - no key has been pre-selected (e.g. by SageSlinger)

View file

@ -49,7 +49,7 @@ public class SignKeySpinner extends KeySpinner {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri(); Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsUri();
String[] projection = KeyAdapter.getProjectionWith(new String[] { String[] projection = KeyAdapter.getProjectionWith(new String[] {
KeychainContract.KeyRings.HAS_SIGN, KeychainContract.KeyRings.HAS_SIGN_SECRET,
}); });
String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1"; String where = KeychainContract.KeyRings.HAS_ANY_SECRET + " = 1";
@ -66,7 +66,7 @@ public class SignKeySpinner extends KeySpinner {
super.onLoadFinished(loader, data); super.onLoadFinished(loader, data);
if (loader.getId() == LOADER_ID) { if (loader.getId() == LOADER_ID) {
mIndexHasSign = data.getColumnIndex(KeychainContract.KeyRings.HAS_SIGN); mIndexHasSign = data.getColumnIndex(KeychainContract.KeyRings.HAS_SIGN_SECRET);
} }
} }