mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 19:22:14 -05:00
Fix layout, add API notes to README, register fingerprint URIs, some reformatting (sry)
This commit is contained in:
parent
4c8809042f
commit
5359205b50
@ -266,6 +266,20 @@
|
|||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:windowSoftInputMode="stateHidden" >
|
android:windowSoftInputMode="stateHidden" >
|
||||||
|
|
||||||
|
<!-- Handle URIs with fingerprints when scanning directly from Barcode Scanner -->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
|
<!-- Android's scheme matcher is case-sensitive, so include most likely variations -->
|
||||||
|
<data android:scheme="openpgp4fpr" />
|
||||||
|
<data android:scheme="OPENPGP4FPR" />
|
||||||
|
<data android:scheme="OpenPGP4FPR" />
|
||||||
|
<data android:scheme="OpenPGP4Fpr" />
|
||||||
|
<data android:scheme="OpenPGP4fpr" />
|
||||||
|
</intent-filter>
|
||||||
<!-- Handle NFC tags detected from outside our application -->
|
<!-- Handle NFC tags detected from outside our application -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||||
|
@ -42,17 +42,6 @@ import android.content.Context;
|
|||||||
|
|
||||||
public class PgpKeyHelper {
|
public class PgpKeyHelper {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the last 9 chars of a fingerprint
|
|
||||||
*
|
|
||||||
* @param fingerprint
|
|
||||||
* String containing short or long fingerprint
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String shortifyFingerprint(String fingerprint) {
|
|
||||||
return fingerprint.substring(41);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Date getCreationDate(PGPPublicKey key) {
|
public static Date getCreationDate(PGPPublicKey key) {
|
||||||
return key.getCreationTime();
|
return key.getCreationTime();
|
||||||
}
|
}
|
||||||
@ -175,10 +164,6 @@ public class PgpKeyHelper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isExpired(PGPSecretKey key) {
|
|
||||||
return isExpired(key.getPublicKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector<PGPSecretKey> getUsableCertificationKeys(PGPSecretKeyRing keyRing) {
|
public static Vector<PGPSecretKey> getUsableCertificationKeys(PGPSecretKeyRing keyRing) {
|
||||||
Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
|
Vector<PGPSecretKey> usableKeys = new Vector<PGPSecretKey>();
|
||||||
Vector<PGPSecretKey> signingKeys = getCertificationKeys(keyRing);
|
Vector<PGPSecretKey> signingKeys = getCertificationKeys(keyRing);
|
||||||
@ -460,12 +445,12 @@ public class PgpKeyHelper {
|
|||||||
* @param fp
|
* @param fp
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String convertFingerprintToHex(byte[] fp) {
|
public static String convertFingerprintToHex(byte[] fp, boolean chunked) {
|
||||||
String fingerPrint = "";
|
String fingerPrint = "";
|
||||||
for (int i = 0; i < fp.length; ++i) {
|
for (int i = 0; i < fp.length; ++i) {
|
||||||
if (i != 0 && i % 10 == 0) {
|
if (chunked && i != 0 && i % 10 == 0) {
|
||||||
fingerPrint += " ";
|
fingerPrint += " ";
|
||||||
} else if (i != 0 && i % 2 == 0) {
|
} else if (chunked && i != 0 && i % 2 == 0) {
|
||||||
fingerPrint += " ";
|
fingerPrint += " ";
|
||||||
}
|
}
|
||||||
String chunk = Integer.toHexString((fp[i] + 256) % 256).toUpperCase(Locale.US);
|
String chunk = Integer.toHexString((fp[i] + 256) % 256).toUpperCase(Locale.US);
|
||||||
@ -491,21 +476,21 @@ public class PgpKeyHelper {
|
|||||||
key = secretKey.getPublicKey();
|
key = secretKey.getPublicKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertFingerprintToHex(key.getFingerprint());
|
return convertFingerprintToHex(key.getFingerprint(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) {
|
public static boolean isSecretKeyPrivateEmpty(PGPSecretKey secretKey) {
|
||||||
return secretKey.isPrivateKeyEmpty();
|
return secretKey.isPrivateKeyEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSecretKeyPrivateEmpty(Context context, long keyId) {
|
// public static boolean isSecretKeyPrivateEmpty(Context context, long keyId) {
|
||||||
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
// PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, keyId);
|
||||||
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 false; // could be a public key, assume it is not empty
|
// return false; // could be a public key, assume it is not empty
|
||||||
}
|
// }
|
||||||
return isSecretKeyPrivateEmpty(secretKey);
|
// return isSecretKeyPrivateEmpty(secretKey);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static String convertKeyIdToHex(long keyId) {
|
public static String convertKeyIdToHex(long keyId) {
|
||||||
String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
|
String fingerPrint = Long.toHexString(keyId & 0xffffffffL).toUpperCase(Locale.US);
|
||||||
|
@ -45,6 +45,7 @@ public class KeychainContract {
|
|||||||
String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID
|
String KEY_RING_ROW_ID = "key_ring_row_id"; // foreign key to key_rings._ID
|
||||||
String KEY_DATA = "key_data"; // PGPPublicKey/PGPSecretKey blob
|
String KEY_DATA = "key_data"; // PGPPublicKey/PGPSecretKey blob
|
||||||
String RANK = "rank";
|
String RANK = "rank";
|
||||||
|
String FINGERPRINT = "fingerprint";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserIdsColumns {
|
interface UserIdsColumns {
|
||||||
|
@ -31,7 +31,7 @@ import android.provider.BaseColumns;
|
|||||||
|
|
||||||
public class KeychainDatabase extends SQLiteOpenHelper {
|
public class KeychainDatabase extends SQLiteOpenHelper {
|
||||||
private static final String DATABASE_NAME = "apg.db";
|
private static final String DATABASE_NAME = "apg.db";
|
||||||
private static final int DATABASE_VERSION = 6;
|
private static final int DATABASE_VERSION = 7;
|
||||||
|
|
||||||
public interface Tables {
|
public interface Tables {
|
||||||
String KEY_RINGS = "key_rings";
|
String KEY_RINGS = "key_rings";
|
||||||
@ -42,33 +42,45 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
|||||||
|
|
||||||
private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS
|
private static final String CREATE_KEY_RINGS = "CREATE TABLE IF NOT EXISTS " + Tables.KEY_RINGS
|
||||||
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
+ KeyRingsColumns.MASTER_KEY_ID + " INT64, " + KeyRingsColumns.TYPE + " INTEGER, "
|
+ KeyRingsColumns.MASTER_KEY_ID + " INT64, "
|
||||||
|
+ 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_KEYS = "CREATE TABLE IF NOT EXISTS " + Tables.KEYS + " ("
|
||||||
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KeysColumns.KEY_ID
|
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
+ " INT64, " + KeysColumns.TYPE + " INTEGER, " + KeysColumns.IS_MASTER_KEY
|
+ KeysColumns.KEY_ID + " INT64, "
|
||||||
+ " INTEGER, " + KeysColumns.ALGORITHM + " INTEGER, " + KeysColumns.KEY_SIZE
|
+ KeysColumns.TYPE + " INTEGER, "
|
||||||
+ " INTEGER, " + KeysColumns.CAN_CERTIFY + " INTEGER, " + KeysColumns.CAN_SIGN
|
+ KeysColumns.IS_MASTER_KEY + " INTEGER, "
|
||||||
+ " INTEGER, " + KeysColumns.CAN_ENCRYPT + " INTEGER, " + KeysColumns.IS_REVOKED
|
+ KeysColumns.ALGORITHM + " INTEGER, "
|
||||||
+ " INTEGER, " + KeysColumns.CREATION + " INTEGER, " + KeysColumns.EXPIRY
|
+ KeysColumns.KEY_SIZE + " INTEGER, "
|
||||||
+ " INTEGER, " + KeysColumns.KEY_DATA + " BLOB," + KeysColumns.RANK + " 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 + " INTEGER NOT NULL, FOREIGN KEY("
|
||||||
+ KeysColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
|
+ KeysColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
|
||||||
+ BaseColumns._ID + ") ON DELETE CASCADE)";
|
+ 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_USER_IDS = "CREATE TABLE IF NOT EXISTS " + Tables.USER_IDS
|
||||||
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
+ UserIdsColumns.USER_ID + " TEXT, " + UserIdsColumns.RANK + " INTEGER, "
|
+ UserIdsColumns.USER_ID + " TEXT, "
|
||||||
|
+ UserIdsColumns.RANK + " INTEGER, "
|
||||||
+ UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY("
|
+ UserIdsColumns.KEY_RING_ROW_ID + " INTEGER NOT NULL, FOREIGN KEY("
|
||||||
+ UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
|
+ UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
|
||||||
+ BaseColumns._ID + ") ON DELETE CASCADE)";
|
+ BaseColumns._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, "
|
||||||
+ ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " + ApiAppsColumns.PACKAGE_SIGNATURE
|
+ ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, "
|
||||||
+ " BLOB, " + ApiAppsColumns.KEY_ID + " INT64, " + ApiAppsColumns.ENCRYPTION_ALGORITHM
|
+ ApiAppsColumns.PACKAGE_SIGNATURE + " BLOB, "
|
||||||
+ " INTEGER, " + ApiAppsColumns.HASH_ALORITHM + " INTEGER, "
|
+ ApiAppsColumns.KEY_ID + " INT64, "
|
||||||
|
+ ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, "
|
||||||
|
+ ApiAppsColumns.HASH_ALORITHM + " INTEGER, "
|
||||||
+ ApiAppsColumns.COMPRESSION + " INTEGER)";
|
+ ApiAppsColumns.COMPRESSION + " INTEGER)";
|
||||||
|
|
||||||
KeychainDatabase(Context context) {
|
KeychainDatabase(Context context) {
|
||||||
@ -103,21 +115,24 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
|||||||
Log.w(Constants.TAG, "Upgrading database to version " + version);
|
Log.w(Constants.TAG, "Upgrading database to version " + version);
|
||||||
|
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case 3:
|
case 3:
|
||||||
db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.CAN_CERTIFY
|
db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.CAN_CERTIFY
|
||||||
+ " INTEGER DEFAULT 0;");
|
+ " INTEGER DEFAULT 0;");
|
||||||
db.execSQL("UPDATE " + Tables.KEYS + " SET " + KeysColumns.CAN_CERTIFY
|
db.execSQL("UPDATE " + Tables.KEYS + " SET " + KeysColumns.CAN_CERTIFY
|
||||||
+ " = 1 WHERE " + KeysColumns.IS_MASTER_KEY + "= 1;");
|
+ " = 1 WHERE " + KeysColumns.IS_MASTER_KEY + "= 1;");
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
db.execSQL(CREATE_API_APPS);
|
db.execSQL(CREATE_API_APPS);
|
||||||
case 5:
|
case 5:
|
||||||
// new column: package_signature
|
// new column: package_signature
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS);
|
db.execSQL("DROP TABLE IF EXISTS " + Tables.API_APPS);
|
||||||
db.execSQL(CREATE_API_APPS);
|
db.execSQL(CREATE_API_APPS);
|
||||||
|
case 6:
|
||||||
default:
|
// new column: fingerprint
|
||||||
break;
|
db.execSQL("ALTER TABLE " + Tables.KEYS + " ADD COLUMN " + KeysColumns.FINGERPRINT
|
||||||
|
+ " BLOB;");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,9 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
|
|
||||||
private KeychainDatabase mApgDatabase;
|
private KeychainDatabase mApgDatabase;
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
mUriMatcher = buildUriMatcher();
|
mUriMatcher = buildUriMatcher();
|
||||||
@ -248,52 +250,54 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getType(Uri uri) {
|
public String getType(Uri uri) {
|
||||||
final int match = mUriMatcher.match(uri);
|
final int match = mUriMatcher.match(uri);
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case PUBLIC_KEY_RING:
|
case PUBLIC_KEY_RING:
|
||||||
case PUBLIC_KEY_RING_BY_EMAILS:
|
case PUBLIC_KEY_RING_BY_EMAILS:
|
||||||
case PUBLIC_KEY_RING_BY_LIKE_EMAIL:
|
case PUBLIC_KEY_RING_BY_LIKE_EMAIL:
|
||||||
case SECRET_KEY_RING:
|
case SECRET_KEY_RING:
|
||||||
case SECRET_KEY_RING_BY_EMAILS:
|
case SECRET_KEY_RING_BY_EMAILS:
|
||||||
case SECRET_KEY_RING_BY_LIKE_EMAIL:
|
case SECRET_KEY_RING_BY_LIKE_EMAIL:
|
||||||
return KeyRings.CONTENT_TYPE;
|
return KeyRings.CONTENT_TYPE;
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_BY_ROW_ID:
|
case PUBLIC_KEY_RING_BY_ROW_ID:
|
||||||
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
case PUBLIC_KEY_RING_BY_KEY_ID:
|
case PUBLIC_KEY_RING_BY_KEY_ID:
|
||||||
case SECRET_KEY_RING_BY_ROW_ID:
|
case SECRET_KEY_RING_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
case SECRET_KEY_RING_BY_KEY_ID:
|
case SECRET_KEY_RING_BY_KEY_ID:
|
||||||
return KeyRings.CONTENT_ITEM_TYPE;
|
return KeyRings.CONTENT_ITEM_TYPE;
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_KEY:
|
case PUBLIC_KEY_RING_KEY:
|
||||||
case SECRET_KEY_RING_KEY:
|
case SECRET_KEY_RING_KEY:
|
||||||
return Keys.CONTENT_TYPE;
|
return Keys.CONTENT_TYPE;
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
||||||
return Keys.CONTENT_ITEM_TYPE;
|
return Keys.CONTENT_ITEM_TYPE;
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_USER_ID:
|
case PUBLIC_KEY_RING_USER_ID:
|
||||||
case SECRET_KEY_RING_USER_ID:
|
case SECRET_KEY_RING_USER_ID:
|
||||||
return UserIds.CONTENT_TYPE;
|
return UserIds.CONTENT_TYPE;
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
return UserIds.CONTENT_ITEM_TYPE;
|
return UserIds.CONTENT_ITEM_TYPE;
|
||||||
|
|
||||||
case API_APPS:
|
case API_APPS:
|
||||||
return ApiApps.CONTENT_TYPE;
|
return ApiApps.CONTENT_TYPE;
|
||||||
|
|
||||||
case API_APPS_BY_ROW_ID:
|
case API_APPS_BY_ROW_ID:
|
||||||
case API_APPS_BY_PACKAGE_NAME:
|
case API_APPS_BY_PACKAGE_NAME:
|
||||||
return ApiApps.CONTENT_ITEM_TYPE;
|
return ApiApps.CONTENT_ITEM_TYPE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,36 +310,36 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
private int getKeyType(int match) {
|
private int getKeyType(int match) {
|
||||||
int type;
|
int type;
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case PUBLIC_KEY_RING:
|
case PUBLIC_KEY_RING:
|
||||||
case PUBLIC_KEY_RING_BY_ROW_ID:
|
case PUBLIC_KEY_RING_BY_ROW_ID:
|
||||||
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
case PUBLIC_KEY_RING_BY_KEY_ID:
|
case PUBLIC_KEY_RING_BY_KEY_ID:
|
||||||
case PUBLIC_KEY_RING_BY_EMAILS:
|
case PUBLIC_KEY_RING_BY_EMAILS:
|
||||||
case PUBLIC_KEY_RING_BY_LIKE_EMAIL:
|
case PUBLIC_KEY_RING_BY_LIKE_EMAIL:
|
||||||
case PUBLIC_KEY_RING_KEY:
|
case PUBLIC_KEY_RING_KEY:
|
||||||
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
||||||
case PUBLIC_KEY_RING_USER_ID:
|
case PUBLIC_KEY_RING_USER_ID:
|
||||||
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
type = KeyTypes.PUBLIC;
|
type = KeyTypes.PUBLIC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECRET_KEY_RING:
|
case SECRET_KEY_RING:
|
||||||
case SECRET_KEY_RING_BY_ROW_ID:
|
case SECRET_KEY_RING_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
case SECRET_KEY_RING_BY_KEY_ID:
|
case SECRET_KEY_RING_BY_KEY_ID:
|
||||||
case SECRET_KEY_RING_BY_EMAILS:
|
case SECRET_KEY_RING_BY_EMAILS:
|
||||||
case SECRET_KEY_RING_BY_LIKE_EMAIL:
|
case SECRET_KEY_RING_BY_LIKE_EMAIL:
|
||||||
case SECRET_KEY_RING_KEY:
|
case SECRET_KEY_RING_KEY:
|
||||||
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_USER_ID:
|
case SECRET_KEY_RING_USER_ID:
|
||||||
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
type = KeyTypes.SECRET;
|
type = KeyTypes.SECRET;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.e(Constants.TAG, "Unknown match " + match);
|
Log.e(Constants.TAG, "Unknown match " + match);
|
||||||
type = -1;
|
type = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
@ -350,10 +354,13 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
HashMap<String, String> projectionMap = new HashMap<String, String>();
|
HashMap<String, String> projectionMap = new HashMap<String, String>();
|
||||||
|
|
||||||
projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID);
|
projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID);
|
||||||
projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "."
|
|
||||||
+ KeyRingsColumns.MASTER_KEY_ID);
|
|
||||||
projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "."
|
projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "."
|
||||||
+ KeyRingsColumns.KEY_RING_DATA);
|
+ KeyRingsColumns.KEY_RING_DATA);
|
||||||
|
projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID);
|
||||||
|
// TODO: deprecated master key id
|
||||||
|
//projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.KEY_ID);
|
||||||
|
projectionMap.put(KeysColumns.FINGERPRINT, Tables.KEYS + "." + KeysColumns.FINGERPRINT);
|
||||||
|
|
||||||
projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID);
|
projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID);
|
||||||
|
|
||||||
return projectionMap;
|
return projectionMap;
|
||||||
@ -386,22 +393,20 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds default query for keyRings: KeyRings table is joined with UserIds
|
* Builds default query for keyRings: KeyRings table is joined with UserIds and Keys
|
||||||
*
|
|
||||||
* @param qb
|
|
||||||
* @param match
|
|
||||||
* @param isMasterKey
|
|
||||||
* @param sortOrder
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match, String sortOrder) {
|
private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match) {
|
||||||
// public or secret keyring
|
// public or secret keyring
|
||||||
qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = ");
|
qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = ");
|
||||||
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
||||||
|
|
||||||
// join keyrings with userIds to every keyring
|
// join keyrings with keys and userIds
|
||||||
qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.USER_IDS + " ON " + "("
|
// Only get user id and key with rank 0 (main user id and main key)
|
||||||
+ Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "."
|
qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "("
|
||||||
|
+ Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "."
|
||||||
|
+ KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "."
|
||||||
|
+ KeysColumns.RANK + " = '0') " + " INNER JOIN " + Tables.USER_IDS + " ON "
|
||||||
|
+ "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "."
|
||||||
+ UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "."
|
+ UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "."
|
||||||
+ UserIdsColumns.RANK + " = '0')");
|
+ UserIdsColumns.RANK + " = '0')");
|
||||||
|
|
||||||
@ -411,16 +416,11 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds default query for keyRings: KeyRings table is joined with Keys and UserIds
|
* Builds default query for keyRings: KeyRings table is joined with UserIds and Keys
|
||||||
*
|
* <p/>
|
||||||
* @param qb
|
* Here only one key should be selected in the query to return a single keyring!
|
||||||
* @param match
|
|
||||||
* @param isMasterKey
|
|
||||||
* @param sortOrder
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private SQLiteQueryBuilder buildKeyRingQueryWithKeys(SQLiteQueryBuilder qb, int match,
|
private SQLiteQueryBuilder buildKeyRingQueryWithSpecificKey(SQLiteQueryBuilder qb, int match) {
|
||||||
String sortOrder) {
|
|
||||||
// public or secret keyring
|
// public or secret keyring
|
||||||
qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = ");
|
qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = ");
|
||||||
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
||||||
@ -438,11 +438,13 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
||||||
String sortOrder) {
|
String sortOrder) {
|
||||||
Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
|
Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
|
||||||
|
|
||||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
||||||
@ -451,169 +453,169 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
int match = mUriMatcher.match(uri);
|
int match = mUriMatcher.match(uri);
|
||||||
|
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case PUBLIC_KEY_RING:
|
case PUBLIC_KEY_RING:
|
||||||
case SECRET_KEY_RING:
|
case SECRET_KEY_RING:
|
||||||
qb = buildKeyRingQuery(qb, match, sortOrder);
|
qb = buildKeyRingQuery(qb, match);
|
||||||
|
|
||||||
if (TextUtils.isEmpty(sortOrder)) {
|
if (TextUtils.isEmpty(sortOrder)) {
|
||||||
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_BY_ROW_ID:
|
|
||||||
case SECRET_KEY_RING_BY_ROW_ID:
|
|
||||||
qb = buildKeyRingQuery(qb, match, sortOrder);
|
|
||||||
|
|
||||||
qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = ");
|
|
||||||
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
|
||||||
|
|
||||||
if (TextUtils.isEmpty(sortOrder)) {
|
|
||||||
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
|
||||||
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
|
||||||
qb = buildKeyRingQuery(qb, match, sortOrder);
|
|
||||||
|
|
||||||
qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = ");
|
|
||||||
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
|
||||||
|
|
||||||
if (TextUtils.isEmpty(sortOrder)) {
|
|
||||||
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SECRET_KEY_RING_BY_KEY_ID:
|
|
||||||
case PUBLIC_KEY_RING_BY_KEY_ID:
|
|
||||||
qb = buildKeyRingQueryWithKeys(qb, match, sortOrder);
|
|
||||||
|
|
||||||
qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.KEY_ID + " = ");
|
|
||||||
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
|
||||||
|
|
||||||
if (TextUtils.isEmpty(sortOrder)) {
|
|
||||||
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SECRET_KEY_RING_BY_EMAILS:
|
|
||||||
case PUBLIC_KEY_RING_BY_EMAILS:
|
|
||||||
qb = buildKeyRingQuery(qb, match, sortOrder);
|
|
||||||
|
|
||||||
String emails = uri.getLastPathSegment();
|
|
||||||
String chunks[] = emails.split(" *, *");
|
|
||||||
boolean gotCondition = false;
|
|
||||||
String emailWhere = "";
|
|
||||||
for (int i = 0; i < chunks.length; ++i) {
|
|
||||||
if (chunks[i].length() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (i != 0) {
|
|
||||||
emailWhere += " OR ";
|
|
||||||
}
|
|
||||||
emailWhere += "tmp." + UserIdsColumns.USER_ID + " LIKE ";
|
|
||||||
// match '*<email>', so it has to be at the *end* of the user id
|
|
||||||
emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
|
|
||||||
gotCondition = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gotCondition) {
|
break;
|
||||||
|
|
||||||
|
case PUBLIC_KEY_RING_BY_ROW_ID:
|
||||||
|
case SECRET_KEY_RING_BY_ROW_ID:
|
||||||
|
qb = buildKeyRingQuery(qb, match);
|
||||||
|
|
||||||
|
qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = ");
|
||||||
|
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(sortOrder)) {
|
||||||
|
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
|
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
|
qb = buildKeyRingQuery(qb, match);
|
||||||
|
|
||||||
|
qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = ");
|
||||||
|
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(sortOrder)) {
|
||||||
|
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECRET_KEY_RING_BY_KEY_ID:
|
||||||
|
case PUBLIC_KEY_RING_BY_KEY_ID:
|
||||||
|
qb = buildKeyRingQueryWithSpecificKey(qb, match);
|
||||||
|
|
||||||
|
qb.appendWhere(" AND " + Tables.KEYS + "." + KeysColumns.KEY_ID + " = ");
|
||||||
|
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(sortOrder)) {
|
||||||
|
sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECRET_KEY_RING_BY_EMAILS:
|
||||||
|
case PUBLIC_KEY_RING_BY_EMAILS:
|
||||||
|
qb = buildKeyRingQuery(qb, match);
|
||||||
|
|
||||||
|
String emails = uri.getLastPathSegment();
|
||||||
|
String chunks[] = emails.split(" *, *");
|
||||||
|
boolean gotCondition = false;
|
||||||
|
String emailWhere = "";
|
||||||
|
for (int i = 0; i < chunks.length; ++i) {
|
||||||
|
if (chunks[i].length() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i != 0) {
|
||||||
|
emailWhere += " OR ";
|
||||||
|
}
|
||||||
|
emailWhere += "tmp." + UserIdsColumns.USER_ID + " LIKE ";
|
||||||
|
// match '*<email>', so it has to be at the *end* of the user id
|
||||||
|
emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">");
|
||||||
|
gotCondition = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gotCondition) {
|
||||||
|
qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM "
|
||||||
|
+ Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID
|
||||||
|
+ " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere
|
||||||
|
+ "))");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECRET_KEY_RING_BY_LIKE_EMAIL:
|
||||||
|
case PUBLIC_KEY_RING_BY_LIKE_EMAIL:
|
||||||
|
qb = buildKeyRingQuery(qb, match);
|
||||||
|
|
||||||
|
String likeEmail = uri.getLastPathSegment();
|
||||||
|
|
||||||
|
String likeEmailWhere = "tmp." + UserIdsColumns.USER_ID + " LIKE "
|
||||||
|
+ DatabaseUtils.sqlEscapeString("%<%" + likeEmail + "%>");
|
||||||
|
|
||||||
qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM "
|
qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM "
|
||||||
+ Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID
|
+ Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID
|
||||||
+ " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere
|
+ " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + likeEmailWhere
|
||||||
+ "))");
|
+ "))");
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECRET_KEY_RING_BY_LIKE_EMAIL:
|
case PUBLIC_KEY_RING_KEY:
|
||||||
case PUBLIC_KEY_RING_BY_LIKE_EMAIL:
|
case SECRET_KEY_RING_KEY:
|
||||||
qb = buildKeyRingQuery(qb, match, sortOrder);
|
qb.setTables(Tables.KEYS);
|
||||||
|
qb.appendWhere(KeysColumns.TYPE + " = ");
|
||||||
|
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
||||||
|
|
||||||
String likeEmail = uri.getLastPathSegment();
|
qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = ");
|
||||||
|
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
||||||
|
|
||||||
String likeEmailWhere = "tmp." + UserIdsColumns.USER_ID + " LIKE "
|
qb.setProjectionMap(getProjectionMapForKeys());
|
||||||
+ DatabaseUtils.sqlEscapeString("%<%" + likeEmail + "%>");
|
|
||||||
|
|
||||||
qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM "
|
break;
|
||||||
+ Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID
|
|
||||||
+ " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + likeEmailWhere
|
|
||||||
+ "))");
|
|
||||||
|
|
||||||
break;
|
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
||||||
|
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
||||||
|
qb.setTables(Tables.KEYS);
|
||||||
|
qb.appendWhere(KeysColumns.TYPE + " = ");
|
||||||
|
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_KEY:
|
qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = ");
|
||||||
case SECRET_KEY_RING_KEY:
|
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
||||||
qb.setTables(Tables.KEYS);
|
|
||||||
qb.appendWhere(KeysColumns.TYPE + " = ");
|
|
||||||
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
|
||||||
|
|
||||||
qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = ");
|
qb.appendWhere(" AND " + BaseColumns._ID + " = ");
|
||||||
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
||||||
|
|
||||||
qb.setProjectionMap(getProjectionMapForKeys());
|
qb.setProjectionMap(getProjectionMapForKeys());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
case PUBLIC_KEY_RING_USER_ID:
|
||||||
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
case SECRET_KEY_RING_USER_ID:
|
||||||
qb.setTables(Tables.KEYS);
|
qb.setTables(Tables.USER_IDS);
|
||||||
qb.appendWhere(KeysColumns.TYPE + " = ");
|
qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = ");
|
||||||
qb.appendWhereEscapeString(Integer.toString(getKeyType(match)));
|
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
||||||
|
|
||||||
qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = ");
|
break;
|
||||||
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
|
||||||
|
|
||||||
qb.appendWhere(" AND " + BaseColumns._ID + " = ");
|
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
|
qb.setTables(Tables.USER_IDS);
|
||||||
|
qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = ");
|
||||||
|
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
||||||
|
|
||||||
qb.setProjectionMap(getProjectionMapForKeys());
|
qb.appendWhere(" AND " + BaseColumns._ID + " = ");
|
||||||
|
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_USER_ID:
|
case API_APPS:
|
||||||
case SECRET_KEY_RING_USER_ID:
|
qb.setTables(Tables.API_APPS);
|
||||||
qb.setTables(Tables.USER_IDS);
|
|
||||||
qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = ");
|
|
||||||
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case API_APPS_BY_ROW_ID:
|
||||||
|
qb.setTables(Tables.API_APPS);
|
||||||
|
|
||||||
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
qb.appendWhere(BaseColumns._ID + " = ");
|
||||||
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
||||||
qb.setTables(Tables.USER_IDS);
|
|
||||||
qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = ");
|
|
||||||
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
|
||||||
|
|
||||||
qb.appendWhere(" AND " + BaseColumns._ID + " = ");
|
break;
|
||||||
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
case API_APPS_BY_PACKAGE_NAME:
|
||||||
|
qb.setTables(Tables.API_APPS);
|
||||||
|
qb.appendWhere(ApiApps.PACKAGE_NAME + " = ");
|
||||||
|
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case API_APPS:
|
default:
|
||||||
qb.setTables(Tables.API_APPS);
|
throw new IllegalArgumentException("Unknown URI " + uri);
|
||||||
|
|
||||||
break;
|
|
||||||
case API_APPS_BY_ROW_ID:
|
|
||||||
qb.setTables(Tables.API_APPS);
|
|
||||||
|
|
||||||
qb.appendWhere(BaseColumns._ID + " = ");
|
|
||||||
qb.appendWhereEscapeString(uri.getLastPathSegment());
|
|
||||||
|
|
||||||
break;
|
|
||||||
case API_APPS_BY_PACKAGE_NAME:
|
|
||||||
qb.setTables(Tables.API_APPS);
|
|
||||||
qb.appendWhere(ApiApps.PACKAGE_NAME + " = ");
|
|
||||||
qb.appendWhereEscapeString(uri.getPathSegments().get(2));
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unknown URI " + uri);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,14 +636,16 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
Log.d(Constants.TAG,
|
Log.d(Constants.TAG,
|
||||||
"Query: "
|
"Query: "
|
||||||
+ qb.buildQuery(projection, selection, selectionArgs, null, null,
|
+ qb.buildQuery(projection, selection, selectionArgs, null, null,
|
||||||
orderBy, null));
|
orderBy, null));
|
||||||
Log.d(Constants.TAG, "Cursor: " + DatabaseUtils.dumpCursorToString(c));
|
Log.d(Constants.TAG, "Cursor: " + DatabaseUtils.dumpCursorToString(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Uri insert(Uri uri, ContentValues values) {
|
public Uri insert(Uri uri, ContentValues values) {
|
||||||
Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
|
Log.d(Constants.TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
|
||||||
@ -654,56 +658,56 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
final int match = mUriMatcher.match(uri);
|
final int match = mUriMatcher.match(uri);
|
||||||
|
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case PUBLIC_KEY_RING:
|
case PUBLIC_KEY_RING:
|
||||||
values.put(KeyRings.TYPE, KeyTypes.PUBLIC);
|
values.put(KeyRings.TYPE, KeyTypes.PUBLIC);
|
||||||
|
|
||||||
rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values);
|
rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values);
|
||||||
rowUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId));
|
rowUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId));
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_KEY:
|
case PUBLIC_KEY_RING_KEY:
|
||||||
values.put(Keys.TYPE, KeyTypes.PUBLIC);
|
values.put(Keys.TYPE, KeyTypes.PUBLIC);
|
||||||
|
|
||||||
rowId = db.insertOrThrow(Tables.KEYS, null, values);
|
rowId = db.insertOrThrow(Tables.KEYS, null, values);
|
||||||
rowUri = Keys.buildPublicKeysUri(Long.toString(rowId));
|
rowUri = Keys.buildPublicKeysUri(Long.toString(rowId));
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_USER_ID:
|
case PUBLIC_KEY_RING_USER_ID:
|
||||||
rowId = db.insertOrThrow(Tables.USER_IDS, null, values);
|
rowId = db.insertOrThrow(Tables.USER_IDS, null, values);
|
||||||
rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId));
|
rowUri = UserIds.buildPublicUserIdsUri(Long.toString(rowId));
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SECRET_KEY_RING:
|
case SECRET_KEY_RING:
|
||||||
values.put(KeyRings.TYPE, KeyTypes.SECRET);
|
values.put(KeyRings.TYPE, KeyTypes.SECRET);
|
||||||
|
|
||||||
rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values);
|
rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values);
|
||||||
rowUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId));
|
rowUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId));
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SECRET_KEY_RING_KEY:
|
case SECRET_KEY_RING_KEY:
|
||||||
values.put(Keys.TYPE, KeyTypes.SECRET);
|
values.put(Keys.TYPE, KeyTypes.SECRET);
|
||||||
|
|
||||||
rowId = db.insertOrThrow(Tables.KEYS, null, values);
|
rowId = db.insertOrThrow(Tables.KEYS, null, values);
|
||||||
rowUri = Keys.buildSecretKeysUri(Long.toString(rowId));
|
rowUri = Keys.buildSecretKeysUri(Long.toString(rowId));
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SECRET_KEY_RING_USER_ID:
|
case SECRET_KEY_RING_USER_ID:
|
||||||
rowId = db.insertOrThrow(Tables.USER_IDS, null, values);
|
rowId = db.insertOrThrow(Tables.USER_IDS, null, values);
|
||||||
rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId));
|
rowUri = UserIds.buildSecretUserIdsUri(Long.toString(rowId));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case API_APPS:
|
case API_APPS:
|
||||||
rowId = db.insertOrThrow(Tables.API_APPS, null, values);
|
rowId = db.insertOrThrow(Tables.API_APPS, null, values);
|
||||||
rowUri = ApiApps.buildIdUri(Long.toString(rowId));
|
rowUri = ApiApps.buildIdUri(Long.toString(rowId));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify of changes in db
|
// notify of changes in db
|
||||||
@ -716,7 +720,9 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
return rowUri;
|
return rowUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||||
Log.v(Constants.TAG, "delete(uri=" + uri + ")");
|
Log.v(Constants.TAG, "delete(uri=" + uri + ")");
|
||||||
@ -728,45 +734,45 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
|
|
||||||
String defaultSelection = null;
|
String defaultSelection = null;
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case PUBLIC_KEY_RING_BY_ROW_ID:
|
case PUBLIC_KEY_RING_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_BY_ROW_ID:
|
case SECRET_KEY_RING_BY_ROW_ID:
|
||||||
defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment();
|
defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment();
|
||||||
// corresponding keys and userIds are deleted by ON DELETE CASCADE
|
// corresponding keys and userIds are deleted by ON DELETE CASCADE
|
||||||
count = db.delete(Tables.KEY_RINGS,
|
count = db.delete(Tables.KEY_RINGS,
|
||||||
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection),
|
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection),
|
||||||
selectionArgs);
|
selectionArgs);
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment();
|
defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment();
|
||||||
// corresponding keys and userIds are deleted by ON DELETE CASCADE
|
// corresponding keys and userIds are deleted by ON DELETE CASCADE
|
||||||
count = db.delete(Tables.KEY_RINGS,
|
count = db.delete(Tables.KEY_RINGS,
|
||||||
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection),
|
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match), selection),
|
||||||
selectionArgs);
|
selectionArgs);
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
||||||
count = db.delete(Tables.KEYS,
|
count = db.delete(Tables.KEYS,
|
||||||
buildDefaultKeysSelection(uri, getKeyType(match), selection), selectionArgs);
|
buildDefaultKeysSelection(uri, getKeyType(match), selection), selectionArgs);
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection),
|
count = db.delete(Tables.KEYS, buildDefaultUserIdsSelection(uri, selection),
|
||||||
selectionArgs);
|
selectionArgs);
|
||||||
break;
|
break;
|
||||||
case API_APPS_BY_ROW_ID:
|
case API_APPS_BY_ROW_ID:
|
||||||
count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, false, selection),
|
count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, false, selection),
|
||||||
selectionArgs);
|
selectionArgs);
|
||||||
break;
|
break;
|
||||||
case API_APPS_BY_PACKAGE_NAME:
|
case API_APPS_BY_PACKAGE_NAME:
|
||||||
count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection),
|
count = db.delete(Tables.API_APPS, buildDefaultApiAppsSelection(uri, true, selection),
|
||||||
selectionArgs);
|
selectionArgs);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify of changes in db
|
// notify of changes in db
|
||||||
@ -775,7 +781,9 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||||
Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
|
Log.v(Constants.TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
|
||||||
@ -787,54 +795,54 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
try {
|
try {
|
||||||
final int match = mUriMatcher.match(uri);
|
final int match = mUriMatcher.match(uri);
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case PUBLIC_KEY_RING_BY_ROW_ID:
|
case PUBLIC_KEY_RING_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_BY_ROW_ID:
|
case SECRET_KEY_RING_BY_ROW_ID:
|
||||||
defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment();
|
defaultSelection = BaseColumns._ID + "=" + uri.getLastPathSegment();
|
||||||
|
|
||||||
count = db.update(
|
count = db.update(
|
||||||
Tables.KEY_RINGS,
|
Tables.KEY_RINGS,
|
||||||
values,
|
values,
|
||||||
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match),
|
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match),
|
||||||
selection), selectionArgs);
|
selection), selectionArgs);
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
case PUBLIC_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
case SECRET_KEY_RING_BY_MASTER_KEY_ID:
|
||||||
defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment();
|
defaultSelection = KeyRings.MASTER_KEY_ID + "=" + uri.getLastPathSegment();
|
||||||
|
|
||||||
count = db.update(
|
count = db.update(
|
||||||
Tables.KEY_RINGS,
|
Tables.KEY_RINGS,
|
||||||
values,
|
values,
|
||||||
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match),
|
buildDefaultKeyRingsSelection(defaultSelection, getKeyType(match),
|
||||||
selection), selectionArgs);
|
selection), selectionArgs);
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
case PUBLIC_KEY_RING_KEY_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
case SECRET_KEY_RING_KEY_BY_ROW_ID:
|
||||||
count = db
|
count = db
|
||||||
.update(Tables.KEYS, values,
|
.update(Tables.KEYS, values,
|
||||||
buildDefaultKeysSelection(uri, getKeyType(match), selection),
|
buildDefaultKeysSelection(uri, getKeyType(match), selection),
|
||||||
selectionArgs);
|
selectionArgs);
|
||||||
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
sendBroadcastDatabaseChange(getKeyType(match), getType(uri));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
case SECRET_KEY_RING_USER_ID_BY_ROW_ID:
|
||||||
count = db.update(Tables.USER_IDS, values,
|
count = db.update(Tables.USER_IDS, values,
|
||||||
buildDefaultUserIdsSelection(uri, selection), selectionArgs);
|
buildDefaultUserIdsSelection(uri, selection), selectionArgs);
|
||||||
break;
|
break;
|
||||||
case API_APPS_BY_ROW_ID:
|
case API_APPS_BY_ROW_ID:
|
||||||
count = db.update(Tables.API_APPS, values,
|
count = db.update(Tables.API_APPS, values,
|
||||||
buildDefaultApiAppsSelection(uri, false, selection), selectionArgs);
|
buildDefaultApiAppsSelection(uri, false, selection), selectionArgs);
|
||||||
break;
|
break;
|
||||||
case API_APPS_BY_PACKAGE_NAME:
|
case API_APPS_BY_PACKAGE_NAME:
|
||||||
count = db.update(Tables.API_APPS, values,
|
count = db.update(Tables.API_APPS, values,
|
||||||
buildDefaultApiAppsSelection(uri, true, selection), selectionArgs);
|
buildDefaultApiAppsSelection(uri, true, selection), selectionArgs);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
throw new UnsupportedOperationException("Unknown uri: " + uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify of changes in db
|
// notify of changes in db
|
||||||
@ -856,7 +864,7 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String buildDefaultKeyRingsSelection(String defaultSelection, Integer keyType,
|
private String buildDefaultKeyRingsSelection(String defaultSelection, Integer keyType,
|
||||||
String selection) {
|
String selection) {
|
||||||
String andType = "";
|
String andType = "";
|
||||||
if (keyType != null) {
|
if (keyType != null) {
|
||||||
andType = " AND " + KeyRingsColumns.TYPE + "=" + keyType;
|
andType = " AND " + KeyRingsColumns.TYPE + "=" + keyType;
|
||||||
|
@ -23,6 +23,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||||
|
import org.spongycastle.bcpg.UserAttributePacket;
|
||||||
|
import org.spongycastle.bcpg.UserAttributeSubpacket;
|
||||||
import org.spongycastle.openpgp.PGPKeyRing;
|
import org.spongycastle.openpgp.PGPKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPPublicKey;
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
@ -55,10 +57,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Private helper method to get PGPKeyRing from database
|
* Private helper method to get PGPKeyRing from database
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param queryUri
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) {
|
public static PGPKeyRing getPGPKeyRing(Context context, Uri queryUri) {
|
||||||
Cursor cursor = context.getContentResolver().query(queryUri,
|
Cursor cursor = context.getContentResolver().query(queryUri,
|
||||||
@ -83,10 +81,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPPublicKeyRing object from the database blob based on the rowId
|
* Retrieves the actual PGPPublicKeyRing object from the database blob based on the rowId
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param rowId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPPublicKeyRing getPGPPublicKeyRingByRowId(Context context, long rowId) {
|
public static PGPPublicKeyRing getPGPPublicKeyRingByRowId(Context context, long rowId) {
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId));
|
Uri queryUri = KeyRings.buildPublicKeyRingsUri(Long.toString(rowId));
|
||||||
@ -95,10 +89,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPPublicKeyRing object from the database blob based on the maserKeyId
|
* Retrieves the actual PGPPublicKeyRing object from the database blob based on the maserKeyId
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param masterKeyId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context,
|
public static PGPPublicKeyRing getPGPPublicKeyRingByMasterKeyId(Context context,
|
||||||
long masterKeyId) {
|
long masterKeyId) {
|
||||||
@ -109,10 +99,6 @@ public class ProviderHelper {
|
|||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPPublicKeyRing object from the database blob associated with a key
|
* Retrieves the actual PGPPublicKeyRing object from the database blob associated with a key
|
||||||
* with this keyId
|
* with this keyId
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPPublicKeyRing getPGPPublicKeyRingByKeyId(Context context, long keyId) {
|
public static PGPPublicKeyRing getPGPPublicKeyRingByKeyId(Context context, long keyId) {
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsByKeyIdUri(Long.toString(keyId));
|
Uri queryUri = KeyRings.buildPublicKeyRingsByKeyIdUri(Long.toString(keyId));
|
||||||
@ -122,10 +108,6 @@ public class ProviderHelper {
|
|||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPPublicKey object from the database blob associated with a key with
|
* Retrieves the actual PGPPublicKey object from the database blob associated with a key with
|
||||||
* this keyId
|
* this keyId
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
|
public static PGPPublicKey getPGPPublicKeyByKeyId(Context context, long keyId) {
|
||||||
PGPPublicKeyRing keyRing = getPGPPublicKeyRingByKeyId(context, keyId);
|
PGPPublicKeyRing keyRing = getPGPPublicKeyRingByKeyId(context, keyId);
|
||||||
@ -138,10 +120,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPSecretKeyRing object from the database blob based on the rowId
|
* Retrieves the actual PGPSecretKeyRing object from the database blob based on the rowId
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param rowId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPSecretKeyRing getPGPSecretKeyRingByRowId(Context context, long rowId) {
|
public static PGPSecretKeyRing getPGPSecretKeyRingByRowId(Context context, long rowId) {
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId));
|
Uri queryUri = KeyRings.buildSecretKeyRingsUri(Long.toString(rowId));
|
||||||
@ -150,10 +128,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param masterKeyId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context,
|
public static PGPSecretKeyRing getPGPSecretKeyRingByMasterKeyId(Context context,
|
||||||
long masterKeyId) {
|
long masterKeyId) {
|
||||||
@ -164,10 +138,6 @@ public class ProviderHelper {
|
|||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPSecretKeyRing object from the database blob associated with a key
|
* Retrieves the actual PGPSecretKeyRing object from the database blob associated with a key
|
||||||
* with this keyId
|
* with this keyId
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPSecretKeyRing getPGPSecretKeyRingByKeyId(Context context, long keyId) {
|
public static PGPSecretKeyRing getPGPSecretKeyRingByKeyId(Context context, long keyId) {
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsByKeyIdUri(Long.toString(keyId));
|
Uri queryUri = KeyRings.buildSecretKeyRingsByKeyIdUri(Long.toString(keyId));
|
||||||
@ -177,10 +147,6 @@ public class ProviderHelper {
|
|||||||
/**
|
/**
|
||||||
* Retrieves the actual PGPSecretKey object from the database blob associated with a key with
|
* Retrieves the actual PGPSecretKey object from the database blob associated with a key with
|
||||||
* this keyId
|
* this keyId
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) {
|
public static PGPSecretKey getPGPSecretKeyByKeyId(Context context, long keyId) {
|
||||||
PGPSecretKeyRing keyRing = getPGPSecretKeyRingByKeyId(context, keyId);
|
PGPSecretKeyRing keyRing = getPGPSecretKeyRingByKeyId(context, keyId);
|
||||||
@ -193,12 +159,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves PGPPublicKeyRing with its keys and userIds in DB
|
* Saves PGPPublicKeyRing with its keys and userIds in DB
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRing
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
* @throws GeneralException
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static void saveKeyRing(Context context, PGPPublicKeyRing keyRing) throws IOException {
|
public static void saveKeyRing(Context context, PGPPublicKeyRing keyRing) throws IOException {
|
||||||
@ -263,12 +223,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves PGPSecretKeyRing with its keys and userIds in DB
|
* Saves PGPSecretKeyRing with its keys and userIds in DB
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRing
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
* @throws GeneralException
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static void saveKeyRing(Context context, PGPSecretKeyRing keyRing) throws IOException {
|
public static void saveKeyRing(Context context, PGPSecretKeyRing keyRing) throws IOException {
|
||||||
@ -333,13 +287,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
|
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @param key
|
|
||||||
* @param rank
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
private static ContentProviderOperation buildPublicKeyOperations(Context context,
|
private static ContentProviderOperation buildPublicKeyOperations(Context context,
|
||||||
long keyRingRowId, PGPPublicKey key, int rank) throws IOException {
|
long keyRingRowId, PGPPublicKey key, int rank) throws IOException {
|
||||||
@ -367,13 +314,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing
|
* Build ContentProviderOperation to add PublicUserIds to database corresponding to a keyRing
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @param key
|
|
||||||
* @param rank
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
private static ContentProviderOperation buildPublicUserIdOperations(Context context,
|
private static ContentProviderOperation buildPublicUserIdOperations(Context context,
|
||||||
long keyRingRowId, String userId, int rank) {
|
long keyRingRowId, String userId, int rank) {
|
||||||
@ -389,13 +329,6 @@ 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
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @param key
|
|
||||||
* @param rank
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
private static ContentProviderOperation buildSecretKeyOperations(Context context,
|
private static ContentProviderOperation buildSecretKeyOperations(Context context,
|
||||||
long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
|
long keyRingRowId, PGPSecretKey key, int rank) throws IOException {
|
||||||
@ -432,13 +365,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing
|
* Build ContentProviderOperation to add SecretUserIds to database corresponding to a keyRing
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @param key
|
|
||||||
* @param rank
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
private static ContentProviderOperation buildSecretUserIdOperations(Context context,
|
private static ContentProviderOperation buildSecretUserIdOperations(Context context,
|
||||||
long keyRingRowId, String userId, int rank) {
|
long keyRingRowId, String userId, int rank) {
|
||||||
@ -454,10 +380,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Private helper method
|
* Private helper method
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param queryUri
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private static ArrayList<Long> getKeyRingsMasterKeyIds(Context context, Uri queryUri) {
|
private static ArrayList<Long> getKeyRingsMasterKeyIds(Context context, Uri queryUri) {
|
||||||
Cursor cursor = context.getContentResolver().query(queryUri,
|
Cursor cursor = context.getContentResolver().query(queryUri,
|
||||||
@ -482,9 +404,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves ids of all SecretKeyRings
|
* Retrieves ids of all SecretKeyRings
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Long> getSecretKeyRingsMasterKeyIds(Context context) {
|
public static ArrayList<Long> getSecretKeyRingsMasterKeyIds(Context context) {
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri();
|
Uri queryUri = KeyRings.buildSecretKeyRingsUri();
|
||||||
@ -493,9 +412,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves ids of all PublicKeyRings
|
* Retrieves ids of all PublicKeyRings
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Long> getPublicKeyRingsMasterKeyIds(Context context) {
|
public static ArrayList<Long> getPublicKeyRingsMasterKeyIds(Context context) {
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsUri();
|
Uri queryUri = KeyRings.buildPublicKeyRingsUri();
|
||||||
@ -514,10 +430,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get master key id of keyring by its row id
|
* Get master key id of keyring by its row id
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static long getPublicMasterKeyId(Context context, long keyRingRowId) {
|
public static long getPublicMasterKeyId(Context context, long keyRingRowId) {
|
||||||
Uri queryUri = KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowId));
|
Uri queryUri = KeyRings.buildPublicKeyRingsUri(String.valueOf(keyRingRowId));
|
||||||
@ -526,10 +438,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get empty status of master key of keyring by its row id
|
* Get empty status of master key of keyring by its row id
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static boolean getSecretMasterKeyCanSign(Context context, long keyRingRowId) {
|
public static boolean getSecretMasterKeyCanSign(Context context, long keyRingRowId) {
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId));
|
Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId));
|
||||||
@ -538,11 +446,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Private helper method to get master key private empty status of keyring by its row id
|
* Private helper method to get master key private empty status of keyring by its row id
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param queryUri
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) {
|
private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) {
|
||||||
String[] projection = new String[]{
|
String[] projection = new String[]{
|
||||||
@ -572,10 +475,6 @@ public class ProviderHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get master key id of keyring by its row id
|
* Get master key id of keyring by its row id
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static long getSecretMasterKeyId(Context context, long keyRingRowId) {
|
public static long getSecretMasterKeyId(Context context, long keyRingRowId) {
|
||||||
Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId));
|
Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId));
|
||||||
@ -583,41 +482,84 @@ public class ProviderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private helper method to get master key id of keyring by its row id
|
* Get master key id of key
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param queryUri
|
|
||||||
* @param keyRingRowId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static long getMasterKeyId(Context context, Uri queryUri) {
|
public static long getMasterKeyId(Context context, Uri queryUri) {
|
||||||
String[] projection = new String[]{KeyRings.MASTER_KEY_ID};
|
String[] projection = new String[]{KeyRings.MASTER_KEY_ID};
|
||||||
|
Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
|
||||||
ContentResolver cr = context.getContentResolver();
|
|
||||||
Cursor cursor = cr.query(queryUri, projection, null, null, null);
|
|
||||||
|
|
||||||
long masterKeyId = -1;
|
long masterKeyId = -1;
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
try {
|
||||||
int masterKeyIdCol = cursor.getColumnIndex(KeyRings.MASTER_KEY_ID);
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
int masterKeyIdCol = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID);
|
||||||
|
|
||||||
masterKeyId = cursor.getLong(masterKeyIdCol);
|
masterKeyId = cursor.getLong(masterKeyIdCol);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return masterKeyId;
|
return masterKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<String> getPublicKeyRingsAsArmoredString(Context context,
|
/**
|
||||||
long[] masterKeyIds) {
|
* Get fingerprint of key
|
||||||
return getKeyRingsAsArmoredString(context, KeyRings.buildPublicKeyRingsUri(), masterKeyIds);
|
*/
|
||||||
}
|
public static byte[] getFingerprint(Context context, Uri queryUri) {
|
||||||
|
String[] projection = new String[]{Keys.FINGERPRINT};
|
||||||
|
Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
|
||||||
|
|
||||||
public static ArrayList<String> getSecretKeyRingsAsArmoredString(Context context,
|
byte[] fingerprint = null;
|
||||||
long[] masterKeyIds) {
|
try {
|
||||||
return getKeyRingsAsArmoredString(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds);
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
int col = cursor.getColumnIndexOrThrow(Keys.FINGERPRINT);
|
||||||
|
|
||||||
|
fingerprint = cursor.getBlob(col);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FALLBACK: If fingerprint is not in database, get it from key blob!
|
||||||
|
// this could happen if the key was saved by a previous version of Keychain!
|
||||||
|
if (fingerprint == null) {
|
||||||
|
Log.d(Constants.TAG, "FALLBACK: fingerprint is not in database, get it from key blob!");
|
||||||
|
|
||||||
|
// get master key id
|
||||||
|
projection = new String[]{KeyRings.MASTER_KEY_ID};
|
||||||
|
cursor = context.getContentResolver().query(queryUri, projection, null, null, null);
|
||||||
|
long masterKeyId = 0;
|
||||||
|
try {
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
int col = cursor.getColumnIndexOrThrow(KeyRings.MASTER_KEY_ID);
|
||||||
|
|
||||||
|
masterKeyId = cursor.getLong(col);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPPublicKey key = ProviderHelper.getPGPPublicKeyByKeyId(context, masterKeyId);
|
||||||
|
// if it is no public key get it from your own keys...
|
||||||
|
if (key == null) {
|
||||||
|
PGPSecretKey secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, masterKeyId);
|
||||||
|
if (secretKey == null) {
|
||||||
|
Log.e(Constants.TAG, "Key could not be found!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
key = secretKey.getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
fingerprint = key.getFingerprint();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri,
|
public static ArrayList<String> getKeyRingsAsArmoredString(Context context, Uri uri,
|
||||||
@ -681,14 +623,6 @@ public class ProviderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getPublicKeyRingsAsByteArray(Context context, long[] masterKeyIds) {
|
|
||||||
return getKeyRingsAsByteArray(context, KeyRings.buildPublicKeyRingsUri(), masterKeyIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] getSecretKeyRingsAsByteArray(Context context, long[] masterKeyIds) {
|
|
||||||
return getKeyRingsAsByteArray(context, KeyRings.buildSecretKeyRingsUri(), masterKeyIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] getKeyRingsAsByteArray(Context context, Uri uri, long[] masterKeyIds) {
|
public static byte[] getKeyRingsAsByteArray(Context context, Uri uri, long[] masterKeyIds) {
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@ -35,6 +36,7 @@ import android.app.ProgressDialog;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.nfc.NdefMessage;
|
import android.nfc.NdefMessage;
|
||||||
import android.nfc.NfcAdapter;
|
import android.nfc.NfcAdapter;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -56,6 +58,8 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY";
|
public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY";
|
||||||
public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
|
public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
|
||||||
+ "IMPORT_KEY_FROM_QR_CODE";
|
+ "IMPORT_KEY_FROM_QR_CODE";
|
||||||
|
public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = Constants.INTENT_PREFIX
|
||||||
|
+ "IMPORT_KEY_FROM_KEYSERVER";
|
||||||
|
|
||||||
// Actions for internal use only:
|
// Actions for internal use only:
|
||||||
public static final String ACTION_IMPORT_KEY_FROM_FILE = Constants.INTENT_PREFIX
|
public static final String ACTION_IMPORT_KEY_FROM_FILE = Constants.INTENT_PREFIX
|
||||||
@ -63,24 +67,21 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
public static final String ACTION_IMPORT_KEY_FROM_NFC = Constants.INTENT_PREFIX
|
public static final String ACTION_IMPORT_KEY_FROM_NFC = Constants.INTENT_PREFIX
|
||||||
+ "IMPORT_KEY_FROM_NFC";
|
+ "IMPORT_KEY_FROM_NFC";
|
||||||
|
|
||||||
// only used by IMPORT
|
// only used by ACTION_IMPORT_KEY
|
||||||
public static final String EXTRA_KEY_BYTES = "key_bytes";
|
public static final String EXTRA_KEY_BYTES = "key_bytes";
|
||||||
|
|
||||||
// TODO: import keys from server
|
// only used by ACTION_IMPORT_KEY_FROM_KEYSERVER
|
||||||
// public static final String EXTRA_KEY_ID = "keyId";
|
public static final String EXTRA_QUERY = "query";
|
||||||
|
|
||||||
|
public static final String FINGERPRINT_SCHEME = "openpgp4fpr";
|
||||||
|
|
||||||
protected boolean mDeleteAfterImport = false;
|
protected boolean mDeleteAfterImport = false;
|
||||||
|
|
||||||
FileDialogFragment mFileDialog;
|
// view
|
||||||
ImportKeysListFragment mListFragment;
|
private ImportKeysListFragment mListFragment;
|
||||||
OnNavigationListener mOnNavigationListener;
|
private String[] mNavigationStrings;
|
||||||
String[] mNavigationStrings;
|
private Fragment mCurrentFragment;
|
||||||
|
private BootstrapButton mImportButton;
|
||||||
Fragment mCurrentFragment;
|
|
||||||
|
|
||||||
BootstrapButton mImportButton;
|
|
||||||
|
|
||||||
// BootstrapButton mImportSignUploadButton;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -95,21 +96,11 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
importKeys();
|
importKeys();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// mImportSignUploadButton = (BootstrapButton) findViewById(R.id.import_sign_and_upload);
|
|
||||||
// mImportSignUploadButton.setOnClickListener(new OnClickListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onClick(View v) {
|
|
||||||
// signAndUploadOnClick();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||||
|
|
||||||
setupDrawerNavigation(savedInstanceState);
|
setupDrawerNavigation(savedInstanceState);
|
||||||
|
|
||||||
// set actionbar without home button if called from another app
|
|
||||||
// ActionBarHelper.setBackButton(this);
|
|
||||||
|
|
||||||
// set drop down navigation
|
// set drop down navigation
|
||||||
mNavigationStrings = getResources().getStringArray(R.array.import_action_list);
|
mNavigationStrings = getResources().getStringArray(R.array.import_action_list);
|
||||||
Context context = getSupportActionBar().getThemedContext();
|
Context context = getSupportActionBar().getThemedContext();
|
||||||
@ -125,6 +116,8 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
protected void handleActions(Bundle savedInstanceState, Intent intent) {
|
protected void handleActions(Bundle savedInstanceState, Intent intent) {
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
|
Uri dataUri = intent.getData();
|
||||||
|
String scheme = intent.getScheme();
|
||||||
|
|
||||||
if (extras == null) {
|
if (extras == null) {
|
||||||
extras = new Bundle();
|
extras = new Bundle();
|
||||||
@ -139,6 +132,15 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
action = ACTION_IMPORT_KEY;
|
action = ACTION_IMPORT_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scanning a fingerprint directly with Barcode Scanner
|
||||||
|
*/
|
||||||
|
if (scheme != null && scheme.toLowerCase(Locale.ENGLISH).equals(FINGERPRINT_SCHEME)) {
|
||||||
|
getSupportActionBar().setSelectedNavigationItem(0);
|
||||||
|
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[0]);
|
||||||
|
loadFromFingerprintUri(dataUri);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keychain's own Actions
|
* Keychain's own Actions
|
||||||
*/
|
*/
|
||||||
@ -160,14 +162,25 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
// directly load data
|
// directly load data
|
||||||
startListFragment(savedInstanceState, importData, null);
|
startListFragment(savedInstanceState, importData, null);
|
||||||
}
|
}
|
||||||
|
} else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) {
|
||||||
|
if (!extras.containsKey(EXTRA_QUERY)) {
|
||||||
|
Log.e(Constants.TAG, "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query' extra!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = extras.getString(EXTRA_QUERY);
|
||||||
|
|
||||||
|
// TODO: implement KEYSERVER!
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Internal actions
|
// Other actions
|
||||||
startListFragment(savedInstanceState, null, null);
|
startListFragment(savedInstanceState, null, null);
|
||||||
|
|
||||||
if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
|
if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
|
||||||
getSupportActionBar().setSelectedNavigationItem(1);
|
getSupportActionBar().setSelectedNavigationItem(1);
|
||||||
loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
|
loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
|
||||||
} else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) {
|
} else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) {
|
||||||
|
// also exposed in AndroidManifest
|
||||||
getSupportActionBar().setSelectedNavigationItem(2);
|
getSupportActionBar().setSelectedNavigationItem(2);
|
||||||
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[2]);
|
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[2]);
|
||||||
} else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
|
} else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
|
||||||
@ -239,6 +252,23 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
ft.commit();
|
ft.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadFromFingerprintUri(Uri dataUri) {
|
||||||
|
String fingerprint = dataUri.toString().split(":")[1].toLowerCase(Locale.ENGLISH);
|
||||||
|
|
||||||
|
Log.d(Constants.TAG, "fingerprint: " + fingerprint);
|
||||||
|
|
||||||
|
if (fingerprint.length() < 16) {
|
||||||
|
Toast.makeText(this, R.string.import_qr_code_too_short_fingerprint,
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent queryIntent = new Intent(this, KeyServerQueryActivity.class);
|
||||||
|
queryIntent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID);
|
||||||
|
queryIntent.putExtra(KeyServerQueryActivity.EXTRA_FINGERPRINT, fingerprint);
|
||||||
|
startActivity(queryIntent);
|
||||||
|
}
|
||||||
|
|
||||||
public void loadCallback(byte[] importData, String importFilename) {
|
public void loadCallback(byte[] importData, String importFilename) {
|
||||||
mListFragment.loadNew(importData, importFilename);
|
mListFragment.loadNew(importData, importFilename);
|
||||||
}
|
}
|
||||||
@ -413,19 +443,6 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importOnClick() {
|
|
||||||
importKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void signAndUploadOnClick() {
|
|
||||||
// // first, import!
|
|
||||||
// // importOnClick(view);
|
|
||||||
//
|
|
||||||
// // TODO: implement sign and upload!
|
|
||||||
// Toast.makeText(ImportKeysActivity.this, "Not implemented right now!", Toast.LENGTH_SHORT)
|
|
||||||
// .show();
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NFC
|
* NFC
|
||||||
*/
|
*/
|
||||||
|
@ -26,6 +26,7 @@ import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4;
|
|||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -101,8 +102,8 @@ public class ImportKeysQrCodeFragment extends Fragment {
|
|||||||
Log.d(Constants.TAG, "scanResult content: " + scanResult.getContents());
|
Log.d(Constants.TAG, "scanResult content: " + scanResult.getContents());
|
||||||
|
|
||||||
// look if it's fingerprint only
|
// look if it's fingerprint only
|
||||||
if (scanResult.getContents().toLowerCase(Locale.ENGLISH).startsWith("openpgp4fpr")) {
|
if (scanResult.getContents().toLowerCase(Locale.ENGLISH).startsWith(ImportKeysActivity.FINGERPRINT_SCHEME)) {
|
||||||
importFingerprint(scanResult.getContents().toLowerCase(Locale.ENGLISH));
|
importFingerprint(Uri.parse(scanResult.getContents()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,21 +129,8 @@ public class ImportKeysQrCodeFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importFingerprint(String uri) {
|
public void importFingerprint(Uri dataUri) {
|
||||||
String fingerprint = uri.split(":")[1];
|
mImportActivity.loadFromFingerprintUri(dataUri);
|
||||||
|
|
||||||
Log.d(Constants.TAG, "fingerprint: " + fingerprint);
|
|
||||||
|
|
||||||
if (fingerprint.length() < 16) {
|
|
||||||
Toast.makeText(getActivity(), R.string.import_qr_code_too_short_fingerprint,
|
|
||||||
Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent queryIntent = new Intent(getActivity(), KeyServerQueryActivity.class);
|
|
||||||
queryIntent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID);
|
|
||||||
queryIntent.putExtra(KeyServerQueryActivity.EXTRA_FINGERPRINT, fingerprint);
|
|
||||||
startActivity(queryIntent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importParts(String[] parts) {
|
private void importParts(String[] parts) {
|
||||||
|
@ -32,10 +32,12 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
|
|||||||
public class ImportKeysServerFragment extends Fragment {
|
public class ImportKeysServerFragment extends Fragment {
|
||||||
private BootstrapButton mButton;
|
private BootstrapButton mButton;
|
||||||
|
|
||||||
|
String mQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance of this fragment
|
* Creates new instance of this fragment
|
||||||
*/
|
*/
|
||||||
public static ImportKeysServerFragment newInstance() {
|
public static ImportKeysServerFragment newInstance(String query) {
|
||||||
ImportKeysServerFragment frag = new ImportKeysServerFragment();
|
ImportKeysServerFragment frag = new ImportKeysServerFragment();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
|
@ -83,7 +83,7 @@ public class ImportKeysListEntry implements Serializable {
|
|||||||
|
|
||||||
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
|
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
|
||||||
this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
|
this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
|
||||||
.getFingerprint());
|
.getFingerprint(), true);
|
||||||
this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
|
this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
|
||||||
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
|
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
|
||||||
int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
|
int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
|
||||||
|
@ -40,12 +40,14 @@ import android.widget.TextView;
|
|||||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||||
|
|
||||||
public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
|
public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
|
||||||
private static final String ARG_URI = "uri";
|
private static final String ARG_KEY_URI = "uri";
|
||||||
private static final String ARG_FINGERPRINT_ONLY = "fingerprint_only";
|
private static final String ARG_FINGERPRINT_ONLY = "fingerprint_only";
|
||||||
|
|
||||||
private ImageView mImage;
|
private ImageView mImage;
|
||||||
private TextView mText;
|
private TextView mText;
|
||||||
|
|
||||||
|
private boolean mFingerprintOnly;
|
||||||
|
|
||||||
private ArrayList<String> mContentList;
|
private ArrayList<String> mContentList;
|
||||||
private int mCounter;
|
private int mCounter;
|
||||||
|
|
||||||
@ -53,15 +55,11 @@ public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance of this dialog fragment
|
* Creates new instance of this dialog fragment
|
||||||
*
|
|
||||||
* @param content
|
|
||||||
* Content to be shared via QR Codes
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static ShareQrCodeDialogFragment newInstance(Uri dataUri, boolean fingerprintOnly) {
|
public static ShareQrCodeDialogFragment newInstance(Uri dataUri, boolean fingerprintOnly) {
|
||||||
ShareQrCodeDialogFragment frag = new ShareQrCodeDialogFragment();
|
ShareQrCodeDialogFragment frag = new ShareQrCodeDialogFragment();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putParcelable(ARG_URI, dataUri);
|
args.putParcelable(ARG_KEY_URI, dataUri);
|
||||||
args.putBoolean(ARG_FINGERPRINT_ONLY, fingerprintOnly);
|
args.putBoolean(ARG_FINGERPRINT_ONLY, fingerprintOnly);
|
||||||
|
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
@ -76,8 +74,8 @@ public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
|
|||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final Activity activity = getActivity();
|
final Activity activity = getActivity();
|
||||||
|
|
||||||
Uri dataUri = getArguments().getParcelable(ARG_URI);
|
Uri dataUri = getArguments().getParcelable(ARG_KEY_URI);
|
||||||
boolean fingerprintOnly = getArguments().getBoolean(ARG_FINGERPRINT_ONLY);
|
mFingerprintOnly = getArguments().getBoolean(ARG_FINGERPRINT_ONLY);
|
||||||
|
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
|
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
|
||||||
|
|
||||||
@ -90,29 +88,31 @@ public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
|
|||||||
mImage = (ImageView) view.findViewById(R.id.share_qr_code_dialog_image);
|
mImage = (ImageView) view.findViewById(R.id.share_qr_code_dialog_image);
|
||||||
mText = (TextView) view.findViewById(R.id.share_qr_code_dialog_text);
|
mText = (TextView) view.findViewById(R.id.share_qr_code_dialog_text);
|
||||||
|
|
||||||
// TODO
|
|
||||||
long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
|
|
||||||
|
|
||||||
String content = null;
|
String content = null;
|
||||||
if (fingerprintOnly) {
|
if (mFingerprintOnly) {
|
||||||
content = "openpgp4fpr:";
|
content = "openpgp4fpr:";
|
||||||
|
|
||||||
String fingerprint = PgpKeyHelper.convertKeyToHex(masterKeyId);
|
byte[] fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), dataUri);
|
||||||
|
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);
|
||||||
mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " "
|
|
||||||
+ fingerprint);
|
|
||||||
|
|
||||||
|
mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " " + fingerprint);
|
||||||
content = content + fingerprint;
|
content = content + fingerprint;
|
||||||
|
|
||||||
Log.d(Constants.TAG, "content: " + content);
|
Log.d(Constants.TAG, "content: " + content);
|
||||||
|
|
||||||
alert.setPositiveButton(R.string.btn_okay, null);
|
alert.setPositiveButton(R.string.btn_okay, null);
|
||||||
|
|
||||||
|
setQrCode(content);
|
||||||
} else {
|
} else {
|
||||||
mText.setText(R.string.share_qr_code_dialog_start);
|
mText.setText(R.string.share_qr_code_dialog_start);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
|
||||||
|
|
||||||
|
|
||||||
// get public keyring as ascii armored string
|
// get public keyring as ascii armored string
|
||||||
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
|
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
|
||||||
getActivity(), dataUri, new long[] { masterKeyId });
|
getActivity(), dataUri, new long[]{masterKeyId});
|
||||||
|
|
||||||
// TODO: binary?
|
// TODO: binary?
|
||||||
|
|
||||||
@ -122,55 +122,61 @@ public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
|
|||||||
// http://stackoverflow.com/questions/2620444/how-to-prevent-a-dialog-from-closing-when-a-button-is-clicked
|
// http://stackoverflow.com/questions/2620444/how-to-prevent-a-dialog-from-closing-when-a-button-is-clicked
|
||||||
alert.setPositiveButton(R.string.btn_next, null);
|
alert.setPositiveButton(R.string.btn_next, null);
|
||||||
alert.setNegativeButton(android.R.string.cancel, null);
|
alert.setNegativeButton(android.R.string.cancel, null);
|
||||||
|
|
||||||
|
mContentList = splitString(content, 1000);
|
||||||
|
|
||||||
|
// start with first
|
||||||
|
mCounter = 0;
|
||||||
|
updatePartsQrCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
mContentList = splitString(content, 1000);
|
|
||||||
|
|
||||||
// start with first
|
|
||||||
mCounter = 0;
|
|
||||||
updateQrCode();
|
|
||||||
|
|
||||||
return alert.create();
|
return alert.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
AlertDialog alertDialog = (AlertDialog) getDialog();
|
|
||||||
final Button backButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
|
|
||||||
final Button nextButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
|
||||||
|
|
||||||
backButton.setOnClickListener(new View.OnClickListener() {
|
if (!mFingerprintOnly) {
|
||||||
@Override
|
AlertDialog alertDialog = (AlertDialog) getDialog();
|
||||||
public void onClick(View v) {
|
final Button backButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);
|
||||||
if (mCounter > 0) {
|
final Button nextButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
mCounter--;
|
|
||||||
updateQrCode();
|
|
||||||
updateDialog(backButton, nextButton);
|
|
||||||
} else {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
nextButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
|
|
||||||
if (mCounter < mContentList.size() - 1) {
|
backButton.setOnClickListener(new View.OnClickListener() {
|
||||||
mCounter++;
|
@Override
|
||||||
updateQrCode();
|
public void onClick(View v) {
|
||||||
updateDialog(backButton, nextButton);
|
if (mCounter > 0) {
|
||||||
} else {
|
mCounter--;
|
||||||
dismiss();
|
updatePartsQrCode();
|
||||||
|
updateDialog(backButton, nextButton);
|
||||||
|
} else {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
nextButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
if (mCounter < mContentList.size() - 1) {
|
||||||
|
mCounter++;
|
||||||
|
updatePartsQrCode();
|
||||||
|
updateDialog(backButton, nextButton);
|
||||||
|
} else {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateQrCode() {
|
private void updatePartsQrCode() {
|
||||||
// Content: <counter>,<size>,<content>
|
// Content: <counter>,<size>,<content>
|
||||||
mImage.setImageBitmap(QrCodeUtils.getQRCodeBitmap(mCounter + "," + mContentList.size()
|
setQrCode(mCounter + "," + mContentList.size() + "," + mContentList.get(mCounter));
|
||||||
+ "," + mContentList.get(mCounter), QR_CODE_SIZE));
|
}
|
||||||
|
|
||||||
|
private void setQrCode(String data) {
|
||||||
|
mImage.setImageBitmap(QrCodeUtils.getQRCodeBitmap(data, QR_CODE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDialog(Button backButton, Button nextButton) {
|
private void updateDialog(Button backButton, Button nextButton) {
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_marginLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
android:id="@+id/import_clipboard_button"
|
android:id="@+id/import_clipboard_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="70dp"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:text="@string/import_clipboard_button"
|
android:text="@string/import_clipboard_button"
|
||||||
bootstrapbutton:bb_icon_left="fa-clipboard"
|
bootstrapbutton:bb_icon_left="fa-clipboard"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
android:id="@+id/import_keyserver_button"
|
android:id="@+id/import_keyserver_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="70dp"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:text="@string/menu_key_server"
|
android:text="@string/menu_key_server"
|
||||||
bootstrapbutton:bb_size="default"
|
bootstrapbutton:bb_size="default"
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="10dp"
|
android:padding="10dp"
|
||||||
android:orientation="horizontal" >
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
android:id="@+id/import_nfc_button"
|
android:id="@+id/import_nfc_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="60dp"
|
android:layout_height="70dp"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginLeft="10dp"
|
android:layout_marginLeft="10dp"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<com.beardedhen.androidbootstrap.BootstrapButton
|
<com.beardedhen.androidbootstrap.BootstrapButton
|
||||||
android:id="@+id/import_qrcode_button"
|
android:id="@+id/import_qrcode_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="70dp"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp"
|
||||||
android:text="@string/import_qr_scan_button"
|
android:text="@string/import_qr_scan_button"
|
||||||
bootstrapbutton:bb_icon_left="fa-barcode"
|
bootstrapbutton:bb_icon_left="fa-barcode"
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
10
README.md
10
README.md
@ -57,12 +57,12 @@ I am using the newest [Android Studio](http://developer.android.com/sdk/installi
|
|||||||
All Intents require user interaction, e.g. to finally encrypt the user needs to press the "Encrypt" button.
|
All Intents require user interaction, e.g. to finally encrypt the user needs to press the "Encrypt" button.
|
||||||
To do automatic encryption/decryption/sign/verify use the OpenPGP Remote API.
|
To do automatic encryption/decryption/sign/verify use the OpenPGP Remote API.
|
||||||
|
|
||||||
#### Android Intent actions provided by OpenPGP Keychain:
|
#### Android Intent actions:
|
||||||
|
|
||||||
* ``android.intent.action.VIEW`` connected to .gpg and .asc files: Import Key and Decrypt
|
* ``android.intent.action.VIEW`` connected to .gpg and .asc files: Import Key and Decrypt
|
||||||
* ``android.intent.action.SEND`` connected to all mime types (text/plain and every binary data like files and images): Encrypt and Decrypt
|
* ``android.intent.action.SEND`` connected to all mime types (text/plain and every binary data like files and images): Encrypt and Decrypt
|
||||||
|
|
||||||
#### OpenPGP Keychain specific Intent actions:
|
#### OpenPGP Keychain Intent actions:
|
||||||
|
|
||||||
* ``org.sufficientlysecure.keychain.action.ENCRYPT``
|
* ``org.sufficientlysecure.keychain.action.ENCRYPT``
|
||||||
* To encrypt or sign text, use extra ``text`` (type: ``String``)
|
* To encrypt or sign text, use extra ``text`` (type: ``String``)
|
||||||
@ -74,9 +74,15 @@ To do automatic encryption/decryption/sign/verify use the OpenPGP Remote API.
|
|||||||
* ``org.sufficientlysecure.keychain.action.IMPORT_KEY``
|
* ``org.sufficientlysecure.keychain.action.IMPORT_KEY``
|
||||||
* Extras: ``key_bytes`` (type: ``byte[]``)
|
* Extras: ``key_bytes`` (type: ``byte[]``)
|
||||||
* or set data ``Uri`` (``intent.setData()``) pointing to a file
|
* or set data ``Uri`` (``intent.setData()``) pointing to a file
|
||||||
|
* ``org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_KEYSERVER``
|
||||||
|
* Extras: ``query`` (type: ``String``)
|
||||||
* ``org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_QR_CODE``
|
* ``org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_QR_CODE``
|
||||||
* without extras, starts Barcode Scanner to get QR Code
|
* without extras, starts Barcode Scanner to get QR Code
|
||||||
|
|
||||||
|
#### OpenPGP Keychain special registered Intents:
|
||||||
|
* ``android.intent.action.VIEW`` with URIs following the ``openpgp4fpr`` schema. For example: ``openpgp4fpr:718C070100012282``. This is used in QR Codes, but could also be embedded into your website. (compatible with Monkeysphere's and Guardian Project's QR Codes)
|
||||||
|
* NFC (``android.nfc.action.NDEF_DISCOVERED``) on mime type ``application/pgp-keys`` (as specified in http://tools.ietf.org/html/rfc3156, section 7)
|
||||||
|
|
||||||
### OpenPGP Remote API
|
### OpenPGP Remote API
|
||||||
To do asyncronous fast encryption/decryption/sign/verify operations bind to the OpenPGP remote service.
|
To do asyncronous fast encryption/decryption/sign/verify operations bind to the OpenPGP remote service.
|
||||||
The API Demo contains all required AIDL files and a demo activity.
|
The API Demo contains all required AIDL files and a demo activity.
|
||||||
|
Loading…
Reference in New Issue
Block a user