aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenPGP-Keychain-API-Lib/src/org/sufficientlysecure/keychain/integration/KeychainContentProviderHelper.java13
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java129
-rw-r--r--README.md27
3 files changed, 109 insertions, 60 deletions
diff --git a/OpenPGP-Keychain-API-Lib/src/org/sufficientlysecure/keychain/integration/KeychainContentProviderHelper.java b/OpenPGP-Keychain-API-Lib/src/org/sufficientlysecure/keychain/integration/KeychainContentProviderHelper.java
index bc2a4ad7a..0b9211748 100644
--- a/OpenPGP-Keychain-API-Lib/src/org/sufficientlysecure/keychain/integration/KeychainContentProviderHelper.java
+++ b/OpenPGP-Keychain-API-Lib/src/org/sufficientlysecure/keychain/integration/KeychainContentProviderHelper.java
@@ -235,11 +235,18 @@ public class KeychainContentProviderHelper {
* @param keyId
* @return user id
*/
- public String getUserId(long keyId) {
+ public String getUserId(long keyId, boolean secretKeyrings) {
String userId = null;
try {
- Uri contentUri = ContentUris.withAppendedId(CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID,
- keyId);
+ Uri contentUri = null;
+ if (secretKeyrings) {
+ contentUri = ContentUris.withAppendedId(CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID,
+ keyId);
+ } else {
+ contentUri = ContentUris.withAppendedId(CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID,
+ keyId);
+ }
+
Cursor c = mContext.getContentResolver().query(contentUri, new String[] { "user_id" },
null, null, null);
if (c != null && c.moveToFirst()) {
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java
index 9d531dceb..04df935c9 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/provider/KeychainProvider.java
@@ -35,6 +35,7 @@ import org.sufficientlysecure.keychain.util.Log;
import android.content.ContentProvider;
import android.content.ContentValues;
+import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
@@ -47,6 +48,9 @@ import android.provider.BaseColumns;
import android.text.TextUtils;
public class KeychainProvider extends ContentProvider {
+ public static final String ACTION_BROADCAST_DATABASE_CHANGE = Constants.PACKAGE_NAME
+ + ".action.DATABASE_CHANGE";
+
private static final int PUBLIC_KEY_RING = 101;
private static final int PUBLIC_KEY_RING_BY_ROW_ID = 102;
private static final int PUBLIC_KEY_RING_BY_MASTER_KEY_ID = 103;
@@ -104,22 +108,26 @@ public class KeychainProvider extends ContentProvider {
* key_rings/public/like_email/_
* </pre>
*/
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC,
- PUBLIC_KEY_RING);
- matcher.addURI(authority,
- KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/#",
- PUBLIC_KEY_RING_BY_ROW_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
- + KeychainContract.PATH_BY_MASTER_KEY_ID + "/*", PUBLIC_KEY_RING_BY_MASTER_KEY_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
- + KeychainContract.PATH_BY_KEY_ID + "/*", PUBLIC_KEY_RING_BY_KEY_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
- + KeychainContract.PATH_BY_EMAILS + "/*", PUBLIC_KEY_RING_BY_EMAILS);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
- + KeychainContract.PATH_BY_EMAILS, PUBLIC_KEY_RING_BY_EMAILS); // without emails
- // specified
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
- + KeychainContract.PATH_BY_LIKE_EMAIL + "/*", PUBLIC_KEY_RING_BY_LIKE_EMAIL);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC, PUBLIC_KEY_RING);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/#", PUBLIC_KEY_RING_BY_ROW_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_MASTER_KEY_ID
+ + "/*", PUBLIC_KEY_RING_BY_MASTER_KEY_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_KEY_ID + "/*",
+ PUBLIC_KEY_RING_BY_KEY_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_EMAILS + "/*",
+ PUBLIC_KEY_RING_BY_EMAILS);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_EMAILS,
+ PUBLIC_KEY_RING_BY_EMAILS); // without emails
+ // specified
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_LIKE_EMAIL + "/*",
+ PUBLIC_KEY_RING_BY_LIKE_EMAIL);
/**
* public keys
@@ -129,10 +137,12 @@ public class KeychainProvider extends ContentProvider {
* key_rings/public/#/keys/#
* </pre>
*/
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
- + "/#/" + KeychainContract.PATH_KEYS, PUBLIC_KEY_RING_KEY);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
- + "/#/" + KeychainContract.PATH_KEYS + "/#", PUBLIC_KEY_RING_KEY_BY_ROW_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_KEYS,
+ PUBLIC_KEY_RING_KEY);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_KEYS + "/#",
+ PUBLIC_KEY_RING_KEY_BY_ROW_ID);
/**
* public user ids
@@ -142,10 +152,12 @@ public class KeychainProvider extends ContentProvider {
* key_rings/public/#/user_ids/#
* </pre>
*/
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
- + "/#/" + KeychainContract.PATH_USER_IDS, PUBLIC_KEY_RING_USER_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
- + "/#/" + KeychainContract.PATH_USER_IDS + "/#", PUBLIC_KEY_RING_USER_ID_BY_ROW_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_USER_IDS,
+ PUBLIC_KEY_RING_USER_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_USER_IDS + "/#",
+ PUBLIC_KEY_RING_USER_ID_BY_ROW_ID);
/**
* secret key rings
@@ -159,22 +171,26 @@ public class KeychainProvider extends ContentProvider {
* key_rings/secret/like_email/_
* </pre>
*/
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET,
- SECRET_KEY_RING);
- matcher.addURI(authority,
- KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/#",
- SECRET_KEY_RING_BY_ROW_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
- + KeychainContract.PATH_BY_MASTER_KEY_ID + "/*", SECRET_KEY_RING_BY_MASTER_KEY_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
- + KeychainContract.PATH_BY_KEY_ID + "/*", SECRET_KEY_RING_BY_KEY_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
- + KeychainContract.PATH_BY_EMAILS + "/*", SECRET_KEY_RING_BY_EMAILS);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
- + KeychainContract.PATH_BY_EMAILS, SECRET_KEY_RING_BY_EMAILS); // without emails
- // specified
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
- + KeychainContract.PATH_BY_LIKE_EMAIL + "/*", SECRET_KEY_RING_BY_LIKE_EMAIL);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET, SECRET_KEY_RING);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/#", SECRET_KEY_RING_BY_ROW_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_MASTER_KEY_ID
+ + "/*", SECRET_KEY_RING_BY_MASTER_KEY_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_KEY_ID + "/*",
+ SECRET_KEY_RING_BY_KEY_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_EMAILS + "/*",
+ SECRET_KEY_RING_BY_EMAILS);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_EMAILS,
+ SECRET_KEY_RING_BY_EMAILS); // without emails
+ // specified
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_LIKE_EMAIL + "/*",
+ SECRET_KEY_RING_BY_LIKE_EMAIL);
/**
* secret keys
@@ -184,10 +200,12 @@ public class KeychainProvider extends ContentProvider {
* key_rings/secret/#/keys/#
* </pre>
*/
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
- + "/#/" + KeychainContract.PATH_KEYS, SECRET_KEY_RING_KEY);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
- + "/#/" + KeychainContract.PATH_KEYS + "/#", SECRET_KEY_RING_KEY_BY_ROW_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_KEYS,
+ SECRET_KEY_RING_KEY);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_KEYS + "/#",
+ SECRET_KEY_RING_KEY_BY_ROW_ID);
/**
* secret user ids
@@ -197,10 +215,12 @@ public class KeychainProvider extends ContentProvider {
* key_rings/secret/#/user_ids/#
* </pre>
*/
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
- + "/#/" + KeychainContract.PATH_USER_IDS, SECRET_KEY_RING_USER_ID);
- matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
- + "/#/" + KeychainContract.PATH_USER_IDS + "/#", SECRET_KEY_RING_USER_ID_BY_ROW_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_USER_IDS,
+ SECRET_KEY_RING_USER_ID);
+ matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
+ + KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_USER_IDS + "/#",
+ SECRET_KEY_RING_USER_ID_BY_ROW_ID);
/**
* data stream
@@ -656,6 +676,7 @@ public class KeychainProvider extends ContentProvider {
// notify of changes in db
getContext().getContentResolver().notifyChange(uri, null);
+ sendBroadcastDatabaseChange();
return rowUri;
}
@@ -704,6 +725,7 @@ public class KeychainProvider extends ContentProvider {
// notify of changes in db
getContext().getContentResolver().notifyChange(uri, null);
+ sendBroadcastDatabaseChange();
return count;
}
@@ -761,6 +783,7 @@ public class KeychainProvider extends ContentProvider {
// notify of changes in db
getContext().getContentResolver().notifyChange(uri, null);
+ sendBroadcastDatabaseChange();
return count;
}
@@ -849,4 +872,14 @@ public class KeychainProvider extends ContentProvider {
File file = new File(getContext().getFilesDir().getAbsolutePath(), fileName);
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}
+
+ /**
+ * This broadcast is send system wide to inform other application that a keyring was inserted,
+ * updated, or deleted
+ */
+ private void sendBroadcastDatabaseChange() {
+ Intent intent = new Intent();
+ intent.setAction(ACTION_BROADCAST_DATABASE_CHANGE);
+ getContext().sendBroadcast(intent, Constants.PERMISSION_ACCESS_API);
+ }
}
diff --git a/README.md b/README.md
index c32c5c3e4..5bdf080df 100644
--- a/README.md
+++ b/README.md
@@ -66,14 +66,15 @@ See http://docs.oseems.com/general/application/eclipse/fix-gc-overhead-limit-exc
Android primitives to exchange data: Intent, Intent with return values, Send (also an Intent), Content Provider, AIDL
-## Permission
+## Possible Permissions
* ACCESS_API: Encrypt/Sign/Decrypt/Create keys without user interaction (intents, remote service), Read key information (not the actual keys)(content provider)
* ACCESS_KEYS: get and import actual public and secret keys (remote service)
-## Intents
+## Without Permissions
-### Without permission
+### Intents
+All Intents start with org.sufficientlysecure.keychain.action.
* 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
@@ -92,7 +93,9 @@ Android primitives to exchange data: Intent, Intent with return values, Send (al
* DECRYPT
* DECRYPT_FILE
-### With permission ACCESS_API
+## With permission ACCESS_API
+
+### Intents
* CREATE_KEYRING
* ENCRYPT_AND_RETURN
@@ -101,7 +104,11 @@ Android primitives to exchange data: Intent, Intent with return values, Send (al
* DECRYPT_AND_RETURN
* DECRYPT_STREAM_AND_RETURN
-## Content Provider
+### Broadcast Receiver
+On change of database the following broadcast is send.
+* DATABASE_CHANGE
+
+### Content Provider
* The whole content provider requires a permission (only read)
* Don't give out blobs (keys can be accessed by ACCESS_KEYS via remote service)
@@ -109,11 +116,13 @@ Android primitives to exchange data: Intent, Intent with return values, Send (al
* Look at android:grantUriPermissions especially for ApgServiceBlobProvider
* Only give out android:readPermission
-## ApgApiService (Remote Service)
-* ACCESS_API
+### ApgApiService (Remote Service)
+AIDL service
+
+## With permission ACCESS_KEYS
-## ApgKeyService (Remote Service)
-* ACCESS_KEYS
+### ApgKeyService (Remote Service)
+AIDL service to access actual private keyring objects
# Licenses
OpenPGP Kechain is licensed under Apache License v2.