mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
Break a lot of stuff. Also, database redesign.
Change entire database design. This introduces a lot of changes, notably all URIs and almost all projections. Some features (like key deletion) have been simply commented out for now since they need serious reconsideration. There are a couple of new TODOs marking places where more work is needed. The migration path works fine from what I tested. The old database is not deleted for now, ie, it is reimported at every start of the application making all intermediate changes transient. Tested and working (for me): - All activities in the main drawer - Multiselect and Search - ViewKeyActivity, with and without secret key available - CertifyKeyActivity - SelectSecretKeyActivity (from CertifyKeyActivity) - SelectPublicKeyActivity (from encrypt activity) What doesn't work: - Actually certifying keys (pending a TODO in ProviderHelper) - Importing keys doesn't preserve secret keys - "Encrypt to this contact" doesn't pass key - Editing keys. All controls are disabled, I'm not sure why... (is this even my fault?) - Deleting keys What I didn't test: - Key export - API stuff - Creating keys (since editing doesn't even work)
This commit is contained in:
parent
acc2e208cf
commit
a7eff41ced
@ -239,7 +239,7 @@ public class PgpDecryptVerify {
|
|||||||
if (mEnforcedKeyId != 0) {
|
if (mEnforcedKeyId != 0) {
|
||||||
// TODO: improve this code! get master key directly!
|
// TODO: improve this code! get master key directly!
|
||||||
PGPSecretKeyRing secretKeyRing =
|
PGPSecretKeyRing secretKeyRing =
|
||||||
ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, encData.getKeyID());
|
ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, encData.getKeyID());
|
||||||
long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID();
|
long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID();
|
||||||
Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
|
Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
|
||||||
Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId);
|
Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId);
|
||||||
@ -371,7 +371,7 @@ public class PgpDecryptVerify {
|
|||||||
signatureIndex = i;
|
signatureIndex = i;
|
||||||
signatureKeyId = signature.getKeyID();
|
signatureKeyId = signature.getKeyID();
|
||||||
String userId = null;
|
String userId = null;
|
||||||
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(
|
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(
|
||||||
mContext, signatureKeyId);
|
mContext, signatureKeyId);
|
||||||
if (signKeyRing != null) {
|
if (signKeyRing != null) {
|
||||||
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
||||||
@ -555,7 +555,7 @@ public class PgpDecryptVerify {
|
|||||||
} else {
|
} else {
|
||||||
signatureKeyId = signature.getKeyID();
|
signatureKeyId = signature.getKeyID();
|
||||||
String userId = null;
|
String userId = null;
|
||||||
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext,
|
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(mContext,
|
||||||
signatureKeyId);
|
signatureKeyId);
|
||||||
if (signKeyRing != null) {
|
if (signKeyRing != null) {
|
||||||
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
|
||||||
@ -619,7 +619,7 @@ public class PgpDecryptVerify {
|
|||||||
long signatureKeyId = signature.getKeyID();
|
long signatureKeyId = signature.getKeyID();
|
||||||
boolean validKeyBinding = false;
|
boolean validKeyBinding = false;
|
||||||
|
|
||||||
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context,
|
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(context,
|
||||||
signatureKeyId);
|
signatureKeyId);
|
||||||
PGPPublicKey mKey = null;
|
PGPPublicKey mKey = null;
|
||||||
if (signKeyRing != null) {
|
if (signKeyRing != null) {
|
||||||
|
@ -97,7 +97,7 @@ public class PgpHelper {
|
|||||||
if (obj instanceof PGPPublicKeyEncryptedData) {
|
if (obj instanceof PGPPublicKeyEncryptedData) {
|
||||||
gotAsymmetricEncryption = true;
|
gotAsymmetricEncryption = true;
|
||||||
PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
|
PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) obj;
|
||||||
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, pbe.getKeyID());
|
secretKey = ProviderHelper.getPGPSecretKeyRing(context, pbe.getKeyID()).getSecretKey();
|
||||||
if (secretKey != null) {
|
if (secretKey != null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ public class PgpImportExport {
|
|||||||
|
|
||||||
updateProgress(progress * 100 / masterKeyIdsSize, 100);
|
updateProgress(progress * 100 / masterKeyIdsSize, 100);
|
||||||
PGPPublicKeyRing publicKeyRing =
|
PGPPublicKeyRing publicKeyRing =
|
||||||
ProviderHelper.getPGPPublicKeyRingByMasterKeyId(mContext, pubKeyMasterId);
|
ProviderHelper.getPGPPublicKeyRing(mContext, pubKeyMasterId);
|
||||||
|
|
||||||
if (publicKeyRing != null) {
|
if (publicKeyRing != null) {
|
||||||
publicKeyRing.encode(arOutStream);
|
publicKeyRing.encode(arOutStream);
|
||||||
@ -207,7 +207,7 @@ public class PgpImportExport {
|
|||||||
|
|
||||||
updateProgress(progress * 100 / masterKeyIdsSize, 100);
|
updateProgress(progress * 100 / masterKeyIdsSize, 100);
|
||||||
PGPSecretKeyRing secretKeyRing =
|
PGPSecretKeyRing secretKeyRing =
|
||||||
ProviderHelper.getPGPSecretKeyRingByMasterKeyId(mContext, secretKeyMasterId);
|
ProviderHelper.getPGPSecretKeyRing(mContext, secretKeyMasterId);
|
||||||
|
|
||||||
if (secretKeyRing != null) {
|
if (secretKeyRing != null) {
|
||||||
secretKeyRing.encode(arOutStream);
|
secretKeyRing.encode(arOutStream);
|
||||||
|
@ -219,8 +219,7 @@ public class PgpKeyHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) {
|
public static PGPPublicKey getEncryptPublicKey(Context context, long masterKeyId) {
|
||||||
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(context,
|
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId);
|
||||||
masterKeyId);
|
|
||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
Log.e(Constants.TAG, "keyRing is null!");
|
Log.e(Constants.TAG, "keyRing is null!");
|
||||||
return null;
|
return null;
|
||||||
@ -234,8 +233,7 @@ public class PgpKeyHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PGPSecretKey getCertificationKey(Context context, long masterKeyId) {
|
public static PGPSecretKey getCertificationKey(Context context, long masterKeyId) {
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context,
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
|
||||||
masterKeyId);
|
|
||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -247,8 +245,7 @@ public class PgpKeyHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PGPSecretKey getSigningKey(Context context, long masterKeyId) {
|
public static PGPSecretKey getSigningKey(Context context, long masterKeyId) {
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(context,
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
|
||||||
masterKeyId);
|
|
||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -491,21 +488,6 @@ public class PgpKeyHelper {
|
|||||||
return algorithmStr + ", " + keySize + " bit";
|
return algorithmStr + ", " + keySize + " bit";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFingerPrint(Context context, long keyId) {
|
|
||||||
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, keyId);
|
|
||||||
// if it is no public key get it from your own keys...
|
|
||||||
if (key == null) {
|
|
||||||
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
|
||||||
if (secretKey == null) {
|
|
||||||
Log.e(Constants.TAG, "Key could not be found!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
key = secretKey.getPublicKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertFingerprintToHex(key.getFingerprint());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts fingerprint to hex (optional: with whitespaces after 4 characters)
|
* Converts fingerprint to hex (optional: with whitespaces after 4 characters)
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -513,7 +495,6 @@ public class PgpKeyHelper {
|
|||||||
* better differentiate between numbers and letters when letters are lowercase.
|
* better differentiate between numbers and letters when letters are lowercase.
|
||||||
*
|
*
|
||||||
* @param fingerprint
|
* @param fingerprint
|
||||||
* @param split split into 4 character chunks
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String convertFingerprintToHex(byte[] fingerprint) {
|
public static String convertFingerprintToHex(byte[] fingerprint) {
|
||||||
|
@ -214,7 +214,7 @@ public class PgpSignEncrypt {
|
|||||||
PGPSecretKeyRing signingKeyRing = null;
|
PGPSecretKeyRing signingKeyRing = null;
|
||||||
PGPPrivateKey signaturePrivateKey = null;
|
PGPPrivateKey signaturePrivateKey = null;
|
||||||
if (enableSignature) {
|
if (enableSignature) {
|
||||||
signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId);
|
signingKeyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, mSignatureKeyId);
|
||||||
signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
|
signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
|
||||||
if (signingKey == null) {
|
if (signingKey == null) {
|
||||||
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
|
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
|
||||||
@ -444,7 +444,7 @@ public class PgpSignEncrypt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PGPSecretKeyRing signingKeyRing =
|
PGPSecretKeyRing signingKeyRing =
|
||||||
ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId);
|
ProviderHelper.getPGPSecretKeyRingWithKeyId(mContext, mSignatureKeyId);
|
||||||
PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
|
PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
|
||||||
if (signingKey == null) {
|
if (signingKey == null) {
|
||||||
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
|
throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
|
||||||
|
@ -26,32 +26,32 @@ public class KeychainContract {
|
|||||||
|
|
||||||
interface KeyRingsColumns {
|
interface KeyRingsColumns {
|
||||||
String MASTER_KEY_ID = "master_key_id"; // not a database id
|
String MASTER_KEY_ID = "master_key_id"; // not a database id
|
||||||
String TYPE = "type"; // see KeyTypes
|
|
||||||
String KEY_RING_DATA = "key_ring_data"; // PGPPublicKeyRing / PGPSecretKeyRing blob
|
String KEY_RING_DATA = "key_ring_data"; // PGPPublicKeyRing / PGPSecretKeyRing blob
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeysColumns {
|
interface KeysColumns {
|
||||||
|
String MASTER_KEY_ID = "master_key_id"; // not a database id
|
||||||
|
String RANK = "rank";
|
||||||
|
|
||||||
String KEY_ID = "key_id"; // not a database id
|
String KEY_ID = "key_id"; // not a database id
|
||||||
String TYPE = "type"; // see KeyTypes
|
|
||||||
String IS_MASTER_KEY = "is_master_key";
|
|
||||||
String ALGORITHM = "algorithm";
|
String ALGORITHM = "algorithm";
|
||||||
|
String FINGERPRINT = "fingerprint";
|
||||||
|
|
||||||
String KEY_SIZE = "key_size";
|
String KEY_SIZE = "key_size";
|
||||||
String CAN_CERTIFY = "can_certify";
|
|
||||||
String CAN_SIGN = "can_sign";
|
String CAN_SIGN = "can_sign";
|
||||||
String CAN_ENCRYPT = "can_encrypt";
|
String CAN_ENCRYPT = "can_encrypt";
|
||||||
|
String CAN_CERTIFY = "can_certify";
|
||||||
String IS_REVOKED = "is_revoked";
|
String IS_REVOKED = "is_revoked";
|
||||||
|
|
||||||
String CREATION = "creation";
|
String CREATION = "creation";
|
||||||
String EXPIRY = "expiry";
|
String EXPIRY = "expiry";
|
||||||
String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID
|
|
||||||
String KEY_DATA = "key_data"; // PGPPublicKey/PGPSecretKey blob
|
|
||||||
String RANK = "rank";
|
|
||||||
String FINGERPRINT = "fingerprint";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserIdsColumns {
|
interface UserIdsColumns {
|
||||||
String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID
|
String MASTER_KEY_ID = "master_key_id"; // foreign key to key_rings._ID
|
||||||
String USER_ID = "user_id"; // not a database id
|
String USER_ID = "user_id"; // not a database id
|
||||||
String RANK = "rank";
|
String RANK = "rank"; // ONLY used for sorting! no key, no nothing!
|
||||||
|
String IS_PRIMARY = "is_primary";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ApiAppsColumns {
|
interface ApiAppsColumns {
|
||||||
@ -81,14 +81,15 @@ public class KeychainContract {
|
|||||||
public static final String BASE_KEY_RINGS = "key_rings";
|
public static final String BASE_KEY_RINGS = "key_rings";
|
||||||
public static final String BASE_DATA = "data";
|
public static final String BASE_DATA = "data";
|
||||||
|
|
||||||
public static final String PATH_PUBLIC = "public";
|
public static final String PATH_UNIFIED = "unified";
|
||||||
public static final String PATH_SECRET = "secret";
|
|
||||||
|
|
||||||
public static final String PATH_BY_MASTER_KEY_ID = "master_key_id";
|
public static final String PATH_BY_MASTER_KEY_ID = "master_key_id";
|
||||||
public static final String PATH_BY_KEY_ID = "key_id";
|
public static final String PATH_BY_KEY_ID = "key_id";
|
||||||
public static final String PATH_BY_EMAILS = "emails";
|
public static final String PATH_BY_EMAILS = "emails";
|
||||||
public static final String PATH_BY_LIKE_EMAIL = "like_email";
|
public static final String PATH_BY_LIKE_EMAIL = "like_email";
|
||||||
|
|
||||||
|
public static final String PATH_PUBLIC = "public";
|
||||||
|
public static final String PATH_SECRET = "secret";
|
||||||
public static final String PATH_USER_IDS = "user_ids";
|
public static final String PATH_USER_IDS = "user_ids";
|
||||||
public static final String PATH_KEYS = "keys";
|
public static final String PATH_KEYS = "keys";
|
||||||
|
|
||||||
@ -102,72 +103,43 @@ public class KeychainContract {
|
|||||||
/**
|
/**
|
||||||
* Use if multiple items get returned
|
* Use if multiple items get returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.key_ring";
|
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key_ring";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use if a single item is returned
|
* Use if a single item is returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.key_ring";
|
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key_ring";
|
||||||
|
|
||||||
public static Uri buildUnifiedKeyRingsUri() {
|
public static Uri buildUnifiedKeyRingsUri() {
|
||||||
return CONTENT_URI;
|
return CONTENT_URI.buildUpon().appendPath(PATH_UNIFIED).build();
|
||||||
|
}
|
||||||
|
public static Uri buildUnifiedKeyRingsByEmailUri(String email) {
|
||||||
|
return CONTENT_URI.buildUpon().appendPath("email:" + email).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri buildPublicKeyRingsUri() {
|
public static Uri buildGenericKeyRingUri(String masterKeyId) {
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).build();
|
return CONTENT_URI.buildUpon().appendPath(masterKeyId).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri buildPublicKeyRingsUri(String keyRingRowId) {
|
public static Uri buildPublicKeyRingUri(String masterKeyId) {
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId).build();
|
return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_PUBLIC).build();
|
||||||
|
}
|
||||||
|
public static Uri buildPublicKeyRingUri(Uri uri) {
|
||||||
|
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_PUBLIC).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri buildPublicKeyRingsByMasterKeyIdUri(String masterKeyId) {
|
public static Uri buildSecretKeyRingUri(String masterKeyId) {
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC)
|
return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_SECRET).build();
|
||||||
.appendPath(PATH_BY_MASTER_KEY_ID).appendPath(masterKeyId).build();
|
}
|
||||||
|
public static Uri buildSecretKeyRingUri(Uri uri) {
|
||||||
|
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_SECRET).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri buildPublicKeyRingsByKeyIdUri(String keyId) {
|
public static Uri buildUnifiedKeyRingUri(String masterKeyId) {
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(PATH_BY_KEY_ID)
|
return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_UNIFIED).build();
|
||||||
.appendPath(keyId).build();
|
|
||||||
}
|
}
|
||||||
|
public static Uri buildUnifiedKeyRingUri(Uri uri) {
|
||||||
public static Uri buildPublicKeyRingsByEmailsUri(String emails) {
|
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_UNIFIED).build();
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(PATH_BY_EMAILS)
|
|
||||||
.appendPath(emails).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildPublicKeyRingsByLikeEmailUri(String emails) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(PATH_BY_LIKE_EMAIL)
|
|
||||||
.appendPath(emails).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeyRingsUri() {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeyRingsUri(String keyRingRowId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeyRingsByMasterKeyIdUri(String masterKeyId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET)
|
|
||||||
.appendPath(PATH_BY_MASTER_KEY_ID).appendPath(masterKeyId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeyRingsByKeyIdUri(String keyId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_KEY_ID)
|
|
||||||
.appendPath(keyId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeyRingsByEmailsUri(String emails) {
|
|
||||||
// TODO: encoded?
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_EMAILS)
|
|
||||||
.appendPath(emails).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeyRingsByLikeEmails(String emails) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_LIKE_EMAIL)
|
|
||||||
.appendPath(emails).build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,40 +150,20 @@ public class KeychainContract {
|
|||||||
/**
|
/**
|
||||||
* Use if multiple items get returned
|
* Use if multiple items get returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.key";
|
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.key";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use if a single item is returned
|
* Use if a single item is returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.key";
|
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.key";
|
||||||
|
|
||||||
public static Uri buildPublicKeysUri(String keyRingRowId) {
|
public static Uri buildKeysUri(String masterKeyId) {
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId)
|
return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_KEYS).build();
|
||||||
.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 Uri buildPublicKeysUri(String keyRingRowId, String keyRowId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId)
|
|
||||||
.appendPath(PATH_KEYS).appendPath(keyRowId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeysUri(String keyRingRowId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId)
|
|
||||||
.appendPath(PATH_KEYS).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretKeysUri(String keyRingRowId, String keyRowId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId)
|
|
||||||
.appendPath(PATH_KEYS).appendPath(keyRowId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildKeysUri(Uri keyRingUri) {
|
|
||||||
return keyRingUri.buildUpon().appendPath(PATH_KEYS).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildKeysUri(Uri keyRingUri, String keyRowId) {
|
|
||||||
return keyRingUri.buildUpon().appendPath(PATH_KEYS).appendPath(keyRowId).build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UserIds implements UserIdsColumns, BaseColumns {
|
public static class UserIds implements UserIdsColumns, BaseColumns {
|
||||||
@ -221,39 +173,18 @@ public class KeychainContract {
|
|||||||
/**
|
/**
|
||||||
* Use if multiple items get returned
|
* Use if multiple items get returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.user_id";
|
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.user_id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use if a single item is returned
|
* Use if a single item is returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.user_id";
|
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.user_id";
|
||||||
|
|
||||||
public static Uri buildPublicUserIdsUri(String keyRingRowId) {
|
public static Uri buildUserIdsUri(String masterKeyId) {
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId)
|
return CONTENT_URI.buildUpon().appendPath(masterKeyId).appendPath(PATH_USER_IDS).build();
|
||||||
.appendPath(PATH_USER_IDS).build();
|
|
||||||
}
|
}
|
||||||
|
public static Uri buildUserIdsUri(Uri uri) {
|
||||||
public static Uri buildPublicUserIdsUri(String keyRingRowId, String userIdRowId) {
|
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_USER_IDS).build();
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(keyRingRowId)
|
|
||||||
.appendPath(PATH_USER_IDS).appendPath(userIdRowId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretUserIdsUri(String keyRingRowId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId)
|
|
||||||
.appendPath(PATH_USER_IDS).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildSecretUserIdsUri(String keyRingRowId, String userIdRowId) {
|
|
||||||
return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(keyRingRowId)
|
|
||||||
.appendPath(PATH_USER_IDS).appendPath(userIdRowId).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildUserIdsUri(Uri keyRingUri) {
|
|
||||||
return keyRingUri.buildUpon().appendPath(PATH_USER_IDS).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri buildUserIdsUri(Uri keyRingUri, String userIdRowId) {
|
|
||||||
return keyRingUri.buildUpon().appendPath(PATH_USER_IDS).appendPath(userIdRowId).build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,12 +195,12 @@ public class KeychainContract {
|
|||||||
/**
|
/**
|
||||||
* Use if multiple items get returned
|
* Use if multiple items get returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_apps";
|
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.api_apps";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use if a single item is returned
|
* Use if a single item is returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app";
|
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.api_app";
|
||||||
|
|
||||||
public static Uri buildByPackageNameUri(String packageName) {
|
public static Uri buildByPackageNameUri(String packageName) {
|
||||||
return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build();
|
return CONTENT_URI.buildUpon().appendEncodedPath(packageName).build();
|
||||||
@ -283,12 +214,12 @@ public class KeychainContract {
|
|||||||
/**
|
/**
|
||||||
* Use if multiple items get returned
|
* Use if multiple items get returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.thialfihar.apg.api_app.accounts";
|
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.sufficientlysecure.openkeychain.api_app.accounts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use if a single item is returned
|
* Use if a single item is returned
|
||||||
*/
|
*/
|
||||||
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.api_app.account";
|
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.sufficientlysecure.openkeychain.api_app.account";
|
||||||
|
|
||||||
public static Uri buildBaseUri(String packageName) {
|
public static Uri buildBaseUri(String packageName) {
|
||||||
return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS)
|
return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ACCOUNTS)
|
||||||
|
@ -18,11 +18,16 @@
|
|||||||
package org.sufficientlysecure.keychain.provider;
|
package org.sufficientlysecure.keychain.provider;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
|
|
||||||
|
import org.spongycastle.openpgp.PGPKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
|
||||||
@ -30,51 +35,72 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
|
|||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class KeychainDatabase extends SQLiteOpenHelper {
|
public class KeychainDatabase extends SQLiteOpenHelper {
|
||||||
private static final String DATABASE_NAME = "apg.db";
|
private static final String DATABASE_NAME = "openkeychain.db";
|
||||||
private static final int DATABASE_VERSION = 8;
|
private static final int DATABASE_VERSION = 1;
|
||||||
|
static Boolean apg_hack = false;
|
||||||
|
|
||||||
public interface Tables {
|
public interface Tables {
|
||||||
String KEY_RINGS = "key_rings";
|
String KEY_RINGS_PUBLIC = "keyrings_public";
|
||||||
|
String KEY_RINGS_SECRET = "keyrings_secret";
|
||||||
String KEYS = "keys";
|
String KEYS = "keys";
|
||||||
String USER_IDS = "user_ids";
|
String USER_IDS = "user_ids";
|
||||||
String API_APPS = "api_apps";
|
String API_APPS = "api_apps";
|
||||||
String API_ACCOUNTS = "api_accounts";
|
String API_ACCOUNTS = "api_accounts";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS
|
private static final String CREATE_KEYRINGS_PUBLIC =
|
||||||
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
"CREATE TABLE IF NOT EXISTS keyrings_public ("
|
||||||
+ KeyRingsColumns.MASTER_KEY_ID + " INT64, "
|
+ KeyRingsColumns.MASTER_KEY_ID + " INTEGER PRIMARY KEY,"
|
||||||
+ KeyRingsColumns.TYPE + " INTEGER, "
|
+ KeyRingsColumns.KEY_RING_DATA + " BLOB"
|
||||||
+ KeyRingsColumns.KEY_RING_DATA + " BLOB)";
|
+ ")";
|
||||||
|
|
||||||
private static final String CREATE_KEYS = "CREATE TABLE IF NOT EXISTS " + Tables.KEYS + " ("
|
private static final String CREATE_KEYRINGS_SECRET =
|
||||||
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
"CREATE TABLE IF NOT EXISTS keyrings_secret ("
|
||||||
+ KeysColumns.KEY_ID + " INT64, "
|
+ KeyRingsColumns.MASTER_KEY_ID + " INTEGER PRIMARY KEY,"
|
||||||
+ KeysColumns.TYPE + " INTEGER, "
|
+ KeyRingsColumns.KEY_RING_DATA + " BLOB,"
|
||||||
+ KeysColumns.IS_MASTER_KEY + " INTEGER, "
|
+ "FOREIGN KEY(" + KeyRingsColumns.MASTER_KEY_ID + ") "
|
||||||
+ KeysColumns.ALGORITHM + " INTEGER, "
|
+ "REFERENCES keyrings_public(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
|
||||||
+ KeysColumns.KEY_SIZE + " INTEGER, "
|
+ ")";
|
||||||
+ KeysColumns.CAN_CERTIFY + " INTEGER, "
|
|
||||||
+ KeysColumns.CAN_SIGN + " INTEGER, "
|
|
||||||
+ KeysColumns.CAN_ENCRYPT + " INTEGER, "
|
|
||||||
+ KeysColumns.IS_REVOKED + " INTEGER, "
|
|
||||||
+ KeysColumns.CREATION + " INTEGER, "
|
|
||||||
+ KeysColumns.EXPIRY + " INTEGER, "
|
|
||||||
+ KeysColumns.KEY_DATA + " BLOB,"
|
|
||||||
+ KeysColumns.RANK + " INTEGER, "
|
|
||||||
+ KeysColumns.FINGERPRINT + " BLOB, "
|
|
||||||
+ KeysColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, "
|
|
||||||
+ "FOREIGN KEY(" + KeysColumns.KEY_RING_ROW_ID + ") REFERENCES "
|
|
||||||
+ Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)";
|
|
||||||
|
|
||||||
private static final String CREATE_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS
|
private static final String CREATE_KEYS =
|
||||||
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
"CREATE TABLE IF NOT EXISTS " + Tables.KEYS + " ("
|
||||||
+ UserIdsColumns.USER_ID + " TEXT, "
|
+ KeysColumns.MASTER_KEY_ID + " INTEGER, "
|
||||||
+ UserIdsColumns.RANK + " INTEGER, "
|
+ KeysColumns.RANK + " INTEGER, "
|
||||||
+ UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, "
|
|
||||||
+ "FOREIGN KEY(" + UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES "
|
+ KeysColumns.KEY_ID + " INTEGER, "
|
||||||
+ Tables.KEY_RINGS + "(" + BaseColumns._ID + ") ON DELETE CASCADE)";
|
+ KeysColumns.KEY_SIZE + " INTEGER, "
|
||||||
|
+ KeysColumns.ALGORITHM + " INTEGER, "
|
||||||
|
+ KeysColumns.FINGERPRINT + " BLOB, "
|
||||||
|
|
||||||
|
+ KeysColumns.CAN_CERTIFY + " BOOLEAN, "
|
||||||
|
+ KeysColumns.CAN_SIGN + " BOOLEAN, "
|
||||||
|
+ KeysColumns.CAN_ENCRYPT + " BOOLEAN, "
|
||||||
|
+ KeysColumns.IS_REVOKED + " BOOLEAN, "
|
||||||
|
|
||||||
|
+ KeysColumns.CREATION + " INTEGER, "
|
||||||
|
+ KeysColumns.EXPIRY + " INTEGER, "
|
||||||
|
|
||||||
|
+ "PRIMARY KEY(" + KeysColumns.MASTER_KEY_ID + ", " + KeysColumns.RANK + "),"
|
||||||
|
+ "FOREIGN KEY(" + KeysColumns.MASTER_KEY_ID + ") REFERENCES "
|
||||||
|
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
private static final String CREATE_USER_IDS =
|
||||||
|
"CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS + "("
|
||||||
|
+ UserIdsColumns.MASTER_KEY_ID + " INTEGER, "
|
||||||
|
+ UserIdsColumns.USER_ID + " CHARMANDER, "
|
||||||
|
|
||||||
|
+ UserIdsColumns.IS_PRIMARY + " BOOLEAN, "
|
||||||
|
+ UserIdsColumns.RANK+ " INTEGER, "
|
||||||
|
|
||||||
|
+ "PRIMARY KEY(" + UserIdsColumns.MASTER_KEY_ID + ", " + UserIdsColumns.USER_ID + "),"
|
||||||
|
+ "FOREIGN KEY(" + UserIdsColumns.MASTER_KEY_ID + ") REFERENCES "
|
||||||
|
+ Tables.KEY_RINGS_PUBLIC + "(" + KeyRingsColumns.MASTER_KEY_ID + ") ON DELETE CASCADE"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS
|
private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS
|
||||||
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
@ -96,13 +122,27 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
|||||||
|
|
||||||
KeychainDatabase(Context context) {
|
KeychainDatabase(Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
|
||||||
|
|
||||||
|
// make sure this is only done once, on the first instance!
|
||||||
|
boolean iAmIt = false;
|
||||||
|
synchronized(apg_hack) {
|
||||||
|
if(!apg_hack) {
|
||||||
|
iAmIt = true;
|
||||||
|
apg_hack = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if it's us, do the import
|
||||||
|
if(iAmIt)
|
||||||
|
checkAndImportApg(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(SQLiteDatabase db) {
|
public void onCreate(SQLiteDatabase db) {
|
||||||
Log.w(Constants.TAG, "Creating database...");
|
Log.w(Constants.TAG, "Creating database...");
|
||||||
|
|
||||||
db.execSQL(CREATE_KEY_RINGS);
|
db.execSQL(CREATE_KEYRINGS_PUBLIC);
|
||||||
|
db.execSQL(CREATE_KEYRINGS_SECRET);
|
||||||
db.execSQL(CREATE_KEYS);
|
db.execSQL(CREATE_KEYS);
|
||||||
db.execSQL(CREATE_USER_IDS);
|
db.execSQL(CREATE_USER_IDS);
|
||||||
db.execSQL(CREATE_API_APPS);
|
db.execSQL(CREATE_API_APPS);
|
||||||
@ -119,44 +159,91 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onUpgrade(SQLiteDatabase db, int old, int nu) {
|
||||||
Log.w(Constants.TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
|
// don't care (this is version 1)
|
||||||
|
}
|
||||||
|
|
||||||
// Upgrade from oldVersion through all cases to newest one
|
/** This method tries to import data from a provided database.
|
||||||
for (int version = oldVersion; version < newVersion; ++version) {
|
*
|
||||||
Log.w(Constants.TAG, "Upgrading database to version " + version);
|
* The sole assumptions made on this db are that there is a key_rings table
|
||||||
|
* with a key_ring_data and a type column, the latter of which should be bigger
|
||||||
|
* for secret keys.
|
||||||
|
*/
|
||||||
|
public void checkAndImportApg(Context context) {
|
||||||
|
|
||||||
switch (version) {
|
boolean hasApgDb = false; {
|
||||||
case 3:
|
// It's the Java way =(
|
||||||
db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.CAN_CERTIFY
|
String[] dbs = context.databaseList();
|
||||||
+ " INTEGER DEFAULT 0;");
|
for(String db : dbs) {
|
||||||
db.execSQL("UPDATE " + Tables.KEYS + " SET " + KeysColumns.CAN_CERTIFY
|
if(db.equals("apg.db")) {
|
||||||
+ " = 1 WHERE " + KeysColumns.IS_MASTER_KEY + "= 1;");
|
hasApgDb = true;
|
||||||
break;
|
break;
|
||||||
case 4:
|
}
|
||||||
db.execSQL(CREATE_API_APPS);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// new column: package_signature
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS);
|
|
||||||
db.execSQL(CREATE_API_APPS);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
// new column: fingerprint
|
|
||||||
db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.FINGERPRINT
|
|
||||||
+ " BLOB;");
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
// new db layout for api apps
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS);
|
|
||||||
db.execSQL(CREATE_API_APPS);
|
|
||||||
db.execSQL(CREATE_API_APPS_ACCOUNTS);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!hasApgDb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Log.d(Constants.TAG, "apg.db exists! Importing...");
|
||||||
|
|
||||||
|
SQLiteDatabase db = new SQLiteOpenHelper(context, "apg.db", null, 1) {
|
||||||
|
@Override
|
||||||
|
public void onCreate(SQLiteDatabase db) {
|
||||||
|
// should never happen
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onDowngrade(SQLiteDatabase db, int old, int nu) {
|
||||||
|
// don't care
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(SQLiteDatabase db, int old, int nu) {
|
||||||
|
// don't care either
|
||||||
|
}
|
||||||
|
}.getReadableDatabase();
|
||||||
|
|
||||||
|
// kill current!
|
||||||
|
{ // TODO don't kill current.
|
||||||
|
Log.d(Constants.TAG, "Truncating db...");
|
||||||
|
SQLiteDatabase d = getWritableDatabase();
|
||||||
|
d.execSQL("DELETE FROM keyrings_public");
|
||||||
|
d.close();
|
||||||
|
Log.d(Constants.TAG, "Ok.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Cursor c = db.rawQuery("SELECT key_ring_data FROM key_rings ORDER BY type ASC", null);
|
||||||
|
try {
|
||||||
|
// import from old database
|
||||||
|
Log.d(Constants.TAG, "Importing " + c.getCount() + " keyrings from apg.db...");
|
||||||
|
for(int i = 0; i < c.getCount(); i++) {
|
||||||
|
c.moveToPosition(i);
|
||||||
|
byte[] data = c.getBlob(0);
|
||||||
|
PGPKeyRing ring = PgpConversionHelper.BytesToPGPKeyRing(data);
|
||||||
|
if(ring instanceof PGPPublicKeyRing)
|
||||||
|
ProviderHelper.saveKeyRing(context, (PGPPublicKeyRing) ring);
|
||||||
|
else if(ring instanceof PGPSecretKeyRing)
|
||||||
|
ProviderHelper.saveKeyRing(context, (PGPSecretKeyRing) ring);
|
||||||
|
else {
|
||||||
|
Log.e(Constants.TAG, "Unknown blob data type!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(IOException e) {
|
||||||
|
Log.e(Constants.TAG, "Error importing apg db!", e);
|
||||||
|
return;
|
||||||
|
} finally {
|
||||||
|
if(c != null)
|
||||||
|
c.close();
|
||||||
|
if(db != null)
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO delete old db, if we are sure this works
|
||||||
|
// context.deleteDatabase("apg.db");
|
||||||
|
Log.d(Constants.TAG, "All done, (not) deleting apg.db");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,7 @@ import android.provider.BaseColumns;
|
|||||||
import org.sufficientlysecure.keychain.provider.KeychainServiceBlobContract.BlobsColumns;
|
import org.sufficientlysecure.keychain.provider.KeychainServiceBlobContract.BlobsColumns;
|
||||||
|
|
||||||
public class KeychainServiceBlobDatabase extends SQLiteOpenHelper {
|
public class KeychainServiceBlobDatabase extends SQLiteOpenHelper {
|
||||||
private static final String DATABASE_NAME = "apg_blob.db";
|
private static final String DATABASE_NAME = "openkeychain_blob.db";
|
||||||
private static final int DATABASE_VERSION = 2;
|
private static final int DATABASE_VERSION = 2;
|
||||||
|
|
||||||
public static final String TABLE = "data";
|
public static final String TABLE = "data";
|
||||||
|
@ -75,78 +75,40 @@ public class ProviderHelper {
|
|||||||
return keyRing;
|
return keyRing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
|
||||||
* Retrieves the actual PGPPublicKeyRing object from the database blob based on the rowId
|
return getPGPPublicKeyRingWithKeyId(context, keyId).getPublicKey(keyId);
|
||||||
*/
|
}
|
||||||
public static PGPPublicKeyRing getPGPPublicKeyRingByRowId(Context context, long rowId) {
|
public static PGPPublicKeyRing getPGPPublicKeyRingWithKeyId(Context context, long keyId) {
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId));
|
// todo do
|
||||||
return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) {
|
||||||
|
return getPGPSecretKeyRingWithKeyId(context, keyId).getSecretKey(keyId);
|
||||||
|
}
|
||||||
|
public static PGPSecretKeyRing getPGPSecretKeyRingWithKeyId(Context context, long keyId) {
|
||||||
|
// todo do
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPPublicKeyRing object from the database blob based on the masterKeyId
|
* Retrieves the actual PGPPublicKeyRing object from the database blob based on the masterKeyId
|
||||||
*/
|
*/
|
||||||
public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context,
|
public static PGPPublicKeyRing getPGPPublicKeyRing(Context context,
|
||||||
long masterKeyId) {
|
long masterKeyId) {
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
|
Uri queryUri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId));
|
||||||
return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri);
|
return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the actual PGPPublicKeyRing object from the database blob associated with a key
|
|
||||||
* with this keyId
|
|
||||||
*/
|
|
||||||
public static PGPPublicKeyRing getPGPPublicKeyRingByKeyId(Context context, long keyId) {
|
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsByKeyIdUri(Long.toString(keyId));
|
|
||||||
return (PGPPublicKeyRing) getPGPKeyRing(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the actual PGPPublicKey object from the database blob associated with a key with
|
|
||||||
* this keyId
|
|
||||||
*/
|
|
||||||
public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
|
|
||||||
PGPPublicKeyRing keyRing = getPGPPublicKeyRingByKeyId(context, keyId);
|
|
||||||
|
|
||||||
return (keyRing == null) ? null : keyRing.getPublicKey(keyId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the actual PGPSecretKeyRing object from the database blob based on the rowId
|
|
||||||
*/
|
|
||||||
public static PGPSecretKeyRing getPGPSecretKeyRingByRowId(Context context, long rowId) {
|
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId));
|
|
||||||
return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPSecretKeyRing object from the database blob based on the maserKeyId
|
* Retrieves the actual PGPSecretKeyRing object from the database blob based on the maserKeyId
|
||||||
*/
|
*/
|
||||||
public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context,
|
public static PGPSecretKeyRing getPGPSecretKeyRing(Context context,
|
||||||
long masterKeyId) {
|
long masterKeyId) {
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
|
Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId));
|
||||||
return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri);
|
return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the actual PGPSecretKeyRing object from the database blob associated with a key
|
|
||||||
* with this keyId
|
|
||||||
*/
|
|
||||||
public static PGPSecretKeyRing getPGPSecretKeyRingByKeyId(Context context, long keyId) {
|
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsByKeyIdUri(Long.toString(keyId));
|
|
||||||
return (PGPSecretKeyRing) getPGPKeyRing(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the actual PGPSecretKey object from the database blob associated with a key with
|
|
||||||
* this keyId
|
|
||||||
*/
|
|
||||||
public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) {
|
|
||||||
PGPSecretKeyRing keyRing = getPGPSecretKeyRingByKeyId(context, keyId);
|
|
||||||
|
|
||||||
return (keyRing == null) ? null : keyRing.getSecretKey(keyId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves PGPPublicKeyRing with its keys and userIds in DB
|
* Saves PGPPublicKeyRing with its keys and userIds in DB
|
||||||
*/
|
*/
|
||||||
@ -155,21 +117,13 @@ public class ProviderHelper {
|
|||||||
PGPPublicKey masterKey = keyRing.getPublicKey();
|
PGPPublicKey masterKey = keyRing.getPublicKey();
|
||||||
long masterKeyId = masterKey.getKeyID();
|
long masterKeyId = masterKey.getKeyID();
|
||||||
|
|
||||||
Uri deleteUri = KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
|
// IF there is a secret key, preserve it!
|
||||||
|
// TODO This even necessary?
|
||||||
// get current _ID of key
|
// PGPSecretKeyRing secretRing = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId);
|
||||||
long currentRowId = -1;
|
|
||||||
Cursor oldQuery = context.getContentResolver()
|
|
||||||
.query(deleteUri, new String[]{KeyRings._ID}, null, null, null);
|
|
||||||
if (oldQuery != null && oldQuery.moveToFirst()) {
|
|
||||||
currentRowId = oldQuery.getLong(0);
|
|
||||||
} else {
|
|
||||||
Log.e(Constants.TAG, "Key could not be found! Something wrong is happening!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete old version of this keyRing, which also deletes all keys and userIds on cascade
|
// delete old version of this keyRing, which also deletes all keys and userIds on cascade
|
||||||
try {
|
try {
|
||||||
context.getContentResolver().delete(deleteUri, null, null);
|
context.getContentResolver().delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null);
|
||||||
} catch (UnsupportedOperationException e) {
|
} catch (UnsupportedOperationException e) {
|
||||||
Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e);
|
Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e);
|
||||||
}
|
}
|
||||||
@ -179,29 +133,25 @@ public class ProviderHelper {
|
|||||||
// NOTE: If we would not use the same _ID again,
|
// NOTE: If we would not use the same _ID again,
|
||||||
// getting back to the ViewKeyActivity would result in Nullpointer,
|
// getting back to the ViewKeyActivity would result in Nullpointer,
|
||||||
// because the currently loaded key would be gone from the database
|
// because the currently loaded key would be gone from the database
|
||||||
if (currentRowId != -1) {
|
|
||||||
values.put(KeyRings._ID, currentRowId);
|
|
||||||
}
|
|
||||||
values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
|
values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
|
||||||
values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
|
values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
|
||||||
|
|
||||||
// insert new version of this keyRing
|
// insert new version of this keyRing
|
||||||
Uri uri = KeyRings.buildPublicKeyRingsUri();
|
Uri uri = KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId));
|
||||||
Uri insertedUri = context.getContentResolver().insert(uri, values);
|
Uri insertedUri = context.getContentResolver().insert(uri, values);
|
||||||
long keyRingRowId = Long.valueOf(insertedUri.getLastPathSegment());
|
|
||||||
|
|
||||||
// save all keys and userIds included in keyRing object in database
|
// save all keys and userIds included in keyRing object in database
|
||||||
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
|
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
|
||||||
|
|
||||||
int rank = 0;
|
int rank = 0;
|
||||||
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
|
for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(keyRing.getPublicKeys())) {
|
||||||
operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank));
|
operations.add(buildPublicKeyOperations(context, masterKeyId, key, rank));
|
||||||
++rank;
|
++rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
int userIdRank = 0;
|
int userIdRank = 0;
|
||||||
for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
|
for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
|
||||||
operations.add(buildPublicUserIdOperations(context, keyRingRowId, userId, userIdRank));
|
operations.add(buildUserIdOperations(context, masterKeyId, userId, userIdRank));
|
||||||
++userIdRank;
|
++userIdRank;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +164,6 @@ public class ProviderHelper {
|
|||||||
// operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank));
|
// operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
|
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@ -222,6 +171,12 @@ public class ProviderHelper {
|
|||||||
} catch (OperationApplicationException e) {
|
} catch (OperationApplicationException e) {
|
||||||
Log.e(Constants.TAG, "applyBatch failed!", e);
|
Log.e(Constants.TAG, "applyBatch failed!", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the saved keyring (if any)
|
||||||
|
// TODO this even necessary? see above...
|
||||||
|
// if(secretRing != null)
|
||||||
|
// saveKeyRing(context, secretRing);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,104 +187,46 @@ public class ProviderHelper {
|
|||||||
PGPSecretKey masterKey = keyRing.getSecretKey();
|
PGPSecretKey masterKey = keyRing.getSecretKey();
|
||||||
long masterKeyId = masterKey.getKeyID();
|
long masterKeyId = masterKey.getKeyID();
|
||||||
|
|
||||||
Uri deleteUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
|
// TODO Make sure there is a public key for this secret key in the db (create one maybe)
|
||||||
|
|
||||||
// get current _ID of key
|
{
|
||||||
long currentRowId = -1;
|
ContentValues values = new ContentValues();
|
||||||
Cursor oldQuery = context.getContentResolver()
|
values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
|
||||||
.query(deleteUri, new String[]{KeyRings._ID}, null, null, null);
|
values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
|
||||||
if (oldQuery != null && oldQuery.moveToFirst()) {
|
// insert new version of this keyRing
|
||||||
currentRowId = oldQuery.getLong(0);
|
Uri uri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId));
|
||||||
} else {
|
context.getContentResolver().insert(uri, values);
|
||||||
Log.e(Constants.TAG, "Key could not be found! Something wrong is happening!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete old version of this keyRing, which also deletes all keys and userIds on cascade
|
|
||||||
try {
|
|
||||||
context.getContentResolver().delete(deleteUri, null, null);
|
|
||||||
} catch (UnsupportedOperationException e) {
|
|
||||||
Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
// use exactly the same _ID again to replace key in-place.
|
|
||||||
// NOTE: If we would not use the same _ID again,
|
|
||||||
// getting back to the ViewKeyActivity would result in Nullpointer,
|
|
||||||
// because the currently loaded key would be gone from the database
|
|
||||||
if (currentRowId != -1) {
|
|
||||||
values.put(KeyRings._ID, currentRowId);
|
|
||||||
}
|
|
||||||
values.put(KeyRings.MASTER_KEY_ID, masterKeyId);
|
|
||||||
values.put(KeyRings.KEY_RING_DATA, keyRing.getEncoded());
|
|
||||||
|
|
||||||
// insert new version of this keyRing
|
|
||||||
Uri uri = KeyRings.buildSecretKeyRingsUri();
|
|
||||||
Uri insertedUri = context.getContentResolver().insert(uri, values);
|
|
||||||
long keyRingRowId = Long.valueOf(insertedUri.getLastPathSegment());
|
|
||||||
|
|
||||||
// save all keys and userIds included in keyRing object in database
|
|
||||||
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
|
|
||||||
|
|
||||||
int rank = 0;
|
|
||||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
|
||||||
operations.add(buildSecretKeyOperations(context, keyRingRowId, key, rank));
|
|
||||||
++rank;
|
|
||||||
}
|
|
||||||
|
|
||||||
int userIdRank = 0;
|
|
||||||
for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) {
|
|
||||||
operations.add(buildSecretUserIdOperations(context, keyRingRowId, userId, userIdRank));
|
|
||||||
++userIdRank;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(Constants.TAG, "applyBatch failed!", e);
|
|
||||||
} catch (OperationApplicationException e) {
|
|
||||||
Log.e(Constants.TAG, "applyBatch failed!", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
|
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
|
||||||
*/
|
*/
|
||||||
private static ContentProviderOperation buildPublicKeyOperations(Context context,
|
private static ContentProviderOperation buildPublicKeyOperations(Context context,
|
||||||
long keyRingRowId, PGPPublicKey key, int rank) throws IOException {
|
long masterKeyId, PGPPublicKey key, int rank) throws IOException {
|
||||||
|
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(Keys.MASTER_KEY_ID, masterKeyId);
|
||||||
|
values.put(Keys.RANK, rank);
|
||||||
|
|
||||||
values.put(Keys.KEY_ID, key.getKeyID());
|
values.put(Keys.KEY_ID, key.getKeyID());
|
||||||
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
|
||||||
values.put(Keys.ALGORITHM, key.getAlgorithm());
|
|
||||||
values.put(Keys.KEY_SIZE, key.getBitStrength());
|
values.put(Keys.KEY_SIZE, key.getBitStrength());
|
||||||
values.put(Keys.CAN_SIGN, PgpKeyHelper.isSigningKey(key));
|
values.put(Keys.ALGORITHM, key.getAlgorithm());
|
||||||
|
values.put(Keys.FINGERPRINT, key.getFingerprint());
|
||||||
|
|
||||||
|
values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key)));
|
||||||
|
values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key)));
|
||||||
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
|
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
|
||||||
values.put(Keys.IS_REVOKED, key.isRevoked());
|
values.put(Keys.IS_REVOKED, key.isRevoked());
|
||||||
|
|
||||||
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
|
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
|
||||||
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
|
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
|
||||||
if (expiryDate != null) {
|
if (expiryDate != null) {
|
||||||
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
|
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
|
||||||
}
|
}
|
||||||
values.put(Keys.KEY_RING_ROW_ID, keyRingRowId);
|
|
||||||
values.put(Keys.KEY_DATA, key.getEncoded());
|
|
||||||
values.put(Keys.RANK, rank);
|
|
||||||
values.put(Keys.FINGERPRINT, key.getFingerprint());
|
|
||||||
|
|
||||||
Uri uri = Keys.buildPublicKeysUri(Long.toString(keyRingRowId));
|
Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId));
|
||||||
|
|
||||||
return ContentProviderOperation.newInsert(uri).withValues(values).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing
|
|
||||||
*/
|
|
||||||
private static ContentProviderOperation buildPublicUserIdOperations(Context context,
|
|
||||||
long keyRingRowId, String userId, int rank) {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId);
|
|
||||||
values.put(UserIds.USER_ID, userId);
|
|
||||||
values.put(UserIds.RANK, rank);
|
|
||||||
|
|
||||||
Uri uri = UserIds.buildPublicUserIdsUri(Long.toString(keyRingRowId));
|
|
||||||
|
|
||||||
return ContentProviderOperation.newInsert(uri).withValues(values).build();
|
return ContentProviderOperation.newInsert(uri).withValues(values).build();
|
||||||
}
|
}
|
||||||
@ -338,50 +235,21 @@ public class ProviderHelper {
|
|||||||
* Build ContentProviderOperation to add PGPSecretKey to database corresponding to a keyRing
|
* Build ContentProviderOperation to add PGPSecretKey to database corresponding to a keyRing
|
||||||
*/
|
*/
|
||||||
private static ContentProviderOperation buildSecretKeyOperations(Context context,
|
private static ContentProviderOperation buildSecretKeyOperations(Context context,
|
||||||
long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
|
long masterKeyId, PGPSecretKey key, int rank) throws IOException {
|
||||||
ContentValues values = new ContentValues();
|
return buildPublicKeyOperations(context, masterKeyId, key.getPublicKey(), rank);
|
||||||
|
|
||||||
boolean hasPrivate = true;
|
|
||||||
if (key.isMasterKey()) {
|
|
||||||
if (key.isPrivateKeyEmpty()) {
|
|
||||||
hasPrivate = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
values.put(Keys.KEY_ID, key.getKeyID());
|
|
||||||
values.put(Keys.IS_MASTER_KEY, key.isMasterKey());
|
|
||||||
values.put(Keys.ALGORITHM, key.getPublicKey().getAlgorithm());
|
|
||||||
values.put(Keys.KEY_SIZE, key.getPublicKey().getBitStrength());
|
|
||||||
values.put(Keys.CAN_CERTIFY, (PgpKeyHelper.isCertificationKey(key) && hasPrivate));
|
|
||||||
values.put(Keys.CAN_SIGN, (PgpKeyHelper.isSigningKey(key) && hasPrivate));
|
|
||||||
values.put(Keys.CAN_ENCRYPT, PgpKeyHelper.isEncryptionKey(key));
|
|
||||||
values.put(Keys.IS_REVOKED, key.getPublicKey().isRevoked());
|
|
||||||
values.put(Keys.CREATION, PgpKeyHelper.getCreationDate(key).getTime() / 1000);
|
|
||||||
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
|
|
||||||
if (expiryDate != null) {
|
|
||||||
values.put(Keys.EXPIRY, expiryDate.getTime() / 1000);
|
|
||||||
}
|
|
||||||
values.put(Keys.KEY_RING_ROW_ID, keyRingRowId);
|
|
||||||
values.put(Keys.KEY_DATA, key.getEncoded());
|
|
||||||
values.put(Keys.RANK, rank);
|
|
||||||
values.put(Keys.FINGERPRINT, key.getPublicKey().getFingerprint());
|
|
||||||
|
|
||||||
Uri uri = Keys.buildSecretKeysUri(Long.toString(keyRingRowId));
|
|
||||||
|
|
||||||
return ContentProviderOperation.newInsert(uri).withValues(values).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing
|
* Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing
|
||||||
*/
|
*/
|
||||||
private static ContentProviderOperation buildSecretUserIdOperations(Context context,
|
private static ContentProviderOperation buildUserIdOperations(Context context,
|
||||||
long keyRingRowId, String userId, int rank) {
|
long masterKeyId, String userId, int rank) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(UserIds.KEY_RING_ROW_ID, keyRingRowId);
|
values.put(UserIds.MASTER_KEY_ID, masterKeyId);
|
||||||
values.put(UserIds.USER_ID, userId);
|
values.put(UserIds.USER_ID, userId);
|
||||||
values.put(UserIds.RANK, rank);
|
values.put(UserIds.RANK, rank);
|
||||||
|
|
||||||
Uri uri = UserIds.buildSecretUserIdsUri(Long.toString(keyRingRowId));
|
Uri uri = UserIds.buildUserIdsUri(Long.toString(masterKeyId));
|
||||||
|
|
||||||
return ContentProviderOperation.newInsert(uri).withValues(values).build();
|
return ContentProviderOperation.newInsert(uri).withValues(values).build();
|
||||||
}
|
}
|
||||||
@ -410,141 +278,54 @@ public class ProviderHelper {
|
|||||||
return masterKeyIds;
|
return masterKeyIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static void deletePublicKeyRing(Context context, long masterKeyId) {
|
||||||
* Private helper method
|
|
||||||
*/
|
|
||||||
private static ArrayList<Long> getKeyRingsRowIds(Context context, Uri queryUri) {
|
|
||||||
Cursor cursor = context.getContentResolver().query(queryUri,
|
|
||||||
new String[]{KeyRings._ID}, null, null, null);
|
|
||||||
|
|
||||||
ArrayList<Long> rowIds = new ArrayList<Long>();
|
|
||||||
if (cursor != null) {
|
|
||||||
int idCol = cursor.getColumnIndex(KeyRings._ID);
|
|
||||||
if (cursor.moveToFirst()) {
|
|
||||||
do {
|
|
||||||
rowIds.add(cursor.getLong(idCol));
|
|
||||||
} while (cursor.moveToNext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return rowIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves ids of all SecretKeyRings
|
|
||||||
*/
|
|
||||||
public static ArrayList<Long> getSecretKeyRingsMasterKeyIds(Context context) {
|
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri();
|
|
||||||
return getKeyRingsMasterKeyIds(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves ids of all PublicKeyRings
|
|
||||||
*/
|
|
||||||
public static ArrayList<Long> getPublicKeyRingsMasterKeyIds(Context context) {
|
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsUri();
|
|
||||||
return getKeyRingsMasterKeyIds(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves ids of all SecretKeyRings
|
|
||||||
*/
|
|
||||||
public static ArrayList<Long> getSecretKeyRingsRowIds(Context context) {
|
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri();
|
|
||||||
return getKeyRingsRowIds(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves ids of all PublicKeyRings
|
|
||||||
*/
|
|
||||||
public static ArrayList<Long> getPublicKeyRingsRowIds(Context context) {
|
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsUri();
|
|
||||||
return getKeyRingsRowIds(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deletePublicKeyRing(Context context, long rowId) {
|
|
||||||
ContentResolver cr = context.getContentResolver();
|
ContentResolver cr = context.getContentResolver();
|
||||||
cr.delete(KeyRings.buildPublicKeyRingsUri(Long.toString(rowId)), null, null);
|
cr.delete(KeyRings.buildPublicKeyRingUri(Long.toString(masterKeyId)), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteSecretKeyRing(Context context, long rowId) {
|
public static void deleteSecretKeyRing(Context context, long masterKeyId) {
|
||||||
ContentResolver cr = context.getContentResolver();
|
ContentResolver cr = context.getContentResolver();
|
||||||
cr.delete(KeyRings.buildSecretKeyRingsUri(Long.toString(rowId)), null, null);
|
cr.delete(KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId)), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteUnifiedKeyRing(Context context, String masterKeyId, boolean isSecretKey) {
|
|
||||||
ContentResolver cr = context.getContentResolver();
|
|
||||||
cr.delete(KeyRings.buildPublicKeyRingsByMasterKeyIdUri(masterKeyId), null, null);
|
|
||||||
if (isSecretKey) {
|
|
||||||
cr.delete(KeyRings.buildSecretKeyRingsByMasterKeyIdUri(masterKeyId), null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get master key id of keyring by its row id
|
|
||||||
*/
|
|
||||||
public static long getPublicMasterKeyId(Context context, long keyRingRowId) {
|
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowId));
|
|
||||||
return getMasterKeyId(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get empty status of master key of keyring by its row id
|
|
||||||
*/
|
|
||||||
public static boolean getSecretMasterKeyCanCertify(Context context, long keyRingRowId) {
|
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId));
|
|
||||||
return getMasterKeyCanCertify(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private helper method to get master key private empty status of keyring by its row id
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static boolean getMasterKeyCanCertify(Context context, Uri queryUri) {
|
public static boolean getMasterKeyCanCertify(Context context, Uri queryUri) {
|
||||||
String[] projection = new String[]{
|
// TODO redo
|
||||||
KeyRings.MASTER_KEY_ID,
|
|
||||||
"(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS
|
|
||||||
+ " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = "
|
|
||||||
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
|
|
||||||
+ " AND sign_keys." + Keys.CAN_CERTIFY + " = '1' AND " + Keys.IS_MASTER_KEY
|
|
||||||
+ " = 1) AS sign",};
|
|
||||||
|
|
||||||
ContentResolver cr = context.getContentResolver();
|
return false;
|
||||||
Cursor cursor = cr.query(queryUri, projection, null, null, null);
|
|
||||||
|
|
||||||
long masterKeyId = -1;
|
/*
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
String[] projection = new String[]{
|
||||||
int masterKeyIdCol = cursor.getColumnIndex("sign");
|
KeyRings.MASTER_KEY_ID,
|
||||||
|
"(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS
|
||||||
|
+ " AS sign_keys WHERE sign_keys." + Keys.KEY_RING_ROW_ID + " = "
|
||||||
|
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
|
||||||
|
+ " AND sign_keys." + Keys.CAN_CERTIFY + " = '1' AND " + Keys.IS_MASTER_KEY
|
||||||
|
+ " = 1) AS sign",};
|
||||||
|
|
||||||
masterKeyId = cursor.getLong(masterKeyIdCol);
|
ContentResolver cr = context.getContentResolver();
|
||||||
}
|
Cursor cursor = cr.query(queryUri, projection, null, null, null);
|
||||||
|
|
||||||
if (cursor != null) {
|
long masterKeyId = -1;
|
||||||
cursor.close();
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
}
|
int masterKeyIdCol = cursor.getColumnIndex("sign");
|
||||||
|
|
||||||
return (masterKeyId > 0);
|
masterKeyId = cursor.getLong(masterKeyIdCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (masterKeyId > 0);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) {
|
public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) {
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId));
|
Uri queryUri = KeyRings.buildSecretKeyRingUri(Long.toString(masterKeyId));
|
||||||
// see if we can get our master key id back from the uri
|
// see if we can get our master key id back from the uri
|
||||||
return getMasterKeyId(context, queryUri) == masterKeyId;
|
return getMasterKeyId(context, queryUri) == masterKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get master key id of keyring by its row id
|
|
||||||
*/
|
|
||||||
public static long getSecretMasterKeyId(Context context, long keyRingRowId) {
|
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId));
|
|
||||||
return getMasterKeyId(context, queryUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get master key id of key
|
* Get master key id of key
|
||||||
*/
|
*/
|
||||||
@ -629,10 +410,10 @@ public class ProviderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, masterKeyId);
|
PGPPublicKey key = ProviderHelper.getPGPPublicKeyRing(context, masterKeyId).getPublicKey();
|
||||||
// if it is no public key get it from your own keys...
|
// if it is no public key get it from your own keys...
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, masterKeyId);
|
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyRing(context, masterKeyId).getSecretKey();
|
||||||
if (secretKey == null) {
|
if (secretKey == null) {
|
||||||
Log.e(Constants.TAG, "Key could not be found!");
|
Log.e(Constants.TAG, "Key could not be found!");
|
||||||
return null;
|
return null;
|
||||||
@ -646,26 +427,6 @@ public class ProviderHelper {
|
|||||||
return fingerprint;
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUserId(Context context, Uri queryUri) {
|
|
||||||
String[] projection = new String[]{UserIds.USER_ID};
|
|
||||||
Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
|
|
||||||
|
|
||||||
String userId = null;
|
|
||||||
try {
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
int col = cursor.getColumnIndexOrThrow(UserIds.USER_ID);
|
|
||||||
|
|
||||||
userId = cursor.getString(col);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri,
|
public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri,
|
||||||
long[] masterKeyIds) {
|
long[] masterKeyIds) {
|
||||||
ArrayList<String> output = new ArrayList<String>();
|
ArrayList<String> output = new ArrayList<String>();
|
||||||
|
@ -64,7 +64,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
ArrayList<String> dublicateUserIds = new ArrayList<String>();
|
ArrayList<String> dublicateUserIds = new ArrayList<String>();
|
||||||
|
|
||||||
for (String email : encryptionUserIds) {
|
for (String email : encryptionUserIds) {
|
||||||
Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByEmailsUri(email);
|
Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingsByEmailUri(email);
|
||||||
Cursor cur = getContentResolver().query(uri, null, null, null, null);
|
Cursor cur = getContentResolver().query(uri, null, null, null, null);
|
||||||
if (cur.moveToFirst()) {
|
if (cur.moveToFirst()) {
|
||||||
long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID));
|
long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID));
|
||||||
|
@ -478,8 +478,7 @@ public class KeychainIntentService extends IntentService
|
|||||||
/* Operation */
|
/* Operation */
|
||||||
if (!canSign) {
|
if (!canSign) {
|
||||||
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 50, 100));
|
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 50, 100));
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
|
||||||
.getPGPSecretKeyRingByKeyId(this, masterKeyId);
|
|
||||||
keyRing = keyOperations.changeSecretKeyPassphrase(keyRing,
|
keyRing = keyOperations.changeSecretKeyPassphrase(keyRing,
|
||||||
oldPassPhrase, newPassPhrase);
|
oldPassPhrase, newPassPhrase);
|
||||||
setProgress(R.string.progress_saving_key_ring, 50, 100);
|
setProgress(R.string.progress_saving_key_ring, 50, 100);
|
||||||
@ -487,8 +486,8 @@ public class KeychainIntentService extends IntentService
|
|||||||
setProgress(R.string.progress_done, 100, 100);
|
setProgress(R.string.progress_done, 100, 100);
|
||||||
} else {
|
} else {
|
||||||
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100));
|
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 0, 90, 100));
|
||||||
PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId);
|
PGPSecretKeyRing privkey = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
|
||||||
PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, masterKeyId);
|
PGPPublicKeyRing pubkey = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId);
|
||||||
PgpKeyOperation.Pair<PGPSecretKeyRing,PGPPublicKeyRing> pair =
|
PgpKeyOperation.Pair<PGPSecretKeyRing,PGPPublicKeyRing> pair =
|
||||||
keyOperations.buildSecretKey(privkey, pubkey, saveParams);
|
keyOperations.buildSecretKey(privkey, pubkey, saveParams);
|
||||||
setProgress(R.string.progress_saving_key_ring, 90, 100);
|
setProgress(R.string.progress_saving_key_ring, 90, 100);
|
||||||
@ -639,8 +638,9 @@ public class KeychainIntentService extends IntentService
|
|||||||
|
|
||||||
ArrayList<Long> publicMasterKeyIds = new ArrayList<Long>();
|
ArrayList<Long> publicMasterKeyIds = new ArrayList<Long>();
|
||||||
ArrayList<Long> secretMasterKeyIds = new ArrayList<Long>();
|
ArrayList<Long> secretMasterKeyIds = new ArrayList<Long>();
|
||||||
ArrayList<Long> allPublicMasterKeyIds = ProviderHelper.getPublicKeyRingsMasterKeyIds(this);
|
// TODO redo
|
||||||
ArrayList<Long> allSecretMasterKeyIds = ProviderHelper.getSecretKeyRingsMasterKeyIds(this);
|
ArrayList<Long> allPublicMasterKeyIds = null; // ProviderHelper.getPublicKeyRingsMasterKeyIds(this);
|
||||||
|
ArrayList<Long> allSecretMasterKeyIds = null; // ProviderHelper.getSecretKeyRingsMasterKeyIds(this);
|
||||||
|
|
||||||
if (exportAll) {
|
if (exportAll) {
|
||||||
// get all public key ring MasterKey ids
|
// get all public key ring MasterKey ids
|
||||||
@ -790,8 +790,7 @@ public class KeychainIntentService extends IntentService
|
|||||||
}
|
}
|
||||||
|
|
||||||
PgpKeyOperation keyOperation = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100));
|
PgpKeyOperation keyOperation = new PgpKeyOperation(new ProgressScaler(this, 0, 100, 100));
|
||||||
PGPPublicKeyRing publicRing = ProviderHelper
|
PGPPublicKeyRing publicRing = ProviderHelper.getPGPPublicKeyRing(this, pubKeyId);
|
||||||
.getPGPPublicKeyRingByKeyId(this, pubKeyId);
|
|
||||||
PGPPublicKey publicKey = publicRing.getPublicKey(pubKeyId);
|
PGPPublicKey publicKey = publicRing.getPublicKey(pubKeyId);
|
||||||
PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(this,
|
PGPSecretKey certificationKey = PgpKeyHelper.getCertificationKey(this,
|
||||||
masterKeyId);
|
masterKeyId);
|
||||||
|
@ -161,7 +161,7 @@ public class PassphraseCacheService extends Service {
|
|||||||
// try to get master key id which is used as an identifier for cached passphrases
|
// try to get master key id which is used as an identifier for cached passphrases
|
||||||
long masterKeyId = keyId;
|
long masterKeyId = keyId;
|
||||||
if (masterKeyId != Id.key.symmetric) {
|
if (masterKeyId != Id.key.symmetric) {
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(this, keyId);
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(this, keyId);
|
||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -202,8 +202,7 @@ public class PassphraseCacheService extends Service {
|
|||||||
public static boolean hasPassphrase(Context context, long secretKeyId) {
|
public static boolean hasPassphrase(Context context, long secretKeyId) {
|
||||||
// check if the key has no passphrase
|
// check if the key has no passphrase
|
||||||
try {
|
try {
|
||||||
PGPSecretKeyRing secRing = ProviderHelper
|
PGPSecretKeyRing secRing = ProviderHelper.getPGPSecretKeyRing(context, secretKeyId);
|
||||||
.getPGPSecretKeyRingByKeyId(context, secretKeyId);
|
|
||||||
PGPSecretKey secretKey = null;
|
PGPSecretKey secretKey = null;
|
||||||
boolean foundValidKey = false;
|
boolean foundValidKey = false;
|
||||||
for (Iterator keys = secRing.getSecretKeys(); keys.hasNext(); ) {
|
for (Iterator keys = secRing.getSecretKeys(); keys.hasNext(); ) {
|
||||||
|
@ -139,8 +139,6 @@ public class CertifyKeyActivity extends ActionBarActivity implements
|
|||||||
}
|
}
|
||||||
Log.e(Constants.TAG, "uri: " + mDataUri);
|
Log.e(Constants.TAG, "uri: " + mDataUri);
|
||||||
|
|
||||||
PGPPublicKeyRing signKey = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, mDataUri);
|
|
||||||
|
|
||||||
mUserIds = (ListView) findViewById(R.id.user_ids);
|
mUserIds = (ListView) findViewById(R.id.user_ids);
|
||||||
|
|
||||||
mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0, true);
|
mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0, true);
|
||||||
@ -149,20 +147,12 @@ public class CertifyKeyActivity extends ActionBarActivity implements
|
|||||||
getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
|
getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
|
||||||
getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
|
getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
|
||||||
|
|
||||||
if (signKey != null) {
|
|
||||||
mPubKeyId = PgpKeyHelper.getMasterKey(signKey).getKeyID();
|
|
||||||
}
|
|
||||||
if (mPubKeyId == 0) {
|
|
||||||
Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!");
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static final String[] KEYRING_PROJECTION =
|
static final String[] KEYRING_PROJECTION =
|
||||||
new String[] {
|
new String[] {
|
||||||
KeychainContract.KeyRings._ID,
|
KeychainContract.KeyRings._ID,
|
||||||
KeychainContract.KeyRings.MASTER_KEY_ID,
|
KeychainContract.Keys.MASTER_KEY_ID,
|
||||||
KeychainContract.Keys.FINGERPRINT,
|
KeychainContract.Keys.FINGERPRINT,
|
||||||
KeychainContract.UserIds.USER_ID
|
KeychainContract.UserIds.USER_ID
|
||||||
};
|
};
|
||||||
@ -182,11 +172,13 @@ public class CertifyKeyActivity extends ActionBarActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case LOADER_ID_KEYRING:
|
case LOADER_ID_KEYRING: {
|
||||||
return new CursorLoader(this, mDataUri, KEYRING_PROJECTION, null, null, null);
|
Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
|
||||||
|
return new CursorLoader(this, uri, KEYRING_PROJECTION, null, null, null);
|
||||||
|
}
|
||||||
case LOADER_ID_USER_IDS: {
|
case LOADER_ID_USER_IDS: {
|
||||||
Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
|
Uri uri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
|
||||||
return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, null, null, USER_IDS_SORT_ORDER);
|
return new CursorLoader(this, uri, USER_IDS_PROJECTION, null, null, USER_IDS_SORT_ORDER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -199,19 +191,14 @@ public class CertifyKeyActivity extends ActionBarActivity implements
|
|||||||
// the first key here is our master key
|
// the first key here is our master key
|
||||||
if (data.moveToFirst()) {
|
if (data.moveToFirst()) {
|
||||||
// TODO: put findViewById in onCreate!
|
// TODO: put findViewById in onCreate!
|
||||||
|
mPubKeyId = data.getLong(INDEX_MASTER_KEY_ID);
|
||||||
long keyId = data.getLong(INDEX_MASTER_KEY_ID);
|
String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(mPubKeyId);
|
||||||
String keyIdStr = PgpKeyHelper.convertKeyIdToHexShort(keyId);
|
|
||||||
((TextView) findViewById(R.id.key_id)).setText(keyIdStr);
|
((TextView) findViewById(R.id.key_id)).setText(keyIdStr);
|
||||||
|
|
||||||
String mainUserId = data.getString(INDEX_USER_ID);
|
String mainUserId = data.getString(INDEX_USER_ID);
|
||||||
((TextView) findViewById(R.id.main_user_id)).setText(mainUserId);
|
((TextView) findViewById(R.id.main_user_id)).setText(mainUserId);
|
||||||
|
|
||||||
byte[] fingerprintBlob = data.getBlob(INDEX_FINGERPRINT);
|
byte[] fingerprintBlob = data.getBlob(INDEX_FINGERPRINT);
|
||||||
if (fingerprintBlob == null) {
|
|
||||||
// FALLBACK for old database entries
|
|
||||||
fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
|
|
||||||
}
|
|
||||||
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob);
|
||||||
((TextView) findViewById(R.id.fingerprint)).setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
|
((TextView) findViewById(R.id.fingerprint)).setText(PgpKeyHelper.colorizeFingerprint(fingerprint));
|
||||||
}
|
}
|
||||||
@ -261,7 +248,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
|
|||||||
* handles the UI bits of the signing process on the UI thread
|
* handles the UI bits of the signing process on the UI thread
|
||||||
*/
|
*/
|
||||||
private void initiateSigning() {
|
private void initiateSigning() {
|
||||||
PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, mPubKeyId);
|
PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRing(this, mPubKeyId);
|
||||||
if (pubring != null) {
|
if (pubring != null) {
|
||||||
// if we have already signed this key, dont bother doing it again
|
// if we have already signed this key, dont bother doing it again
|
||||||
boolean alreadySigned = false;
|
boolean alreadySigned = false;
|
||||||
|
@ -356,7 +356,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
|
|||||||
return true;
|
return true;
|
||||||
case R.id.menu_key_edit_delete:
|
case R.id.menu_key_edit_delete:
|
||||||
long rowId= ProviderHelper.getRowId(this,mDataUri);
|
long rowId= ProviderHelper.getRowId(this,mDataUri);
|
||||||
Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingsUri(Long.toString(rowId));
|
Uri convertUri = KeychainContract.KeyRings.buildSecretKeyRingUri(Long.toString(rowId));
|
||||||
// Message is received after key is deleted
|
// Message is received after key is deleted
|
||||||
Handler returnHandler = new Handler() {
|
Handler returnHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
@ -380,7 +380,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
|
|||||||
private void finallyEdit(final long masterKeyId) {
|
private void finallyEdit(final long masterKeyId) {
|
||||||
if (masterKeyId != 0) {
|
if (masterKeyId != 0) {
|
||||||
PGPSecretKey masterKey = null;
|
PGPSecretKey masterKey = null;
|
||||||
mKeyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, masterKeyId);
|
mKeyRing = ProviderHelper.getPGPSecretKeyRing(this, masterKeyId);
|
||||||
if (mKeyRing != null) {
|
if (mKeyRing != null) {
|
||||||
masterKey = PgpKeyHelper.getMasterKey(mKeyRing);
|
masterKey = PgpKeyHelper.getMasterKey(mKeyRing);
|
||||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(mKeyRing.getSecretKeys())) {
|
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(mKeyRing.getSecretKeys())) {
|
||||||
|
@ -141,7 +141,7 @@ public class EncryptAsymmetricFragment extends Fragment {
|
|||||||
private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) {
|
private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) {
|
||||||
if (preselectedSignatureKeyId != 0) {
|
if (preselectedSignatureKeyId != 0) {
|
||||||
// TODO: don't use bouncy castle objects!
|
// TODO: don't use bouncy castle objects!
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(),
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(),
|
||||||
preselectedSignatureKeyId);
|
preselectedSignatureKeyId);
|
||||||
PGPSecretKey masterKey;
|
PGPSecretKey masterKey;
|
||||||
if (keyRing != null) {
|
if (keyRing != null) {
|
||||||
@ -160,7 +160,7 @@ public class EncryptAsymmetricFragment extends Fragment {
|
|||||||
for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) {
|
for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) {
|
||||||
// TODO: don't use bouncy castle objects!
|
// TODO: don't use bouncy castle objects!
|
||||||
|
|
||||||
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(getActivity(),
|
PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingWithKeyId(getActivity(),
|
||||||
preselectedEncryptionKeyIds[i]);
|
preselectedEncryptionKeyIds[i]);
|
||||||
PGPPublicKey masterKey;
|
PGPPublicKey masterKey;
|
||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
@ -203,7 +203,7 @@ public class EncryptAsymmetricFragment extends Fragment {
|
|||||||
String uid = getResources().getString(R.string.user_id_no_name);
|
String uid = getResources().getString(R.string.user_id_no_name);
|
||||||
String uidExtra = "";
|
String uidExtra = "";
|
||||||
// TODO: don't use bouncy castle objects!
|
// TODO: don't use bouncy castle objects!
|
||||||
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(getActivity(),
|
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingWithKeyId(getActivity(),
|
||||||
mSecretKeyId);
|
mSecretKeyId);
|
||||||
if (keyRing != null) {
|
if (keyRing != null) {
|
||||||
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
|
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
|
||||||
|
@ -186,6 +186,7 @@ public class KeyListFragment extends Fragment
|
|||||||
case R.id.menu_key_list_multi_export: {
|
case R.id.menu_key_list_multi_export: {
|
||||||
ids = mStickyList.getWrappedList().getCheckedItemIds();
|
ids = mStickyList.getWrappedList().getCheckedItemIds();
|
||||||
long[] masterKeyIds = new long[2*ids.length];
|
long[] masterKeyIds = new long[2*ids.length];
|
||||||
|
/* TODO! redo
|
||||||
ArrayList<Long> allPubRowIds =
|
ArrayList<Long> allPubRowIds =
|
||||||
ProviderHelper.getPublicKeyRingsRowIds(getActivity());
|
ProviderHelper.getPublicKeyRingsRowIds(getActivity());
|
||||||
for (int i = 0; i < ids.length; i++) {
|
for (int i = 0; i < ids.length; i++) {
|
||||||
@ -194,7 +195,7 @@ public class KeyListFragment extends Fragment
|
|||||||
} else {
|
} else {
|
||||||
masterKeyIds[i] = ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]);
|
masterKeyIds[i] = ProviderHelper.getSecretMasterKeyId(getActivity(), ids[i]);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
|
ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
|
||||||
mExportHelper
|
mExportHelper
|
||||||
.showExportKeysDialog(masterKeyIds, Id.type.public_key,
|
.showExportKeysDialog(masterKeyIds, Id.type.public_key,
|
||||||
@ -254,22 +255,22 @@ public class KeyListFragment extends Fragment
|
|||||||
// These are the rows that we will retrieve.
|
// These are the rows that we will retrieve.
|
||||||
static final String[] PROJECTION = new String[]{
|
static final String[] PROJECTION = new String[]{
|
||||||
KeychainContract.KeyRings._ID,
|
KeychainContract.KeyRings._ID,
|
||||||
KeychainContract.KeyRings.TYPE,
|
KeychainContract.Keys.MASTER_KEY_ID,
|
||||||
KeychainContract.KeyRings.MASTER_KEY_ID,
|
|
||||||
KeychainContract.UserIds.USER_ID,
|
KeychainContract.UserIds.USER_ID,
|
||||||
KeychainContract.Keys.IS_REVOKED
|
KeychainContract.Keys.IS_REVOKED,
|
||||||
|
KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID
|
||||||
};
|
};
|
||||||
|
|
||||||
static final int INDEX_TYPE = 1;
|
static final int INDEX_MASTER_KEY_ID = 1;
|
||||||
static final int INDEX_MASTER_KEY_ID = 2;
|
static final int INDEX_USER_ID = 2;
|
||||||
static final int INDEX_USER_ID = 3;
|
static final int INDEX_IS_REVOKED = 3;
|
||||||
static final int INDEX_IS_REVOKED = 4;
|
static final int INDEX_HAS_SECRET = 4;
|
||||||
|
|
||||||
static final String SORT_ORDER =
|
static final String SORT_ORDER =
|
||||||
// show secret before public key
|
// show secret before public key
|
||||||
KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings.TYPE + " DESC, "
|
KeychainDatabase.Tables.KEY_RINGS_SECRET + "." + KeychainContract.KeyRings.MASTER_KEY_ID + " IS NULL ASC, " +
|
||||||
// sort by user id otherwise
|
// sort by user id otherwise
|
||||||
+ UserIds.USER_ID + " ASC";
|
UserIds.USER_ID + " ASC";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
@ -326,7 +327,7 @@ public class KeyListFragment extends Fragment
|
|||||||
}
|
}
|
||||||
viewIntent.setData(
|
viewIntent.setData(
|
||||||
KeychainContract
|
KeychainContract
|
||||||
.KeyRings.buildPublicKeyRingsByMasterKeyIdUri(
|
.KeyRings.buildPublicKeyRingUri(
|
||||||
Long.toString(mAdapter.getMasterKeyId(position))));
|
Long.toString(mAdapter.getMasterKeyId(position))));
|
||||||
startActivity(viewIntent);
|
startActivity(viewIntent);
|
||||||
}
|
}
|
||||||
@ -503,7 +504,7 @@ public class KeyListFragment extends Fragment
|
|||||||
Button button = (Button) view.findViewById(R.id.edit);
|
Button button = (Button) view.findViewById(R.id.edit);
|
||||||
TextView revoked = (TextView) view.findViewById(R.id.revoked);
|
TextView revoked = (TextView) view.findViewById(R.id.revoked);
|
||||||
|
|
||||||
if (cursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) {
|
if (!cursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) {
|
||||||
// this is a secret key - show the edit button
|
// this is a secret key - show the edit button
|
||||||
statusDivider.setVisibility(View.VISIBLE);
|
statusDivider.setVisibility(View.VISIBLE);
|
||||||
statusLayout.setVisibility(View.VISIBLE);
|
statusLayout.setVisibility(View.VISIBLE);
|
||||||
@ -516,7 +517,7 @@ public class KeyListFragment extends Fragment
|
|||||||
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
|
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
|
||||||
editIntent.setData(
|
editIntent.setData(
|
||||||
KeychainContract.KeyRings
|
KeychainContract.KeyRings
|
||||||
.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(id)));
|
.buildSecretKeyRingUri(Long.toString(id)));
|
||||||
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
|
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
|
||||||
startActivityForResult(editIntent, 0);
|
startActivityForResult(editIntent, 0);
|
||||||
}
|
}
|
||||||
@ -577,7 +578,7 @@ public class KeyListFragment extends Fragment
|
|||||||
throw new IllegalStateException("couldn't move cursor to position " + position);
|
throw new IllegalStateException("couldn't move cursor to position " + position);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) {
|
if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) {
|
||||||
{ // set contact count
|
{ // set contact count
|
||||||
int num = mCursor.getCount();
|
int num = mCursor.getCount();
|
||||||
String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num);
|
String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num);
|
||||||
@ -617,7 +618,7 @@ public class KeyListFragment extends Fragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
// early breakout: all secret keys are assigned id 0
|
// early breakout: all secret keys are assigned id 0
|
||||||
if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) {
|
if (!mCursor.isNull(KeyListFragment.INDEX_HAS_SECRET)) {
|
||||||
return 1L;
|
return 1L;
|
||||||
}
|
}
|
||||||
// otherwise, return the first character of the name as ID
|
// otherwise, return the first character of the name as ID
|
||||||
|
@ -248,9 +248,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
// This is called when a new Loader needs to be created. This
|
Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
|
||||||
// sample only has one Loader, so we don't care about the ID.
|
|
||||||
Uri baseUri = KeyRings.buildPublicKeyRingsUri();
|
|
||||||
|
|
||||||
// These are the rows that we will retrieve.
|
// These are the rows that we will retrieve.
|
||||||
long now = new Date().getTime() / 1000;
|
long now = new Date().getTime() / 1000;
|
||||||
@ -258,24 +256,24 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
|
|||||||
KeyRings._ID,
|
KeyRings._ID,
|
||||||
KeyRings.MASTER_KEY_ID,
|
KeyRings.MASTER_KEY_ID,
|
||||||
UserIds.USER_ID,
|
UserIds.USER_ID,
|
||||||
"(SELECT COUNT(available_keys." + Keys._ID + ") FROM " + Tables.KEYS
|
"(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
|
||||||
+ " AS available_keys WHERE available_keys." + Keys.KEY_RING_ROW_ID + " = "
|
+" WHERE k." + Keys.MASTER_KEY_ID + " = "
|
||||||
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
|
+ KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
|
||||||
+ " AND available_keys." + Keys.IS_REVOKED + " = '0' AND available_keys."
|
+ " AND k." + Keys.IS_REVOKED + " = '0'"
|
||||||
+ Keys.CAN_ENCRYPT + " = '1') AS "
|
+ " AND k." + Keys.CAN_ENCRYPT + " = '1'"
|
||||||
+ SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
|
+ ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
|
||||||
"(SELECT COUNT(valid_keys." + Keys._ID + ") FROM " + Tables.KEYS
|
"(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
|
||||||
+ " AS valid_keys WHERE valid_keys." + Keys.KEY_RING_ROW_ID + " = "
|
+ " WHERE k." + Keys.MASTER_KEY_ID + " = "
|
||||||
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
|
+ KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
|
||||||
+ " AND valid_keys." + Keys.IS_REVOKED + " = '0' AND valid_keys."
|
+ " AND k." + Keys.IS_REVOKED + " = '0'"
|
||||||
+ Keys.CAN_ENCRYPT + " = '1' AND valid_keys." + Keys.CREATION + " <= '"
|
+ " AND k." + Keys.CAN_ENCRYPT + " = '1'"
|
||||||
+ now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys."
|
+ " AND k." + Keys.CREATION + " <= '" + now + "'"
|
||||||
+ Keys.EXPIRY + " >= '" + now + "')) AS "
|
+ " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY + " >= '" + now + "' )"
|
||||||
+ SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
|
+ ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
|
||||||
|
|
||||||
String inMasterKeyList = null;
|
String inMasterKeyList = null;
|
||||||
if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) {
|
if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) {
|
||||||
inMasterKeyList = KeyRings.MASTER_KEY_ID + " IN (";
|
inMasterKeyList = Tables.KEYS + "." + KeyRings.MASTER_KEY_ID + " IN (";
|
||||||
for (int i = 0; i < mSelectedMasterKeyIds.length; ++i) {
|
for (int i = 0; i < mSelectedMasterKeyIds.length; ++i) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
inMasterKeyList += ", ";
|
inMasterKeyList += ", ";
|
||||||
|
@ -85,7 +85,7 @@ public class SelectSecretKeyFragment extends ListFragment implements
|
|||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
|
||||||
long masterKeyId = mAdapter.getMasterKeyId(position);
|
long masterKeyId = mAdapter.getMasterKeyId(position);
|
||||||
Uri result = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId));
|
Uri result = KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId));
|
||||||
|
|
||||||
// return data to activity, which results in finishing it
|
// return data to activity, which results in finishing it
|
||||||
mActivity.afterListSelection(result);
|
mActivity.afterListSelection(result);
|
||||||
@ -112,12 +112,7 @@ public class SelectSecretKeyFragment extends ListFragment implements
|
|||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
// This is called when a new Loader needs to be created. This
|
// This is called when a new Loader needs to be created. This
|
||||||
// sample only has one Loader, so we don't care about the ID.
|
// sample only has one Loader, so we don't care about the ID.
|
||||||
Uri baseUri = KeyRings.buildSecretKeyRingsUri();
|
Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
|
||||||
|
|
||||||
String capFilter = null;
|
|
||||||
if (mFilterCertify) {
|
|
||||||
capFilter = "(cert > 0)";
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are the rows that we will retrieve.
|
// These are the rows that we will retrieve.
|
||||||
long now = new Date().getTime() / 1000;
|
long now = new Date().getTime() / 1000;
|
||||||
@ -125,29 +120,36 @@ public class SelectSecretKeyFragment extends ListFragment implements
|
|||||||
KeyRings._ID,
|
KeyRings._ID,
|
||||||
KeyRings.MASTER_KEY_ID,
|
KeyRings.MASTER_KEY_ID,
|
||||||
UserIds.USER_ID,
|
UserIds.USER_ID,
|
||||||
"(SELECT COUNT(cert_keys." + Keys._ID + ") FROM " + Tables.KEYS
|
"(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
|
||||||
+ " AS cert_keys WHERE cert_keys." + Keys.KEY_RING_ROW_ID + " = "
|
+ " WHERE k." + Keys.MASTER_KEY_ID + " = "
|
||||||
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND cert_keys."
|
+ KeychainDatabase.Tables.KEYS + "." + KeyRings.MASTER_KEY_ID
|
||||||
+ Keys.CAN_CERTIFY + " = '1') AS cert",
|
+ " AND k." + Keys.CAN_CERTIFY + " = '1'"
|
||||||
"(SELECT COUNT(available_keys." + Keys._ID + ") FROM " + Tables.KEYS
|
+ ") AS cert",
|
||||||
+ " AS available_keys WHERE available_keys." + Keys.KEY_RING_ROW_ID + " = "
|
"(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
|
||||||
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID
|
+" WHERE k." + Keys.MASTER_KEY_ID + " = "
|
||||||
+ " AND available_keys." + Keys.IS_REVOKED + " = '0' AND available_keys."
|
+ KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
|
||||||
+ Keys.CAN_SIGN + " = '1') AS "
|
+ " AND k." + Keys.IS_REVOKED + " = '0'"
|
||||||
+ SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
|
+ " AND k." + Keys.CAN_SIGN + " = '1'"
|
||||||
"(SELECT COUNT(valid_keys." + Keys._ID + ") FROM " + Tables.KEYS
|
+ ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_AVAILABLE,
|
||||||
+ " AS valid_keys WHERE valid_keys." + Keys.KEY_RING_ROW_ID + " = "
|
"(SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
|
||||||
+ KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings._ID + " AND valid_keys."
|
+ " WHERE k." + Keys.MASTER_KEY_ID + " = "
|
||||||
+ Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_SIGN
|
+ KeychainDatabase.Tables.KEYS + "." + Keys.MASTER_KEY_ID
|
||||||
+ " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND "
|
+ " AND k." + Keys.IS_REVOKED + " = '0'"
|
||||||
+ "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY
|
+ " AND k." + Keys.CAN_SIGN + " = '1'"
|
||||||
+ " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID,};
|
+ " AND k." + Keys.CREATION + " <= '" + now + "'"
|
||||||
|
+ " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY + " >= '" + now + "' )"
|
||||||
|
+ ") AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
|
||||||
|
|
||||||
String orderBy = UserIds.USER_ID + " ASC";
|
String orderBy = UserIds.USER_ID + " ASC";
|
||||||
|
|
||||||
|
String where = Tables.KEY_RINGS_SECRET + "." + KeyRings.MASTER_KEY_ID + " IS NOT NULL";
|
||||||
|
if (mFilterCertify) {
|
||||||
|
where += " AND (cert > 0)";
|
||||||
|
}
|
||||||
|
|
||||||
// Now create and return a CursorLoader that will take care of
|
// Now create and return a CursorLoader that will take care of
|
||||||
// creating a Cursor for the data being displayed.
|
// creating a Cursor for the data being displayed.
|
||||||
return new CursorLoader(getActivity(), baseUri, projection, capFilter, null, orderBy);
|
return new CursorLoader(getActivity(), baseUri, projection, where, null, orderBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,10 +57,12 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan
|
|||||||
|
|
||||||
//The Projection we will retrieve, Master Key ID is for convenience sake,
|
//The Projection we will retrieve, Master Key ID is for convenience sake,
|
||||||
//to avoid having to pass the Key Around
|
//to avoid having to pass the Key Around
|
||||||
final String[] PROJECTION = new String[]{KeychainContract.UserIds.USER_ID
|
final String[] PROJECTION = new String[] {
|
||||||
, KeychainContract.KeyRings.MASTER_KEY_ID};
|
KeychainContract.Keys.MASTER_KEY_ID,
|
||||||
final int INDEX_USER_ID = 0;
|
KeychainContract.UserIds.USER_ID
|
||||||
final int INDEX_MASTER_KEY_ID = 1;
|
};
|
||||||
|
final int INDEX_MASTER_KEY_ID = 0;
|
||||||
|
final int INDEX_USER_ID = 1;
|
||||||
|
|
||||||
public interface SelectSecretKeyCallback {
|
public interface SelectSecretKeyCallback {
|
||||||
void onKeySelected(long secretKeyId);
|
void onKeySelected(long secretKeyId);
|
||||||
@ -126,7 +128,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan
|
|||||||
|
|
||||||
//For AppSettingsFragment
|
//For AppSettingsFragment
|
||||||
public void selectKey(long masterKeyId) {
|
public void selectKey(long masterKeyId) {
|
||||||
Uri buildUri = KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId));
|
Uri buildUri = KeychainContract.KeyRings.buildGenericKeyRingUri(String.valueOf(masterKeyId));
|
||||||
mReceivedUri = buildUri;
|
mReceivedUri = buildUri;
|
||||||
getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
|
getActivity().getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
|
||||||
}
|
}
|
||||||
@ -139,8 +141,9 @@ public class SelectSecretKeyLayoutFragment extends Fragment implements LoaderMan
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
|
Uri uri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mReceivedUri);
|
||||||
//We don't care about the Loader id
|
//We don't care about the Loader id
|
||||||
return new CursorLoader(getActivity(), mReceivedUri, PROJECTION, null, null, null);
|
return new CursorLoader(getActivity(), uri, PROJECTION, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,13 +83,7 @@ public class ViewKeyActivity extends ActionBarActivity {
|
|||||||
selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
|
selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
mDataUri = getIntent().getData();
|
||||||
// normalize mDataUri to a "by row id" query, to ensure it works with any
|
|
||||||
// given valid /public/ query
|
|
||||||
long rowId = ProviderHelper.getRowId(this, getIntent().getData());
|
|
||||||
// TODO: handle (rowId == 0) with something else than a crash
|
|
||||||
mDataUri = KeychainContract.KeyRings.buildPublicKeyRingsUri(Long.toString(rowId));
|
|
||||||
}
|
|
||||||
|
|
||||||
Bundle mainBundle = new Bundle();
|
Bundle mainBundle = new Bundle();
|
||||||
mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
|
mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
|
||||||
@ -124,8 +118,7 @@ public class ViewKeyActivity extends ActionBarActivity {
|
|||||||
uploadToKeyserver(mDataUri);
|
uploadToKeyserver(mDataUri);
|
||||||
return true;
|
return true;
|
||||||
case R.id.menu_key_view_export_file:
|
case R.id.menu_key_view_export_file:
|
||||||
long masterKeyId =
|
long masterKeyId = Long.valueOf(mDataUri.getLastPathSegment());
|
||||||
ProviderHelper.getPublicMasterKeyId(this, Long.valueOf(mDataUri.getLastPathSegment()));
|
|
||||||
long[] ids = new long[]{masterKeyId};
|
long[] ids = new long[]{masterKeyId};
|
||||||
mExportHelper.showExportKeysDialog(ids, Id.type.public_key,
|
mExportHelper.showExportKeysDialog(ids, Id.type.public_key,
|
||||||
Constants.Path.APP_DIR_FILE_PUB, null);
|
Constants.Path.APP_DIR_FILE_PUB, null);
|
||||||
|
@ -69,7 +69,6 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
private ListView mUserIds;
|
private ListView mUserIds;
|
||||||
private ListView mKeys;
|
private ListView mKeys;
|
||||||
|
|
||||||
private static final int LOADER_ID_KEYRING = 0;
|
|
||||||
private static final int LOADER_ID_USER_IDS = 1;
|
private static final int LOADER_ID_USER_IDS = 1;
|
||||||
private static final int LOADER_ID_KEYS = 2;
|
private static final int LOADER_ID_KEYS = 2;
|
||||||
|
|
||||||
@ -144,7 +143,7 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
|
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
|
||||||
editIntent.setData(
|
editIntent.setData(
|
||||||
KeychainContract
|
KeychainContract
|
||||||
.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(
|
.KeyRings.buildSecretKeyRingUri(
|
||||||
Long.toString(masterKeyId)));
|
Long.toString(masterKeyId)));
|
||||||
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
|
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
|
||||||
startActivityForResult(editIntent, 0);
|
startActivityForResult(editIntent, 0);
|
||||||
@ -163,7 +162,7 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
// TODO see todo note above, doing this here for now
|
// TODO see todo note above, doing this here for now
|
||||||
mActionCertify.setOnClickListener(new View.OnClickListener() {
|
mActionCertify.setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
certifyKey(KeychainContract.KeyRings.buildPublicKeyRingsByMasterKeyIdUri(
|
certifyKey(KeychainContract.KeyRings.buildGenericKeyRingUri(
|
||||||
Long.toString(masterKeyId)
|
Long.toString(masterKeyId)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -187,39 +186,31 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
|
|
||||||
// Prepare the loaders. Either re-connect with an existing ones,
|
// Prepare the loaders. Either re-connect with an existing ones,
|
||||||
// or start new ones.
|
// or start new ones.
|
||||||
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
|
|
||||||
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
|
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
|
||||||
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
|
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final String[] KEYRING_PROJECTION =
|
|
||||||
new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID,
|
|
||||||
KeychainContract.UserIds.USER_ID};
|
|
||||||
static final int KEYRING_INDEX_ID = 0;
|
|
||||||
static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
|
|
||||||
static final int KEYRING_INDEX_USER_ID = 2;
|
|
||||||
|
|
||||||
static final String[] USER_IDS_PROJECTION =
|
static final String[] USER_IDS_PROJECTION =
|
||||||
new String[]{
|
new String[]{
|
||||||
KeychainContract.UserIds._ID,
|
KeychainContract.UserIds._ID,
|
||||||
KeychainContract.UserIds.USER_ID,
|
KeychainContract.UserIds.USER_ID,
|
||||||
KeychainContract.UserIds.RANK,
|
KeychainContract.UserIds.RANK,
|
||||||
};
|
};
|
||||||
|
static final int INDEX_UID_UID = 1;
|
||||||
static final String USER_IDS_SORT_ORDER =
|
static final String USER_IDS_SORT_ORDER =
|
||||||
KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC";
|
KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC";
|
||||||
|
|
||||||
static final String[] KEYS_PROJECTION =
|
static final String[] KEYS_PROJECTION =
|
||||||
new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
|
new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
|
||||||
KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM,
|
KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.RANK,
|
||||||
KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY,
|
KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY,
|
||||||
KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT,
|
KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT,
|
||||||
KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION,
|
KeychainContract.Keys.IS_REVOKED, KeychainContract.Keys.CREATION,
|
||||||
KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT};
|
KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT};
|
||||||
static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC";
|
static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC";
|
||||||
static final int KEYS_INDEX_ID = 0;
|
|
||||||
static final int KEYS_INDEX_KEY_ID = 1;
|
static final int KEYS_INDEX_KEY_ID = 1;
|
||||||
static final int KEYS_INDEX_IS_MASTER_KEY = 2;
|
static final int KEYS_INDEX_ALGORITHM = 2;
|
||||||
static final int KEYS_INDEX_ALGORITHM = 3;
|
static final int KEYS_INDEX_RANK = 3;
|
||||||
static final int KEYS_INDEX_KEY_SIZE = 4;
|
static final int KEYS_INDEX_KEY_SIZE = 4;
|
||||||
static final int KEYS_INDEX_CAN_CERTIFY = 5;
|
static final int KEYS_INDEX_CAN_CERTIFY = 5;
|
||||||
static final int KEYS_INDEX_CAN_SIGN = 6;
|
static final int KEYS_INDEX_CAN_SIGN = 6;
|
||||||
@ -231,13 +222,6 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
|
|
||||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case LOADER_ID_KEYRING: {
|
|
||||||
Uri baseUri = mDataUri;
|
|
||||||
|
|
||||||
// Now create and return a CursorLoader that will take care of
|
|
||||||
// creating a Cursor for the data being displayed.
|
|
||||||
return new CursorLoader(getActivity(), baseUri, KEYRING_PROJECTION, null, null, null);
|
|
||||||
}
|
|
||||||
case LOADER_ID_USER_IDS: {
|
case LOADER_ID_USER_IDS: {
|
||||||
Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
|
Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
|
||||||
|
|
||||||
@ -263,11 +247,11 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
// Swap the new cursor in. (The framework will take care of closing the
|
// Swap the new cursor in. (The framework will take care of closing the
|
||||||
// old cursor once we return.)
|
// old cursor once we return.)
|
||||||
switch (loader.getId()) {
|
switch (loader.getId()) {
|
||||||
case LOADER_ID_KEYRING:
|
case LOADER_ID_USER_IDS:
|
||||||
if (data.moveToFirst()) {
|
if (data.moveToFirst()) {
|
||||||
// get name, email, and comment from USER_ID
|
// get name, email, and comment from USER_ID
|
||||||
String[] mainUserId = PgpKeyHelper.splitUserId(data
|
String[] mainUserId = PgpKeyHelper.splitUserId(data
|
||||||
.getString(KEYRING_INDEX_USER_ID));
|
.getString(INDEX_UID_UID));
|
||||||
if (mainUserId[0] != null) {
|
if (mainUserId[0] != null) {
|
||||||
getActivity().setTitle(mainUserId[0]);
|
getActivity().setTitle(mainUserId[0]);
|
||||||
mName.setText(mainUserId[0]);
|
mName.setText(mainUserId[0]);
|
||||||
@ -278,9 +262,6 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
mEmail.setText(mainUserId[1]);
|
mEmail.setText(mainUserId[1]);
|
||||||
mComment.setText(mainUserId[2]);
|
mComment.setText(mainUserId[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
case LOADER_ID_USER_IDS:
|
|
||||||
mUserIdsAdapter.swapCursor(data);
|
mUserIdsAdapter.swapCursor(data);
|
||||||
break;
|
break;
|
||||||
case LOADER_ID_KEYS:
|
case LOADER_ID_KEYS:
|
||||||
@ -354,9 +335,6 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
*/
|
*/
|
||||||
public void onLoaderReset(Loader<Cursor> loader) {
|
public void onLoaderReset(Loader<Cursor> loader) {
|
||||||
switch (loader.getId()) {
|
switch (loader.getId()) {
|
||||||
case LOADER_ID_KEYRING:
|
|
||||||
// No resources need to be freed for this ID
|
|
||||||
break;
|
|
||||||
case LOADER_ID_USER_IDS:
|
case LOADER_ID_USER_IDS:
|
||||||
mUserIdsAdapter.swapCursor(null);
|
mUserIdsAdapter.swapCursor(null);
|
||||||
break;
|
break;
|
||||||
@ -368,11 +346,11 @@ public class ViewKeyMainFragment extends Fragment implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void encryptToContact(Uri dataUri) {
|
private void encryptToContact(Uri dataUri) {
|
||||||
long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
|
// TODO preselect from uri? should be feasible without trivial query
|
||||||
|
long keyId = Long.parseLong(dataUri.getPathSegments().get(1));
|
||||||
|
|
||||||
long[] encryptionKeyIds = new long[]{keyId};
|
long[] encryptionKeyIds = new long[]{ keyId };
|
||||||
Intent intent = new Intent(getActivity(), EncryptActivity.class);
|
Intent intent = new Intent(getActivity(), EncryptActivity.class);
|
||||||
intent.setAction(EncryptActivity.ACTION_ENCRYPT);
|
intent.setAction(EncryptActivity.ACTION_ENCRYPT);
|
||||||
intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
|
intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
|
||||||
|
@ -41,7 +41,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
|
|||||||
private int mIndexKeyId;
|
private int mIndexKeyId;
|
||||||
private int mIndexAlgorithm;
|
private int mIndexAlgorithm;
|
||||||
private int mIndexKeySize;
|
private int mIndexKeySize;
|
||||||
private int mIndexIsMasterKey;
|
private int mIndexRank;
|
||||||
private int mIndexCanCertify;
|
private int mIndexCanCertify;
|
||||||
private int mIndexCanEncrypt;
|
private int mIndexCanEncrypt;
|
||||||
private int mIndexCanSign;
|
private int mIndexCanSign;
|
||||||
@ -76,7 +76,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
|
|||||||
mIndexKeyId = cursor.getColumnIndexOrThrow(Keys.KEY_ID);
|
mIndexKeyId = cursor.getColumnIndexOrThrow(Keys.KEY_ID);
|
||||||
mIndexAlgorithm = cursor.getColumnIndexOrThrow(Keys.ALGORITHM);
|
mIndexAlgorithm = cursor.getColumnIndexOrThrow(Keys.ALGORITHM);
|
||||||
mIndexKeySize = cursor.getColumnIndexOrThrow(Keys.KEY_SIZE);
|
mIndexKeySize = cursor.getColumnIndexOrThrow(Keys.KEY_SIZE);
|
||||||
mIndexIsMasterKey = cursor.getColumnIndexOrThrow(Keys.IS_MASTER_KEY);
|
mIndexRank = cursor.getColumnIndexOrThrow(Keys.RANK);
|
||||||
mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY);
|
mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY);
|
||||||
mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT);
|
mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT);
|
||||||
mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN);
|
mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN);
|
||||||
@ -103,7 +103,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
|
|||||||
keyId.setText(keyIdStr);
|
keyId.setText(keyIdStr);
|
||||||
keyDetails.setText("(" + algorithmStr + ")");
|
keyDetails.setText("(" + algorithmStr + ")");
|
||||||
|
|
||||||
if (cursor.getInt(mIndexIsMasterKey) != 1) {
|
if (cursor.getInt(mIndexRank) == 0) {
|
||||||
masterKeyIcon.setVisibility(View.INVISIBLE);
|
masterKeyIcon.setVisibility(View.INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
masterKeyIcon.setVisibility(View.VISIBLE);
|
masterKeyIcon.setVisibility(View.VISIBLE);
|
||||||
|
@ -98,6 +98,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
checkDeleteSecret = (CheckBox) inflateView.findViewById(R.id.checkDeleteSecret);
|
checkDeleteSecret = (CheckBox) inflateView.findViewById(R.id.checkDeleteSecret);
|
||||||
|
|
||||||
builder.setTitle(R.string.warning);
|
builder.setTitle(R.string.warning);
|
||||||
|
/* TODO! redo
|
||||||
|
|
||||||
//If only a single key has been selected
|
//If only a single key has been selected
|
||||||
if (keyRingRowIds.length == 1) {
|
if (keyRingRowIds.length == 1) {
|
||||||
@ -210,6 +211,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
|||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,10 +116,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
secretKey = null;
|
secretKey = null;
|
||||||
alert.setMessage(R.string.passphrase_for_symmetric_encryption);
|
alert.setMessage(R.string.passphrase_for_symmetric_encryption);
|
||||||
} else {
|
} else {
|
||||||
// TODO: by master key id???
|
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(activity, secretKeyId);
|
||||||
secretKey = PgpKeyHelper.getMasterKey(ProviderHelper.getPGPSecretKeyRingByKeyId(activity,
|
|
||||||
secretKeyId));
|
|
||||||
// secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
|
|
||||||
|
|
||||||
if (secretKey == null) {
|
if (secretKey == null) {
|
||||||
alert.setTitle(R.string.title_key_not_found);
|
alert.setTitle(R.string.title_key_not_found);
|
||||||
@ -175,7 +172,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
clickSecretKey = PgpKeyHelper.getKeyNum(ProviderHelper
|
clickSecretKey = PgpKeyHelper.getKeyNum(ProviderHelper
|
||||||
.getPGPSecretKeyRingByKeyId(activity, secretKeyId),
|
.getPGPSecretKeyRingWithKeyId(activity, secretKeyId),
|
||||||
curKeyIndex);
|
curKeyIndex);
|
||||||
curKeyIndex++; // does post-increment work like C?
|
curKeyIndex++; // does post-increment work like C?
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user