mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-17 22:35:05 -05:00
Remove most of old API
This commit is contained in:
parent
9bcf733670
commit
b6a1bc770c
31
API.md
31
API.md
@ -2,33 +2,30 @@
|
|||||||
|
|
||||||
## Basic goals
|
## Basic goals
|
||||||
|
|
||||||
* Intents without permissions should only work based on user interaction (e.g. click a button in a dialog)
|
* Intents invoked by apps that are not registered by Keychain's App API must require user interaction (e.g. click a button in a dialog to actually encrypt!)
|
||||||
|
|
||||||
Android primitives to exchange data: Intent, Intent with return values, Send (also an Intent), Content Provider, AIDL
|
|
||||||
|
|
||||||
## Without Permissions
|
## Without Permissions
|
||||||
|
|
||||||
### Intents
|
### Intents
|
||||||
|
These Intents require user interaction!
|
||||||
|
|
||||||
All Intents start with ``org.sufficientlysecure.keychain.action.``
|
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.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
|
||||||
* ``IMPORT``
|
|
||||||
* ``IMPORT_FROM_FILE``
|
|
||||||
* ``IMPORT_FROM_QR_CODE``
|
* ``KEY_IMPORT`` with extra "keyring_bytes" or Uri in data with file schema
|
||||||
* ``IMPORT_FROM_NFC``
|
* ``KEY_IMPORT_FROM_QR_CODE`` without extras
|
||||||
* ``SHARE_KEYRING``
|
|
||||||
* ``SHARE_KEYRING_WITH_QR_CODE``
|
|
||||||
* ``SHARE_KEYRING_WITH_NFC``
|
* ``ENCRYPT`` TODO: explain extras (see source)
|
||||||
* ``EDIT_KEYRING``
|
|
||||||
* ``SELECT_PUBLIC_KEYRINGS``
|
|
||||||
* ``SELECT_SECRET_KEYRING``
|
|
||||||
* ``ENCRYPT``
|
|
||||||
* ``ENCRYPT_FILE``
|
* ``ENCRYPT_FILE``
|
||||||
* ``DECRYPT``
|
|
||||||
|
* ``DECRYPT`` TODO: explain extras (see source)
|
||||||
* ``DECRYPT_FILE``
|
* ``DECRYPT_FILE``
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- remove IMPORT, SHARE intents, simplify ENCRYPT and DECRYPT intents (include _FILE derivates like done in SEND based on file type)
|
|
||||||
- EDIT_KEYRING and CREATE_KEYRING, should be available via for registered apps
|
|
||||||
- new intent REGISTER_APP?
|
- new intent REGISTER_APP?
|
||||||
|
|
||||||
|
## App API
|
||||||
|
@ -67,28 +67,6 @@
|
|||||||
<uses-permission android:name="android.permission.NFC" />
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
<uses-permission android:name="com.fsck.k9.permission.READ_ATTACHMENT" />
|
<uses-permission android:name="com.fsck.k9.permission.READ_ATTACHMENT" />
|
||||||
|
|
||||||
<!-- TODO: disabled, old API -->
|
|
||||||
<!-- <permission-group -->
|
|
||||||
<!-- android:name="org.sufficientlysecure.keychain.permission-group.keychain" -->
|
|
||||||
<!-- android:description="@string/permission_group_description" -->
|
|
||||||
<!-- android:icon="@drawable/icon" -->
|
|
||||||
<!-- android:label="@string/permission_group_label" /> -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <permission -->
|
|
||||||
<!-- android:name="org.sufficientlysecure.keychain.permission.ACCESS_KEYS" -->
|
|
||||||
<!-- android:description="@string/permission_access_keys_description" -->
|
|
||||||
<!-- android:label="@string/permission_access_keys_label" -->
|
|
||||||
<!-- android:permissionGroup="org.sufficientlysecure.keychain.permission-group.keychain" -->
|
|
||||||
<!-- android:protectionLevel="dangerous" /> -->
|
|
||||||
<!-- <permission -->
|
|
||||||
<!-- android:name="org.sufficientlysecure.keychain.permission.ACCESS_API" -->
|
|
||||||
<!-- android:description="@string/permission_access_api_description" -->
|
|
||||||
<!-- android:label="@string/permission_access_api_label" -->
|
|
||||||
<!-- android:permissionGroup="org.sufficientlysecure.keychain.permission-group.keychain" -->
|
|
||||||
<!-- android:protectionLevel="dangerous" /> -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- android:allowBackup="false": Don't allow backup over adb backup or other apps! -->
|
<!-- android:allowBackup="false": Don't allow backup over adb backup or other apps! -->
|
||||||
<application
|
<application
|
||||||
android:name=".KeychainApplication"
|
android:name=".KeychainApplication"
|
||||||
@ -113,13 +91,15 @@
|
|||||||
android:label="@string/title_managePublicKeys"
|
android:label="@string/title_managePublicKeys"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:uiOptions="splitActionBarWhenNarrow" >
|
android:uiOptions="splitActionBarWhenNarrow" >
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.SEARCH" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<meta-data
|
<!-- <intent-filter> -->
|
||||||
android:name="android.app.searchable"
|
<!-- <action android:name="android.intent.action.SEARCH" /> -->
|
||||||
android:resource="@xml/searchable_public_keys" />
|
<!-- </intent-filter> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <meta-data -->
|
||||||
|
<!-- android:name="android.app.searchable" -->
|
||||||
|
<!-- android:resource="@xml/searchable_public_keys" /> -->
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.KeyListSecretActivity"
|
android:name=".ui.KeyListSecretActivity"
|
||||||
@ -127,31 +107,22 @@
|
|||||||
android:label="@string/title_manageSecretKeys"
|
android:label="@string/title_manageSecretKeys"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:uiOptions="splitActionBarWhenNarrow" >
|
android:uiOptions="splitActionBarWhenNarrow" >
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.SEARCH" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<meta-data
|
<!-- <intent-filter> -->
|
||||||
android:name="android.app.searchable"
|
<!-- <action android:name="android.intent.action.SEARCH" /> -->
|
||||||
android:resource="@xml/searchable_secret_keys" />
|
<!-- </intent-filter> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <meta-data -->
|
||||||
|
<!-- android:name="android.app.searchable" -->
|
||||||
|
<!-- android:resource="@xml/searchable_secret_keys" /> -->
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<!-- todo: export disabled, old API -->
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.EditKeyActivity"
|
android:name=".ui.EditKeyActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:exported="false"
|
|
||||||
android:label="@string/title_editKey"
|
android:label="@string/title_editKey"
|
||||||
android:uiOptions="splitActionBarWhenNarrow"
|
android:uiOptions="splitActionBarWhenNarrow"
|
||||||
android:windowSoftInputMode="stateHidden" >
|
android:windowSoftInputMode="stateHidden" >
|
||||||
|
|
||||||
<!-- TODO: disabled: old api! -->
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.EDIT_KEYRING" />
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.CREATE_KEYRING" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.SelectPublicKeyActivity"
|
android:name=".ui.SelectPublicKeyActivity"
|
||||||
@ -159,36 +130,30 @@
|
|||||||
android:label="@string/title_selectRecipients"
|
android:label="@string/title_selectRecipients"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:uiOptions="splitActionBarWhenNarrow" >
|
android:uiOptions="splitActionBarWhenNarrow" >
|
||||||
<intent-filter>
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.SELECT_PUBLIC_KEYRINGS" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<!-- <intent-filter> -->
|
||||||
</intent-filter>
|
<!-- <action android:name="android.intent.action.SEARCH" /> -->
|
||||||
<intent-filter>
|
<!-- </intent-filter> -->
|
||||||
<action android:name="android.intent.action.SEARCH" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<meta-data
|
|
||||||
android:name="android.app.searchable"
|
<!-- <meta-data -->
|
||||||
android:resource="@xml/searchable_public_keys" />
|
<!-- android:name="android.app.searchable" -->
|
||||||
|
<!-- android:resource="@xml/searchable_public_keys" /> -->
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.SelectSecretKeyActivity"
|
android:name=".ui.SelectSecretKeyActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:label="@string/title_selectSignature"
|
android:label="@string/title_selectSignature"
|
||||||
android:launchMode="singleTop" >
|
android:launchMode="singleTop" >
|
||||||
<intent-filter>
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.SELECT_SECRET_KEYRING" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<!-- <intent-filter> -->
|
||||||
</intent-filter>
|
<!-- <action android:name="android.intent.action.SEARCH" /> -->
|
||||||
<intent-filter>
|
<!-- </intent-filter> -->
|
||||||
<action android:name="android.intent.action.SEARCH" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<meta-data
|
|
||||||
android:name="android.app.searchable"
|
<!-- <meta-data -->
|
||||||
android:resource="@xml/searchable_secret_keys" />
|
<!-- android:name="android.app.searchable" -->
|
||||||
|
<!-- android:resource="@xml/searchable_secret_keys" /> -->
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.EncryptActivity"
|
android:name=".ui.EncryptActivity"
|
||||||
@ -197,16 +162,11 @@
|
|||||||
android:uiOptions="splitActionBarWhenNarrow"
|
android:uiOptions="splitActionBarWhenNarrow"
|
||||||
android:windowSoftInputMode="stateHidden" >
|
android:windowSoftInputMode="stateHidden" >
|
||||||
|
|
||||||
<!-- APG's own Actions -->
|
<!-- Keychain's own Actions -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.ENCRYPT" />
|
<action android:name="org.sufficientlysecure.keychain.action.ENCRYPT" />
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.ENCRYPT_FILE" />
|
<action android:name="org.sufficientlysecure.keychain.action.ENCRYPT_FILE" />
|
||||||
|
|
||||||
<!-- With permission ACCESS_API: -->
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.ENCRYPT_AND_RETURN" />
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.ENCRYPT_STREAM_AND_RETURN" />
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.GENERATE_SIGNATURE_AND_RETURN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
<data android:mimeType="*/*" />
|
<data android:mimeType="*/*" />
|
||||||
@ -227,15 +187,11 @@
|
|||||||
android:uiOptions="splitActionBarWhenNarrow"
|
android:uiOptions="splitActionBarWhenNarrow"
|
||||||
android:windowSoftInputMode="stateHidden" >
|
android:windowSoftInputMode="stateHidden" >
|
||||||
|
|
||||||
<!-- APG's own Actions -->
|
<!-- Keychain's own Actions -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
|
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT" />
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT_FILE" />
|
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT_FILE" />
|
||||||
|
|
||||||
<!-- With permission ACCESS_API: -->
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT_AND_RETURN" />
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.DECRYPT_STREAM_AND_RETURN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
<data android:mimeType="*/*" />
|
<data android:mimeType="*/*" />
|
||||||
@ -321,9 +277,9 @@
|
|||||||
android:label="@string/title_importKeys"
|
android:label="@string/title_importKeys"
|
||||||
android:uiOptions="splitActionBarWhenNarrow" >
|
android:uiOptions="splitActionBarWhenNarrow" >
|
||||||
|
|
||||||
<!-- APG's own Actions -->
|
<!-- Keychain's own Actions -->
|
||||||
<intent-filter android:label="@string/intent_import_key" >
|
<intent-filter android:label="@string/intent_import_key" >
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.IMPORT" />
|
<action android:name="org.sufficientlysecure.keychain.action.KEY_IMPORT" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
@ -331,9 +287,8 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
<!-- IMPORT again without mimeType to also allow data only without filename -->
|
<!-- IMPORT again without mimeType to also allow data only without filename -->
|
||||||
<intent-filter android:label="@string/intent_import_key" >
|
<intent-filter android:label="@string/intent_import_key" >
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.IMPORT" />
|
<action android:name="org.sufficientlysecure.keychain.action.KEY_IMPORT" />
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.IMPORT_FROM_QR_CODE" />
|
<action android:name="org.sufficientlysecure.keychain.action.KEY_IMPORT_FROM_QR_CODE" />
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.IMPORT_FROM_NFC" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@ -386,11 +341,6 @@
|
|||||||
android:label="@string/title_shareByNfc"
|
android:label="@string/title_shareByNfc"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:uiOptions="splitActionBarWhenNarrow" >
|
android:uiOptions="splitActionBarWhenNarrow" >
|
||||||
<intent-filter>
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.SHARE_KEYRING_WITH_NFC" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<!-- Handle NFC tags detected from outside our application -->
|
<!-- Handle NFC tags detected from outside our application -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -402,12 +352,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".ui.ShareActivity" >
|
<activity android:name=".ui.ShareActivity" >
|
||||||
<intent-filter>
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.SHARE_KEYRING" />
|
|
||||||
<action android:name="org.sufficientlysecure.keychain.action.SHARE_KEYRING_WITH_QR_CODE" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.HelpActivity"
|
android:name=".ui.HelpActivity"
|
||||||
@ -419,16 +363,7 @@
|
|||||||
android:process=":passphrase_cache" />
|
android:process=":passphrase_cache" />
|
||||||
<service android:name="org.sufficientlysecure.keychain.service.KeychainIntentService" />
|
<service android:name="org.sufficientlysecure.keychain.service.KeychainIntentService" />
|
||||||
|
|
||||||
<!-- TODO: disabled, old API! -->
|
<!-- TODO: Make this extended API -->
|
||||||
<!-- <service -->
|
|
||||||
<!-- android:name="org.sufficientlysecure.keychain.service.KeychainApiService" -->
|
|
||||||
<!-- android:enabled="true" -->
|
|
||||||
<!-- android:exported="true" -->
|
|
||||||
<!-- android:permission="org.sufficientlysecure.keychain.permission.ACCESS_API" -->
|
|
||||||
<!-- android:process=":remoteapi" > -->
|
|
||||||
<!-- <intent-filter> -->
|
|
||||||
<!-- <action android:name="org.sufficientlysecure.keychain.service.IKeychainApiService" /> -->
|
|
||||||
<!-- </intent-filter> -->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <meta-data -->
|
<!-- <meta-data -->
|
||||||
@ -452,18 +387,11 @@
|
|||||||
<!-- </service> -->
|
<!-- </service> -->
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="org.sufficientlysecure.keychain.provider.KeychainProviderInternal"
|
android:name="org.sufficientlysecure.keychain.provider.KeychainProvider"
|
||||||
android:authorities="org.sufficientlysecure.keychain.internal"
|
android:authorities="org.sufficientlysecure.keychain.provider"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<!-- TODO: disabled, old API -->
|
|
||||||
<!-- <provider -->
|
|
||||||
<!-- android:name="org.sufficientlysecure.keychain.provider.KeychainProviderExternal" -->
|
|
||||||
<!-- android:authorities="org.sufficientlysecure.keychain" -->
|
|
||||||
<!-- android:exported="true" -->
|
|
||||||
<!-- android:readPermission="org.sufficientlysecure.keychain.permission.ACCESS_API" /> -->
|
|
||||||
|
|
||||||
|
<!-- TODO: authority! Make this API with content provider uris -->
|
||||||
<!-- TODO: authority! -->
|
|
||||||
<!-- <provider -->
|
<!-- <provider -->
|
||||||
<!-- android:name="org.sufficientlysecure.keychain.provider.KeychainServiceBlobProvider" -->
|
<!-- android:name="org.sufficientlysecure.keychain.provider.KeychainServiceBlobProvider" -->
|
||||||
<!-- android:authorities="org.sufficientlysecure.keychain.provider.apgserviceblobprovider" -->
|
<!-- android:authorities="org.sufficientlysecure.keychain.provider.apgserviceblobprovider" -->
|
||||||
@ -476,6 +404,7 @@
|
|||||||
android:name="org.sufficientlysecure.keychain.remote_api.CryptoServiceActivity"
|
android:name="org.sufficientlysecure.keychain.remote_api.CryptoServiceActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:launchMode="singleTop"
|
||||||
android:process=":crypto" >
|
android:process=":crypto" >
|
||||||
|
|
||||||
<!-- Don't publish intents, they are only used internally! -->
|
<!-- Don't publish intents, they are only used internally! -->
|
||||||
|
@ -306,14 +306,6 @@
|
|||||||
<string name="progress_querying">querying…</string>
|
<string name="progress_querying">querying…</string>
|
||||||
<string name="progress_queryingServer">querying %s…</string>
|
<string name="progress_queryingServer">querying %s…</string>
|
||||||
|
|
||||||
<!-- permission strings -->
|
|
||||||
<string name="permission_group_label">OpenPGP Keychain</string>
|
|
||||||
<string name="permission_group_description">Permissions to use OpenPGP</string>
|
|
||||||
<string name="permission_access_api_label">Encrypt/Sign/Decrypt/Create keys without user interaction, Read key details of public and secret keys (The keys themselves can NOT be read.)</string>
|
|
||||||
<string name="permission_access_api_description">Encrypt/Sign/Decrypt/Create keys (by using Intents or Remote Service) without user interaction. Read key details of public and secret keys stored in OpenPGP, such as key ID and user IDs. The keys themselves can NOT be read.</string>
|
|
||||||
<string name="permission_access_keys_label">Import/Export actual public and secret keys</string>
|
|
||||||
<string name="permission_access_keys_description">Import and export actual private and public keys directly without user interaction.</string>
|
|
||||||
|
|
||||||
<!-- action strings -->
|
<!-- action strings -->
|
||||||
<string name="action_encrypt">Encrypt</string>
|
<string name="action_encrypt">Encrypt</string>
|
||||||
<string name="action_decrypt">Decrypt</string>
|
<string name="action_decrypt">Decrypt</string>
|
||||||
@ -335,7 +327,7 @@
|
|||||||
<string name="slow">slow</string>
|
<string name="slow">slow</string>
|
||||||
<string name="very_slow">very slow</string>
|
<string name="very_slow">very slow</string>
|
||||||
|
|
||||||
<!-- APG 2.0 -->
|
<!-- OpenPGP Keychain (2.0) -->
|
||||||
|
|
||||||
|
|
||||||
<!-- Dashboard -->
|
<!-- Dashboard -->
|
||||||
|
@ -20,7 +20,7 @@ import android.os.Environment;
|
|||||||
|
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
|
|
||||||
public static final boolean DEBUG = true;
|
public static final boolean DEBUG = BuildConfig.DEBUG;
|
||||||
|
|
||||||
public static final String TAG = "Keychain";
|
public static final String TAG = "Keychain";
|
||||||
|
|
||||||
@ -29,14 +29,11 @@ public final class Constants {
|
|||||||
// as defined in http://tools.ietf.org/html/rfc3156, section 7
|
// as defined in http://tools.ietf.org/html/rfc3156, section 7
|
||||||
public static final String NFC_MIME = "application/pgp-keys";
|
public static final String NFC_MIME = "application/pgp-keys";
|
||||||
|
|
||||||
public static final String PERMISSION_ACCESS_KEY_DATABASE = PACKAGE_NAME
|
|
||||||
+ ".permission.ACCESS_KEY_DATABASE";
|
|
||||||
public static final String PERMISSION_ACCESS_API = PACKAGE_NAME + ".permission.ACCESS_API";
|
|
||||||
|
|
||||||
public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
|
public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
|
||||||
|
|
||||||
public static final class path {
|
public static final class path {
|
||||||
public static final String APP_DIR = Environment.getExternalStorageDirectory() + "/OpenPGP-Keychain";
|
public static final String APP_DIR = Environment.getExternalStorageDirectory()
|
||||||
|
+ "/OpenPGP-Keychain";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class pref {
|
public static final class pref {
|
||||||
|
@ -66,11 +66,10 @@ public class KeychainContract {
|
|||||||
public static final int SECRET = 1;
|
public static final int SECRET = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String CONTENT_AUTHORITY_EXTERNAL = Constants.PACKAGE_NAME;
|
public static final String CONTENT_AUTHORITY = Constants.PACKAGE_NAME + ".provider";
|
||||||
public static final String CONTENT_AUTHORITY_INTERNAL = Constants.PACKAGE_NAME + ".internal";
|
|
||||||
|
|
||||||
private static final Uri BASE_CONTENT_URI_INTERNAL = Uri.parse("content://"
|
private static final Uri BASE_CONTENT_URI_INTERNAL = Uri.parse("content://"
|
||||||
+ CONTENT_AUTHORITY_INTERNAL);
|
+ CONTENT_AUTHORITY);
|
||||||
|
|
||||||
public static final String BASE_KEY_RINGS = "key_rings";
|
public static final String BASE_KEY_RINGS = "key_rings";
|
||||||
public static final String BASE_DATA = "data";
|
public static final String BASE_DATA = "data";
|
||||||
|
@ -34,7 +34,6 @@ import org.sufficientlysecure.keychain.util.Log;
|
|||||||
|
|
||||||
import android.content.ContentProvider;
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.UriMatcher;
|
import android.content.UriMatcher;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.DatabaseUtils;
|
import android.database.DatabaseUtils;
|
||||||
@ -46,11 +45,11 @@ import android.provider.BaseColumns;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
public class KeychainProvider extends ContentProvider {
|
public class KeychainProvider extends ContentProvider {
|
||||||
public static final String ACTION_BROADCAST_DATABASE_CHANGE = Constants.PACKAGE_NAME
|
// public static final String ACTION_BROADCAST_DATABASE_CHANGE = Constants.PACKAGE_NAME
|
||||||
+ ".action.DATABASE_CHANGE";
|
// + ".action.DATABASE_CHANGE";
|
||||||
|
//
|
||||||
public static final String EXTRA_BROADCAST_KEY_TYPE = "keyType";
|
// public static final String EXTRA_BROADCAST_KEY_TYPE = "key_type";
|
||||||
public static final String EXTRA_BROADCAST_CONTENT_ITEM_TYPE = "contentItemType";
|
// public static final String EXTRA_BROADCAST_CONTENT_ITEM_TYPE = "contentItemType";
|
||||||
|
|
||||||
private static final int PUBLIC_KEY_RING = 101;
|
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_ROW_ID = 102;
|
||||||
@ -84,22 +83,16 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
|
|
||||||
// private static final int DATA_STREAM = 401;
|
// private static final int DATA_STREAM = 401;
|
||||||
|
|
||||||
protected boolean mInternalProvider;
|
|
||||||
protected UriMatcher mUriMatcher;
|
protected UriMatcher mUriMatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build and return a {@link UriMatcher} that catches all {@link Uri} variations supported by
|
* Build and return a {@link UriMatcher} that catches all {@link Uri} variations supported by
|
||||||
* this {@link ContentProvider}.
|
* this {@link ContentProvider}.
|
||||||
*/
|
*/
|
||||||
protected UriMatcher buildUriMatcher(boolean internalProvider) {
|
protected UriMatcher buildUriMatcher() {
|
||||||
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
|
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||||
|
|
||||||
String authority;
|
String authority = KeychainContract.CONTENT_AUTHORITY;
|
||||||
if (internalProvider) {
|
|
||||||
authority = KeychainContract.CONTENT_AUTHORITY_INTERNAL;
|
|
||||||
} else {
|
|
||||||
authority = KeychainContract.CONTENT_AUTHORITY_EXTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* public key rings
|
* public key rings
|
||||||
@ -250,7 +243,7 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreate() {
|
public boolean onCreate() {
|
||||||
mUriMatcher = buildUriMatcher(mInternalProvider);
|
mUriMatcher = buildUriMatcher();
|
||||||
mApgDatabase = new KeychainDatabase(getContext());
|
mApgDatabase = new KeychainDatabase(getContext());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -359,11 +352,8 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
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 + "."
|
projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "."
|
||||||
+ KeyRingsColumns.MASTER_KEY_ID);
|
+ KeyRingsColumns.MASTER_KEY_ID);
|
||||||
// only give out keyRing blob when we are using the internal content provider
|
projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "."
|
||||||
if (mInternalProvider) {
|
+ KeyRingsColumns.KEY_RING_DATA);
|
||||||
projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "."
|
|
||||||
+ KeyRingsColumns.KEY_RING_DATA);
|
|
||||||
}
|
|
||||||
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;
|
||||||
@ -389,10 +379,7 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION);
|
projectionMap.put(KeysColumns.CREATION, KeysColumns.CREATION);
|
||||||
projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY);
|
projectionMap.put(KeysColumns.EXPIRY, KeysColumns.EXPIRY);
|
||||||
projectionMap.put(KeysColumns.KEY_RING_ROW_ID, KeysColumns.KEY_RING_ROW_ID);
|
projectionMap.put(KeysColumns.KEY_RING_ROW_ID, KeysColumns.KEY_RING_ROW_ID);
|
||||||
// only give out keyRing blob when we are using the internal content provider
|
projectionMap.put(KeysColumns.KEY_DATA, KeysColumns.KEY_DATA);
|
||||||
if (mInternalProvider) {
|
|
||||||
projectionMap.put(KeysColumns.KEY_DATA, KeysColumns.KEY_DATA);
|
|
||||||
}
|
|
||||||
projectionMap.put(KeysColumns.RANK, KeysColumns.RANK);
|
projectionMap.put(KeysColumns.RANK, KeysColumns.RANK);
|
||||||
|
|
||||||
return projectionMap;
|
return projectionMap;
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.provider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The same content provider as ApgProviderInternal except that it does not give out keyRing and key
|
|
||||||
* blob data when querying.
|
|
||||||
*
|
|
||||||
* This provider is exported with a readPermission in AndroidManifest.xml
|
|
||||||
*/
|
|
||||||
public class KeychainProviderExternal extends KeychainProvider {
|
|
||||||
|
|
||||||
public KeychainProviderExternal() {
|
|
||||||
mInternalProvider = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.provider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This provider is NOT exported in AndroidManifest.xml as it also return the actual secret keys
|
|
||||||
* from the database
|
|
||||||
*/
|
|
||||||
public class KeychainProviderInternal extends KeychainProvider {
|
|
||||||
|
|
||||||
public KeychainProviderInternal() {
|
|
||||||
mInternalProvider = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -239,7 +239,7 @@ public class ProviderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY_INTERNAL,
|
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY,
|
||||||
operations);
|
operations);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "applyBatch failed!", e);
|
Log.e(Constants.TAG, "applyBatch failed!", e);
|
||||||
@ -296,7 +296,7 @@ public class ProviderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY_INTERNAL,
|
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY,
|
||||||
operations);
|
operations);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "applyBatch failed!", e);
|
Log.e(Constants.TAG, "applyBatch failed!", e);
|
||||||
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.service;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.service.handler.IKeychainEncryptHandler;
|
|
||||||
import org.sufficientlysecure.keychain.service.handler.IKeychainDecryptHandler;
|
|
||||||
import org.sufficientlysecure.keychain.service.handler.IKeychainGetDecryptionKeyIdHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All methods are oneway, which means they are asynchronous and non-blocking.
|
|
||||||
* Results are returned into given Handler, which has to be implemented on client side.
|
|
||||||
*/
|
|
||||||
interface IKeychainApiService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt
|
|
||||||
*
|
|
||||||
* Either inputBytes or inputUri is given, the other should be null.
|
|
||||||
*
|
|
||||||
* @param inputBytes
|
|
||||||
* Byte array you want to encrypt
|
|
||||||
* @param inputUri
|
|
||||||
* Blob in ContentProvider you want to encrypt
|
|
||||||
* @param useAsciiArmor
|
|
||||||
* Convert bytes to ascii armored text to guard against encoding problems
|
|
||||||
* @param compression
|
|
||||||
* Compression: 0x21070001: none, 1: Zip, 2: Zlib, 3: BZip2
|
|
||||||
* @param encryptionKeyIds
|
|
||||||
* Ids of public keys used for encryption
|
|
||||||
* @param symmetricEncryptionAlgorithm
|
|
||||||
* 7: AES-128, 8: AES-192, 9: AES-256, 4: Blowfish, 10: Twofish, 3: CAST5,
|
|
||||||
* 6: DES, 2: Triple DES, 1: IDEA
|
|
||||||
* @param handler
|
|
||||||
* Results are returned to this Handler after successful encryption
|
|
||||||
*/
|
|
||||||
oneway void encryptAsymmetric(in byte[] inputBytes, in String inputUri, in boolean useAsciiArmor,
|
|
||||||
in int compression, in long[] encryptionKeyIds, in int symmetricEncryptionAlgorithm,
|
|
||||||
in IKeychainEncryptHandler handler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as encryptAsymmetric but using a passphrase for symmetric encryption
|
|
||||||
*
|
|
||||||
* @param encryptionPassphrase
|
|
||||||
* Passphrase for direct symmetric encryption using symmetricEncryptionAlgorithm
|
|
||||||
*/
|
|
||||||
oneway void encryptSymmetric(in byte[] inputBytes, in String inputUri, in boolean useAsciiArmor,
|
|
||||||
in int compression, in String encryptionPassphrase, in int symmetricEncryptionAlgorithm,
|
|
||||||
in IKeychainEncryptHandler handler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt and sign
|
|
||||||
*
|
|
||||||
* Either inputBytes or inputUri is given, the other should be null.
|
|
||||||
*
|
|
||||||
* @param inputBytes
|
|
||||||
* Byte array you want to encrypt
|
|
||||||
* @param inputUri
|
|
||||||
* Blob in ContentProvider you want to encrypt
|
|
||||||
* @param useAsciiArmor
|
|
||||||
* Convert bytes to ascii armored text to guard against encoding problems
|
|
||||||
* @param compression
|
|
||||||
* Compression: 0x21070001: none, 1: Zip, 2: Zlib, 3: BZip2
|
|
||||||
* @param encryptionKeyIds
|
|
||||||
* Ids of public keys used for encryption
|
|
||||||
* @param symmetricEncryptionAlgorithm
|
|
||||||
* 7: AES-128, 8: AES-192, 9: AES-256, 4: Blowfish, 10: Twofish, 3: CAST5,
|
|
||||||
* 6: DES, 2: Triple DES, 1: IDEA
|
|
||||||
* @param signatureKeyId
|
|
||||||
* Key id of key to sign with
|
|
||||||
* @param signatureHashAlgorithm
|
|
||||||
* 1: MD5, 3: RIPEMD-160, 2: SHA-1, 11: SHA-224, 8: SHA-256, 9: SHA-384,
|
|
||||||
* 10: SHA-512
|
|
||||||
* @param signatureForceV3
|
|
||||||
* Force V3 signatures
|
|
||||||
* @param signaturePassphrase
|
|
||||||
* Passphrase to unlock signature key
|
|
||||||
* @param handler
|
|
||||||
* Results are returned to this Handler after successful encryption and signing
|
|
||||||
*/
|
|
||||||
oneway void encryptAndSignAsymmetric(in byte[] inputBytes, in String inputUri,
|
|
||||||
in boolean useAsciiArmor, in int compression, in long[] encryptionKeyIds,
|
|
||||||
in int symmetricEncryptionAlgorithm, in long signatureKeyId, in int signatureHashAlgorithm,
|
|
||||||
in boolean signatureForceV3, in String signaturePassphrase,
|
|
||||||
in IKeychainEncryptHandler handler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as encryptAndSignAsymmetric but using a passphrase for symmetric encryption
|
|
||||||
*
|
|
||||||
* @param encryptionPassphrase
|
|
||||||
* Passphrase for direct symmetric encryption using symmetricEncryptionAlgorithm
|
|
||||||
*/
|
|
||||||
oneway void encryptAndSignSymmetric(in byte[] inputBytes, in String inputUri,
|
|
||||||
in boolean useAsciiArmor, in int compression, in String encryptionPassphrase,
|
|
||||||
in int symmetricEncryptionAlgorithm, in long signatureKeyId, in int signatureHashAlgorithm,
|
|
||||||
in boolean signatureForceV3, in String signaturePassphrase,
|
|
||||||
in IKeychainEncryptHandler handler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypts and verifies given input bytes. If no signature is present this method
|
|
||||||
* will only decrypt.
|
|
||||||
*
|
|
||||||
* @param inputBytes
|
|
||||||
* Byte array you want to decrypt and verify
|
|
||||||
* @param inputUri
|
|
||||||
* Blob in ContentProvider you want to decrypt and verify
|
|
||||||
* @param keyPassphrase
|
|
||||||
* Passphrase to unlock secret key for decryption.
|
|
||||||
* @param handler
|
|
||||||
* Handler where to return results to after successful encryption
|
|
||||||
*/
|
|
||||||
oneway void decryptAndVerifyAsymmetric(in byte[] inputBytes, in String inputUri,
|
|
||||||
in String keyPassphrase, in IKeychainDecryptHandler handler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as decryptAndVerifyAsymmetric but for symmetric decryption.
|
|
||||||
*
|
|
||||||
* @param encryptionPassphrase
|
|
||||||
* Passphrase to decrypt
|
|
||||||
*/
|
|
||||||
oneway void decryptAndVerifySymmetric(in byte[] inputBytes, in String inputUri,
|
|
||||||
in String encryptionPassphrase, in IKeychainDecryptHandler handler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
oneway void getDecryptionKeyId(in byte[] inputBytes, in String inputUri,
|
|
||||||
in IKeychainGetDecryptionKeyIdHandler handler);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,324 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.service;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
import java.security.SignatureException;
|
|
||||||
|
|
||||||
import org.spongycastle.openpgp.PGPException;
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
|
||||||
import org.sufficientlysecure.keychain.Id;
|
|
||||||
import org.sufficientlysecure.keychain.helper.PgpMain;
|
|
||||||
import org.sufficientlysecure.keychain.helper.PgpMain.PgpGeneralException;
|
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
import org.sufficientlysecure.keychain.service.IKeychainApiService;
|
|
||||||
import org.sufficientlysecure.keychain.service.handler.IKeychainDecryptHandler;
|
|
||||||
import org.sufficientlysecure.keychain.service.handler.IKeychainEncryptHandler;
|
|
||||||
import org.sufficientlysecure.keychain.service.handler.IKeychainGetDecryptionKeyIdHandler;
|
|
||||||
|
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
|
|
||||||
public class KeychainApiService extends Service {
|
|
||||||
Context mContext;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
mContext = this;
|
|
||||||
Log.d(Constants.TAG, "KeychainApiService, onCreate()");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
Log.d(Constants.TAG, "KeychainApiService, onDestroy()");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder onBind(Intent intent) {
|
|
||||||
return mBinder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private static void writeToOutputStream(InputStream is, OutputStream os) throws IOException {
|
|
||||||
// byte[] buffer = new byte[8];
|
|
||||||
// int len = 0;
|
|
||||||
// while ((len = is.read(buffer)) != -1) {
|
|
||||||
// os.write(buffer, 0, len);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private synchronized void encryptAndSignSafe(byte[] inputBytes, String inputUri,
|
|
||||||
boolean useAsciiArmor, int compression, long[] encryptionKeyIds,
|
|
||||||
String encryptionPassphrase, int symmetricEncryptionAlgorithm, long signatureKeyId,
|
|
||||||
int signatureHashAlgorithm, boolean signatureForceV3, String signaturePassphrase,
|
|
||||||
IKeychainEncryptHandler handler) throws RemoteException {
|
|
||||||
|
|
||||||
try {
|
|
||||||
// TODO use inputUri
|
|
||||||
|
|
||||||
// InputStream inStream = null;
|
|
||||||
// if (isBlob) {
|
|
||||||
// ContentResolver cr = getContentResolver();
|
|
||||||
// try {
|
|
||||||
// inStream = cr.openInputStream(Uri.parse(pArgs.getString(arg.BLOB.name())));
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// Log.e(TAG, "... exception on opening blob", e);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// inStream = new ByteArrayInputStream(pArgs.getString(arg.MESSAGE.name()).getBytes());
|
|
||||||
// }
|
|
||||||
// InputData in = new InputData(inStream, 0); // XXX Size second param?
|
|
||||||
|
|
||||||
// build InputData and write into OutputStream
|
|
||||||
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
|
||||||
long inputLength = inputBytes.length;
|
|
||||||
InputData input = new InputData(inputStream, inputLength);
|
|
||||||
|
|
||||||
OutputStream output = new ByteArrayOutputStream();
|
|
||||||
//
|
|
||||||
// PgpMain.encryptAndSign(mContext, null, input, output, useAsciiArmor, compression,
|
|
||||||
// encryptionKeyIds, encryptionPassphrase, symmetricEncryptionAlgorithm,
|
|
||||||
// signatureKeyId, signatureHashAlgorithm, signatureForceV3, signaturePassphrase);
|
|
||||||
//
|
|
||||||
// output.close();
|
|
||||||
|
|
||||||
// if (isBlob) {
|
|
||||||
// ContentResolver cr = getContentResolver();
|
|
||||||
// try {
|
|
||||||
// OutputStream outStream = cr.openOutputStream(Uri.parse(pArgs.getString(arg.BLOB
|
|
||||||
// .name())));
|
|
||||||
// writeToOutputStream(new ByteArrayInputStream(out.toString().getBytes()), outStream);
|
|
||||||
// outStream.close();
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// Log.e(TAG, "... exception on writing blob", e);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// pReturn.putString(ret.RESULT.name(), out.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
byte[] outputBytes = ((ByteArrayOutputStream) output).toByteArray();
|
|
||||||
|
|
||||||
// return over handler on client side
|
|
||||||
handler.onSuccess(outputBytes, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(Constants.TAG, "KeychainService, Exception!", e);
|
|
||||||
|
|
||||||
try {
|
|
||||||
handler.onException(getExceptionId(e), e.getMessage());
|
|
||||||
} catch (Exception t) {
|
|
||||||
Log.e(Constants.TAG, "Error returning exception to client", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void decryptAndVerifySafe(byte[] inputBytes, String inputUri,
|
|
||||||
String passphrase, boolean assumeSymmetric, IKeychainDecryptHandler handler)
|
|
||||||
throws RemoteException {
|
|
||||||
|
|
||||||
try {
|
|
||||||
// build InputData and write into OutputStream
|
|
||||||
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
|
||||||
long inputLength = inputBytes.length;
|
|
||||||
InputData inputData = new InputData(inputStream, inputLength);
|
|
||||||
|
|
||||||
OutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
Bundle outputBundle = PgpMain.decryptAndVerify(mContext, null, inputData, outputStream,
|
|
||||||
passphrase, assumeSymmetric);
|
|
||||||
|
|
||||||
outputStream.close();
|
|
||||||
|
|
||||||
byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
|
|
||||||
|
|
||||||
// get signature informations from bundle
|
|
||||||
boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE);
|
|
||||||
long signatureKeyId = outputBundle
|
|
||||||
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
|
||||||
String signatureUserId = outputBundle
|
|
||||||
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
|
||||||
boolean signatureSuccess = outputBundle
|
|
||||||
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS);
|
|
||||||
boolean signatureUnknown = outputBundle
|
|
||||||
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN);
|
|
||||||
|
|
||||||
// return over handler on client side
|
|
||||||
handler.onSuccess(outputBytes, null, signature, signatureKeyId, signatureUserId,
|
|
||||||
signatureSuccess, signatureUnknown);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(Constants.TAG, "KeychainService, Exception!", e);
|
|
||||||
|
|
||||||
try {
|
|
||||||
handler.onException(getExceptionId(e), e.getMessage());
|
|
||||||
} catch (Exception t) {
|
|
||||||
Log.e(Constants.TAG, "Error returning exception to client", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void getDecryptionKeySafe(byte[] inputBytes, String inputUri,
|
|
||||||
IKeychainGetDecryptionKeyIdHandler handler) {
|
|
||||||
|
|
||||||
// TODO: implement inputUri
|
|
||||||
|
|
||||||
try {
|
|
||||||
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
|
||||||
|
|
||||||
long secretKeyId = Id.key.none;
|
|
||||||
boolean symmetric;
|
|
||||||
|
|
||||||
try {
|
|
||||||
secretKeyId = PgpMain.getDecryptionKeyId(KeychainApiService.this, inputStream);
|
|
||||||
if (secretKeyId == Id.key.none) {
|
|
||||||
throw new PgpGeneralException(getString(R.string.error_noSecretKeyFound));
|
|
||||||
}
|
|
||||||
symmetric = false;
|
|
||||||
} catch (PgpMain.NoAsymmetricEncryptionException e) {
|
|
||||||
secretKeyId = Id.key.symmetric;
|
|
||||||
if (!PgpMain.hasSymmetricEncryption(KeychainApiService.this, inputStream)) {
|
|
||||||
throw new PgpGeneralException(getString(R.string.error_noKnownEncryptionFound));
|
|
||||||
}
|
|
||||||
symmetric = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.onSuccess(secretKeyId, symmetric);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(Constants.TAG, "KeychainService, Exception!", e);
|
|
||||||
|
|
||||||
try {
|
|
||||||
handler.onException(getExceptionId(e), e.getMessage());
|
|
||||||
} catch (Exception t) {
|
|
||||||
Log.e(Constants.TAG, "Error returning exception to client", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the implementation of the interface IKeychainService. All methods are oneway, meaning
|
|
||||||
* asynchronous and return to the client using IKeychainHandler.
|
|
||||||
*
|
|
||||||
* The real PGP code is located in PGPMain.
|
|
||||||
*/
|
|
||||||
private final IKeychainApiService.Stub mBinder = new IKeychainApiService.Stub() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encryptAsymmetric(byte[] inputBytes, String inputUri, boolean useAsciiArmor,
|
|
||||||
int compression, long[] encryptionKeyIds, int symmetricEncryptionAlgorithm,
|
|
||||||
IKeychainEncryptHandler handler) throws RemoteException {
|
|
||||||
|
|
||||||
encryptAndSignSafe(inputBytes, inputUri, useAsciiArmor, compression, encryptionKeyIds,
|
|
||||||
null, symmetricEncryptionAlgorithm, Id.key.none, 0, false, null, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encryptSymmetric(byte[] inputBytes, String inputUri, boolean useAsciiArmor,
|
|
||||||
int compression, String encryptionPassphrase, int symmetricEncryptionAlgorithm,
|
|
||||||
IKeychainEncryptHandler handler) throws RemoteException {
|
|
||||||
|
|
||||||
encryptAndSignSafe(inputBytes, inputUri, useAsciiArmor, compression, null,
|
|
||||||
encryptionPassphrase, symmetricEncryptionAlgorithm, Id.key.none, 0, false,
|
|
||||||
null, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encryptAndSignAsymmetric(byte[] inputBytes, String inputUri,
|
|
||||||
boolean useAsciiArmor, int compression, long[] encryptionKeyIds,
|
|
||||||
int symmetricEncryptionAlgorithm, long signatureKeyId, int signatureHashAlgorithm,
|
|
||||||
boolean signatureForceV3, String signaturePassphrase,
|
|
||||||
IKeychainEncryptHandler handler) throws RemoteException {
|
|
||||||
|
|
||||||
encryptAndSignSafe(inputBytes, inputUri, useAsciiArmor, compression, encryptionKeyIds,
|
|
||||||
null, symmetricEncryptionAlgorithm, signatureKeyId, signatureHashAlgorithm,
|
|
||||||
signatureForceV3, signaturePassphrase, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encryptAndSignSymmetric(byte[] inputBytes, String inputUri,
|
|
||||||
boolean useAsciiArmor, int compression, String encryptionPassphrase,
|
|
||||||
int symmetricEncryptionAlgorithm, long signatureKeyId, int signatureHashAlgorithm,
|
|
||||||
boolean signatureForceV3, String signaturePassphrase,
|
|
||||||
IKeychainEncryptHandler handler) throws RemoteException {
|
|
||||||
|
|
||||||
encryptAndSignSafe(inputBytes, inputUri, useAsciiArmor, compression, null,
|
|
||||||
encryptionPassphrase, symmetricEncryptionAlgorithm, signatureKeyId,
|
|
||||||
signatureHashAlgorithm, signatureForceV3, signaturePassphrase, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decryptAndVerifyAsymmetric(byte[] inputBytes, String inputUri,
|
|
||||||
String keyPassphrase, IKeychainDecryptHandler handler) throws RemoteException {
|
|
||||||
|
|
||||||
decryptAndVerifySafe(inputBytes, inputUri, keyPassphrase, false, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decryptAndVerifySymmetric(byte[] inputBytes, String inputUri,
|
|
||||||
String encryptionPassphrase, IKeychainDecryptHandler handler)
|
|
||||||
throws RemoteException {
|
|
||||||
|
|
||||||
decryptAndVerifySafe(inputBytes, inputUri, encryptionPassphrase, true, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getDecryptionKeyId(byte[] inputBytes, String inputUri,
|
|
||||||
IKeychainGetDecryptionKeyIdHandler handler) throws RemoteException {
|
|
||||||
|
|
||||||
getDecryptionKeySafe(inputBytes, inputUri, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As we can not throw an exception through Android RPC, we assign identifiers to the exception
|
|
||||||
* types.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private int getExceptionId(Exception e) {
|
|
||||||
if (e instanceof NoSuchProviderException) {
|
|
||||||
return 0;
|
|
||||||
} else if (e instanceof NoSuchAlgorithmException) {
|
|
||||||
return 1;
|
|
||||||
} else if (e instanceof SignatureException) {
|
|
||||||
return 2;
|
|
||||||
} else if (e instanceof IOException) {
|
|
||||||
return 3;
|
|
||||||
} else if (e instanceof PgpGeneralException) {
|
|
||||||
return 4;
|
|
||||||
} else if (e instanceof PGPException) {
|
|
||||||
return 5;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.service.handler;
|
|
||||||
|
|
||||||
interface IKeychainDecryptHandler {
|
|
||||||
|
|
||||||
oneway void onSuccess(in byte[] outputBytes, in String outputUri, in boolean signature,
|
|
||||||
in long signatureKeyId, in String signatureUserId, in boolean signatureSuccess,
|
|
||||||
in boolean signatureUnknown);
|
|
||||||
|
|
||||||
|
|
||||||
oneway void onException(in int exceptionNumber, in String message);
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.service.handler;
|
|
||||||
|
|
||||||
interface IKeychainEncryptHandler {
|
|
||||||
/**
|
|
||||||
* Either output or streamUri is given. One of them is null
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
oneway void onSuccess(in byte[] outputBytes, in String outputUri);
|
|
||||||
|
|
||||||
|
|
||||||
oneway void onException(in int exceptionNumber, in String message);
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.service.handler;
|
|
||||||
|
|
||||||
interface IKeychainGetDecryptionKeyIdHandler {
|
|
||||||
|
|
||||||
oneway void onSuccess(in long secretKeyId, in boolean symmetric);
|
|
||||||
|
|
||||||
|
|
||||||
oneway void onException(in int exceptionNumber, in String message);
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.service.handler;
|
|
||||||
|
|
||||||
interface IKeychainSignHandler {
|
|
||||||
/**
|
|
||||||
* Either output or streamUri is given. One of them is null
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
oneway void onSuccess(in byte[] outputBytes, in String outputUri);
|
|
||||||
|
|
||||||
|
|
||||||
oneway void onException(in int exceptionNumber, in String message);
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.sufficientlysecure.keychain.service.handler;
|
|
||||||
|
|
||||||
interface IKeychainVerifyHandler {
|
|
||||||
|
|
||||||
oneway void onSuccess(in boolean signature, in long signatureKeyId,
|
|
||||||
in String signatureUserId, in boolean signatureSuccess, in boolean signatureUnknown);
|
|
||||||
|
|
||||||
|
|
||||||
oneway void onException(in int exceptionNumber, in String message);
|
|
||||||
}
|
|
@ -17,13 +17,21 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.FileHelper;
|
import org.sufficientlysecure.keychain.helper.FileHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
|
||||||
import org.sufficientlysecure.keychain.helper.PgpHelper;
|
import org.sufficientlysecure.keychain.helper.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.PgpMain;
|
import org.sufficientlysecure.keychain.helper.PgpMain;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
@ -35,12 +43,8 @@ import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment;
|
|||||||
import org.sufficientlysecure.keychain.ui.dialog.LookupUnknownKeyDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.LookupUnknownKeyDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
|
|
||||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
|
||||||
import com.actionbarsherlock.view.Menu;
|
|
||||||
import com.actionbarsherlock.view.MenuItem;
|
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -60,14 +64,11 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.ViewFlipper;
|
import android.widget.ViewFlipper;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||||
import java.io.File;
|
import com.actionbarsherlock.view.Menu;
|
||||||
import java.io.FileInputStream;
|
import com.actionbarsherlock.view.MenuItem;
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public class DecryptActivity extends SherlockFragmentActivity {
|
public class DecryptActivity extends SherlockFragmentActivity {
|
||||||
|
|
||||||
/* Intents */
|
/* Intents */
|
||||||
@ -75,16 +76,10 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
public static final String ACTION_DECRYPT = Constants.INTENT_PREFIX + "DECRYPT";
|
public static final String ACTION_DECRYPT = Constants.INTENT_PREFIX + "DECRYPT";
|
||||||
public static final String ACTION_DECRYPT_FILE = Constants.INTENT_PREFIX + "DECRYPT_FILE";
|
public static final String ACTION_DECRYPT_FILE = Constants.INTENT_PREFIX + "DECRYPT_FILE";
|
||||||
|
|
||||||
// with permission
|
|
||||||
public static final String ACTION_DECRYPT_AND_RETURN = Constants.INTENT_PREFIX
|
|
||||||
+ "DECRYPT_AND_RETURN";
|
|
||||||
public static final String ACTION_DECRYPT_STREAM_AND_RETURN = Constants.INTENT_PREFIX
|
|
||||||
+ "DECRYPT_STREAM_AND_RETURN";
|
|
||||||
|
|
||||||
/* EXTRA keys for input */
|
/* EXTRA keys for input */
|
||||||
public static final String EXTRA_TEXT = "text";
|
public static final String EXTRA_TEXT = "text";
|
||||||
public static final String EXTRA_DATA = "data";
|
public static final String EXTRA_DATA = "data";
|
||||||
public static final String EXTRA_REPLY_TO = "replyTo";
|
public static final String EXTRA_REPLY_TO = "reply_to";
|
||||||
public static final String EXTRA_SUBJECT = "subject";
|
public static final String EXTRA_SUBJECT = "subject";
|
||||||
public static final String EXTRA_BINARY = "binary";
|
public static final String EXTRA_BINARY = "binary";
|
||||||
|
|
||||||
@ -248,11 +243,6 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// check permissions for intent actions without user interaction
|
|
||||||
String[] restrictedActions = new String[] { ACTION_DECRYPT_AND_RETURN };
|
|
||||||
OtherHelper.checkPackagePermissionForActions(this, this.getCallingPackage(),
|
|
||||||
Constants.PERMISSION_ACCESS_API, getIntent().getAction(), restrictedActions);
|
|
||||||
|
|
||||||
setContentView(R.layout.decrypt);
|
setContentView(R.layout.decrypt);
|
||||||
|
|
||||||
// set actionbar without home button if called from another app
|
// set actionbar without home button if called from another app
|
||||||
@ -456,38 +446,39 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
// end activity
|
// end activity
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
} else if (ACTION_DECRYPT_AND_RETURN.equals(action)) {
|
|
||||||
mReturnBinary = extras.getBoolean(EXTRA_BINARY, false);
|
|
||||||
|
|
||||||
if (mContentUri == null) {
|
|
||||||
mDataBytes = extras.getByteArray(EXTRA_DATA);
|
|
||||||
String data = extras.getString(EXTRA_TEXT);
|
|
||||||
if (data != null) {
|
|
||||||
Matcher matcher = PgpMain.PGP_MESSAGE.matcher(data);
|
|
||||||
if (matcher.matches()) {
|
|
||||||
data = matcher.group(1);
|
|
||||||
// replace non breakable spaces
|
|
||||||
data = data.replaceAll("\\xa0", " ");
|
|
||||||
mMessage.setText(data);
|
|
||||||
} else {
|
|
||||||
matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(data);
|
|
||||||
if (matcher.matches()) {
|
|
||||||
data = matcher.group(1);
|
|
||||||
// replace non breakable spaces
|
|
||||||
data = data.replaceAll("\\xa0", " ");
|
|
||||||
mMessage.setText(data);
|
|
||||||
mDecryptString = getString(R.string.btn_verify);
|
|
||||||
|
|
||||||
// build new action bar
|
|
||||||
invalidateOptionsMenu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mReturnResult = true;
|
|
||||||
} else if (ACTION_DECRYPT_STREAM_AND_RETURN.equals(action)) {
|
|
||||||
// TODO: Implement decrypt stream
|
|
||||||
}
|
}
|
||||||
|
// } else if (ACTION_DECRYPT_AND_RETURN.equals(action)) {
|
||||||
|
// mReturnBinary = extras.getBoolean(EXTRA_BINARY, false);
|
||||||
|
//
|
||||||
|
// if (mContentUri == null) {
|
||||||
|
// mDataBytes = extras.getByteArray(EXTRA_DATA);
|
||||||
|
// String data = extras.getString(EXTRA_TEXT);
|
||||||
|
// if (data != null) {
|
||||||
|
// Matcher matcher = PgpMain.PGP_MESSAGE.matcher(data);
|
||||||
|
// if (matcher.matches()) {
|
||||||
|
// data = matcher.group(1);
|
||||||
|
// // replace non breakable spaces
|
||||||
|
// data = data.replaceAll("\\xa0", " ");
|
||||||
|
// mMessage.setText(data);
|
||||||
|
// } else {
|
||||||
|
// matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(data);
|
||||||
|
// if (matcher.matches()) {
|
||||||
|
// data = matcher.group(1);
|
||||||
|
// // replace non breakable spaces
|
||||||
|
// data = data.replaceAll("\\xa0", " ");
|
||||||
|
// mMessage.setText(data);
|
||||||
|
// mDecryptString = getString(R.string.btn_verify);
|
||||||
|
//
|
||||||
|
// // build new action bar
|
||||||
|
// invalidateOptionsMenu();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// mReturnResult = true;
|
||||||
|
// } else if (ACTION_DECRYPT_STREAM_AND_RETURN.equals(action)) {
|
||||||
|
// // TODO: Implement decrypt stream
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void guessOutputFilename() {
|
private void guessOutputFilename() {
|
||||||
@ -662,7 +653,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
if (inStream.markSupported()) {
|
if (inStream.markSupported()) {
|
||||||
inStream.mark(200); //should probably set this to the max size of two pgpF objects, if it even needs to be anything other than 0.
|
inStream.mark(200); // should probably set this to the max size of two pgpF
|
||||||
|
// objects, if it even needs to be anything other than 0.
|
||||||
}
|
}
|
||||||
mSecretKeyId = PgpMain.getDecryptionKeyId(this, inStream);
|
mSecretKeyId = PgpMain.getDecryptionKeyId(this, inStream);
|
||||||
if (mSecretKeyId == Id.key.none) {
|
if (mSecretKeyId == Id.key.none) {
|
||||||
@ -781,7 +773,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mDataBytes);
|
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mDataBytes);
|
||||||
} else {
|
} else {
|
||||||
String message = mMessage.getText().toString();
|
String message = mMessage.getText().toString();
|
||||||
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, message.getBytes());
|
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES,
|
||||||
|
message.getBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,7 +870,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
|
|
||||||
if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) {
|
if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) {
|
||||||
mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
|
mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
|
||||||
} else if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
|
} else if (returnData
|
||||||
|
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
|
||||||
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
|
mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
|
||||||
Toast.makeText(DecryptActivity.this,
|
Toast.makeText(DecryptActivity.this,
|
||||||
R.string.unknownSignatureKeyTouchToLookUp, Toast.LENGTH_LONG)
|
R.string.unknownSignatureKeyTouchToLookUp, Toast.LENGTH_LONG)
|
||||||
@ -952,4 +946,3 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,20 +65,20 @@ import com.actionbarsherlock.app.SherlockFragmentActivity;
|
|||||||
|
|
||||||
public class EditKeyActivity extends SherlockFragmentActivity {
|
public class EditKeyActivity extends SherlockFragmentActivity {
|
||||||
|
|
||||||
// possible intent actions for this activity
|
// Actions for internal use only:
|
||||||
public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEYRING";
|
public static final String ACTION_CREATE_KEY = Constants.INTENT_PREFIX + "CREATE_KEY";
|
||||||
public static final String ACTION_EDIT_KEY = Constants.INTENT_PREFIX + "EDIT_KEYRING";
|
public static final String ACTION_EDIT_KEY = Constants.INTENT_PREFIX + "EDIT_KEY";
|
||||||
|
|
||||||
// possible extra keys
|
// possible extra keys
|
||||||
public static final String EXTRA_USER_IDS = "userIds";
|
public static final String EXTRA_USER_IDS = "user_ids";
|
||||||
public static final String EXTRA_NO_PASSPHRASE = "noPassphrase";
|
public static final String EXTRA_NO_PASSPHRASE = "no_passphrase";
|
||||||
public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generateDefaultKeys";
|
public static final String EXTRA_GENERATE_DEFAULT_KEYS = "generate_default_keys";
|
||||||
public static final String EXTRA_MASTER_KEY_ID = "masterKeyId";
|
public static final String EXTRA_MASTER_KEY_ID = "master_key_id";
|
||||||
public static final String EXTRA_MASTER_CAN_SIGN = "masterCanSign";
|
public static final String EXTRA_MASTER_CAN_SIGN = "master_can_sign";
|
||||||
|
|
||||||
// results when saving key
|
// results when saving key
|
||||||
public static final String RESULT_EXTRA_MASTER_KEY_ID = "masterKeyId";
|
public static final String RESULT_EXTRA_MASTER_KEY_ID = "master_key_id";
|
||||||
public static final String RESULT_EXTRA_USER_ID = "userId";
|
public static final String RESULT_EXTRA_USER_ID = "user_id";
|
||||||
|
|
||||||
private ActionBar mActionBar;
|
private ActionBar mActionBar;
|
||||||
|
|
||||||
@ -106,12 +106,6 @@ public class EditKeyActivity extends SherlockFragmentActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// TODO: disabled, old API!
|
|
||||||
// check permissions for intent actions without user interaction
|
|
||||||
// String[] restrictedActions = new String[] { ACTION_CREATE_KEY };
|
|
||||||
// OtherHelper.checkPackagePermissionForActions(this, this.getCallingPackage(),
|
|
||||||
// Constants.PERMISSION_ACCESS_API, getIntent().getAction(), restrictedActions);
|
|
||||||
|
|
||||||
// Inflate a "Done"/"Cancel" custom action bar view
|
// Inflate a "Done"/"Cancel" custom action bar view
|
||||||
final LayoutInflater inflater = (LayoutInflater) getSupportActionBar().getThemedContext()
|
final LayoutInflater inflater = (LayoutInflater) getSupportActionBar().getThemedContext()
|
||||||
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
.getSystemService(LAYOUT_INFLATER_SERVICE);
|
||||||
|
@ -30,7 +30,6 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.FileHelper;
|
import org.sufficientlysecure.keychain.helper.FileHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
|
||||||
import org.sufficientlysecure.keychain.helper.PgpHelper;
|
import org.sufficientlysecure.keychain.helper.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.helper.PgpMain;
|
import org.sufficientlysecure.keychain.helper.PgpMain;
|
||||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||||
@ -77,29 +76,20 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT";
|
public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT";
|
||||||
public static final String ACTION_ENCRYPT_FILE = Constants.INTENT_PREFIX + "ENCRYPT_FILE";
|
public static final String ACTION_ENCRYPT_FILE = Constants.INTENT_PREFIX + "ENCRYPT_FILE";
|
||||||
|
|
||||||
// with permission
|
|
||||||
public static final String ACTION_ENCRYPT_AND_RETURN = Constants.INTENT_PREFIX
|
|
||||||
+ "ENCRYPT_AND_RETURN";
|
|
||||||
public static final String ACTION_ENCRYPT_STREAM_AND_RETURN = Constants.INTENT_PREFIX
|
|
||||||
+ "ENCRYPT_STREAM_AND_RETURN";
|
|
||||||
public static final String ACTION_GENERATE_SIGNATURE_AND_RETURN = Constants.INTENT_PREFIX
|
|
||||||
+ "GENERATE_SIGNATURE_AND_RETURN";
|
|
||||||
|
|
||||||
/* EXTRA keys for input */
|
/* EXTRA keys for input */
|
||||||
public static final String EXTRA_TEXT = "text";
|
public static final String EXTRA_TEXT = "text";
|
||||||
public static final String EXTRA_DATA = "data";
|
public static final String EXTRA_DATA = "data";
|
||||||
public static final String EXTRA_ASCII_ARMOUR = "asciiArmour";
|
public static final String EXTRA_ASCII_ARMOUR = "ascii_armor";
|
||||||
public static final String EXTRA_SEND_TO = "sendTo";
|
public static final String EXTRA_SEND_TO = "send_to";
|
||||||
public static final String EXTRA_SUBJECT = "subject";
|
public static final String EXTRA_SUBJECT = "subject";
|
||||||
public static final String EXTRA_SIGNATURE_KEY_ID = "signatureKeyId";
|
public static final String EXTRA_SIGNATURE_KEY_ID = "signature_key_id";
|
||||||
public static final String EXTRA_ENCRYPTION_KEY_IDS = "encryptionKeyIds";
|
public static final String EXTRA_ENCRYPTION_KEY_IDS = "encryption_key_ids";
|
||||||
|
|
||||||
private String mSubject = null;
|
private String mSubject = null;
|
||||||
private String mSendTo = null;
|
private String mSendTo = null;
|
||||||
|
|
||||||
private long mEncryptionKeyIds[] = null;
|
private long mEncryptionKeyIds[] = null;
|
||||||
|
|
||||||
private boolean mEncryptImmediately = false;
|
|
||||||
private EditText mMessage = null;
|
private EditText mMessage = null;
|
||||||
private Button mSelectKeysButton = null;
|
private Button mSelectKeysButton = null;
|
||||||
|
|
||||||
@ -197,12 +187,6 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// check permissions for intent actions without user interaction
|
|
||||||
String[] restrictedActions = new String[] { ACTION_ENCRYPT_AND_RETURN,
|
|
||||||
ACTION_GENERATE_SIGNATURE_AND_RETURN, ACTION_ENCRYPT_STREAM_AND_RETURN };
|
|
||||||
OtherHelper.checkPackagePermissionForActions(this, this.getCallingPackage(),
|
|
||||||
Constants.PERMISSION_ACCESS_API, getIntent().getAction(), restrictedActions);
|
|
||||||
|
|
||||||
setContentView(R.layout.encrypt);
|
setContentView(R.layout.encrypt);
|
||||||
|
|
||||||
// set actionbar without home button if called from another app
|
// set actionbar without home button if called from another app
|
||||||
@ -217,26 +201,26 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
updateSource();
|
updateSource();
|
||||||
updateMode();
|
updateMode();
|
||||||
|
|
||||||
if (mEncryptImmediately) {
|
// if (mEncryptImmediately) {
|
||||||
mSourcePrevious.setClickable(false);
|
// mSourcePrevious.setClickable(false);
|
||||||
mSourcePrevious.setEnabled(false);
|
// mSourcePrevious.setEnabled(false);
|
||||||
mSourcePrevious.setVisibility(View.INVISIBLE);
|
// mSourcePrevious.setVisibility(View.INVISIBLE);
|
||||||
|
//
|
||||||
mSourceNext.setClickable(false);
|
// mSourceNext.setClickable(false);
|
||||||
mSourceNext.setEnabled(false);
|
// mSourceNext.setEnabled(false);
|
||||||
mSourceNext.setVisibility(View.INVISIBLE);
|
// mSourceNext.setVisibility(View.INVISIBLE);
|
||||||
|
//
|
||||||
mSourceLabel.setClickable(false);
|
// mSourceLabel.setClickable(false);
|
||||||
mSourceLabel.setEnabled(false);
|
// mSourceLabel.setEnabled(false);
|
||||||
}
|
// }
|
||||||
|
|
||||||
updateActionBarButtons();
|
updateActionBarButtons();
|
||||||
|
|
||||||
if (mEncryptImmediately
|
// if (mEncryptImmediately
|
||||||
&& (mMessage.getText().length() > 0 || mData != null)
|
// && (mMessage.getText().length() > 0 || mData != null)
|
||||||
&& ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || mSecretKeyId != 0)) {
|
// && ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || mSecretKeyId != 0)) {
|
||||||
encryptClicked();
|
// encryptClicked();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -276,16 +260,16 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ACTION_ENCRYPT_AND_RETURN.equals(action)
|
// if (ACTION_ENCRYPT_AND_RETURN.equals(action)
|
||||||
|| ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) {
|
// || ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) {
|
||||||
mEncryptImmediately = true;
|
// mEncryptImmediately = true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) {
|
// if (ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) {
|
||||||
mGenerateSignature = true;
|
// mGenerateSignature = true;
|
||||||
mOverrideAsciiArmour = true;
|
// mOverrideAsciiArmour = true;
|
||||||
mAsciiArmorDemand = false;
|
// mAsciiArmorDemand = false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (extras.containsKey(EXTRA_ASCII_ARMOUR)) {
|
if (extras.containsKey(EXTRA_ASCII_ARMOUR)) {
|
||||||
mAsciiArmorDemand = extras.getBoolean(EXTRA_ASCII_ARMOUR, true);
|
mAsciiArmorDemand = extras.getBoolean(EXTRA_ASCII_ARMOUR, true);
|
||||||
@ -309,8 +293,9 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
/**
|
/**
|
||||||
* Main Actions
|
* Main Actions
|
||||||
*/
|
*/
|
||||||
if (ACTION_ENCRYPT.equals(action) || ACTION_ENCRYPT_AND_RETURN.equals(action)
|
// if (ACTION_ENCRYPT.equals(action) || ACTION_ENCRYPT_AND_RETURN.equals(action)
|
||||||
|| ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) {
|
// || ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) {
|
||||||
|
if (ACTION_ENCRYPT.equals(action)) {
|
||||||
if (textData != null) {
|
if (textData != null) {
|
||||||
mMessage.setText(textData);
|
mMessage.setText(textData);
|
||||||
}
|
}
|
||||||
@ -340,10 +325,10 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
// end activity
|
// end activity
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
} else if (ACTION_ENCRYPT_STREAM_AND_RETURN.equals(action)) {
|
// } else if (ACTION_ENCRYPT_STREAM_AND_RETURN.equals(action)) {
|
||||||
// TODO: Set mStreamAndReturnUri that is used later to encrypt a stream!
|
// // TODO: Set mStreamAndReturnUri that is used later to encrypt a stream!
|
||||||
|
//
|
||||||
mStreamAndReturnUri = uri;
|
// mStreamAndReturnUri = uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,31 +455,31 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
mSourceLabel.setText(R.string.label_message);
|
mSourceLabel.setText(R.string.label_message);
|
||||||
|
|
||||||
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
|
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
|
||||||
if (mEncryptImmediately) {
|
// if (mEncryptImmediately) {
|
||||||
setActionbarButtons(true, R.string.btn_encrypt, false, 0);
|
// setActionbarButtons(true, R.string.btn_encrypt, false, 0);
|
||||||
} else {
|
// } else {
|
||||||
setActionbarButtons(true, R.string.btn_encryptAndEmail, true,
|
setActionbarButtons(true, R.string.btn_encryptAndEmail, true,
|
||||||
R.string.btn_encryptToClipboard);
|
R.string.btn_encryptToClipboard);
|
||||||
}
|
// }
|
||||||
} else {
|
} else {
|
||||||
if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) {
|
if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) {
|
||||||
if (mSecretKeyId == 0) {
|
if (mSecretKeyId == 0) {
|
||||||
setActionbarButtons(false, 0, false, 0);
|
setActionbarButtons(false, 0, false, 0);
|
||||||
} else {
|
} else {
|
||||||
if (mEncryptImmediately) {
|
// if (mEncryptImmediately) {
|
||||||
setActionbarButtons(true, R.string.btn_sign, false, 0);
|
// setActionbarButtons(true, R.string.btn_sign, false, 0);
|
||||||
} else {
|
// } else {
|
||||||
setActionbarButtons(true, R.string.btn_signAndEmail, true,
|
setActionbarButtons(true, R.string.btn_signAndEmail, true,
|
||||||
R.string.btn_signToClipboard);
|
R.string.btn_signToClipboard);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mEncryptImmediately) {
|
// if (mEncryptImmediately) {
|
||||||
setActionbarButtons(true, R.string.btn_encrypt, false, 0);
|
// setActionbarButtons(true, R.string.btn_encrypt, false, 0);
|
||||||
} else {
|
// } else {
|
||||||
setActionbarButtons(true, R.string.btn_encryptAndEmail, true,
|
setActionbarButtons(true, R.string.btn_encryptAndEmail, true,
|
||||||
R.string.btn_encryptToClipboard);
|
R.string.btn_encryptToClipboard);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -726,7 +711,8 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, mData);
|
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, mData);
|
||||||
} else {
|
} else {
|
||||||
String message = mMessage.getText().toString();
|
String message = mMessage.getText().toString();
|
||||||
if (signOnly && !mEncryptImmediately) {
|
// if (signOnly && !mEncryptImmediately) {
|
||||||
|
if (signOnly) {
|
||||||
fixBadCharactersForGmail(message);
|
fixBadCharactersForGmail(message);
|
||||||
}
|
}
|
||||||
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes());
|
data.putByteArray(KeychainIntentService.ENCRYPT_MESSAGE_BYTES, message.getBytes());
|
||||||
@ -769,13 +755,13 @@ public class EncryptActivity extends SherlockFragmentActivity {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Id.target.email:
|
case Id.target.email:
|
||||||
if (mEncryptImmediately) {
|
// if (mEncryptImmediately) {
|
||||||
Intent intent = new Intent();
|
// Intent intent = new Intent();
|
||||||
intent.putExtras(data);
|
// intent.putExtras(data);
|
||||||
setResult(RESULT_OK, intent);
|
// setResult(RESULT_OK, intent);
|
||||||
finish();
|
// finish();
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING);
|
output = data.getString(KeychainIntentService.RESULT_ENCRYPTED_STRING);
|
||||||
Log.d(Constants.TAG, "output: " + output);
|
Log.d(Constants.TAG, "output: " + output);
|
||||||
|
@ -48,17 +48,20 @@ import com.google.zxing.integration.android.IntentIntegrator;
|
|||||||
import com.google.zxing.integration.android.IntentResult;
|
import com.google.zxing.integration.android.IntentResult;
|
||||||
|
|
||||||
public class ImportKeysActivity extends SherlockFragmentActivity {
|
public class ImportKeysActivity extends SherlockFragmentActivity {
|
||||||
public static final String ACTION_IMPORT = Constants.INTENT_PREFIX + "IMPORT";
|
public static final String ACTION_KEY_IMPORT = Constants.INTENT_PREFIX + "KEY_IMPORT";
|
||||||
public static final String ACTION_IMPORT_FROM_FILE = Constants.INTENT_PREFIX
|
public static final String ACTION_KEY_IMPORT_FROM_QR_CODE = Constants.INTENT_PREFIX
|
||||||
+ "IMPORT_FROM_FILE";
|
+ "KEY_IMPORT_FROM_QR_CODE";
|
||||||
public static final String ACTION_IMPORT_FROM_QR_CODE = Constants.INTENT_PREFIX
|
|
||||||
+ "IMPORT_FROM_QR_CODE";
|
// Actions for internal use only:
|
||||||
public static final String ACTION_IMPORT_FROM_NFC = Constants.INTENT_PREFIX + "IMPORT_FROM_NFC";
|
public static final String ACTION_KEY_IMPORT_FROM_FILE = Constants.INTENT_PREFIX
|
||||||
|
+ "KEY_IMPORT_FROM_FILE";
|
||||||
|
public static final String ACTION_KEY_IMPORT_FROM_NFC = Constants.INTENT_PREFIX
|
||||||
|
+ "KEY_IMPORT_FROM_NFC";
|
||||||
|
|
||||||
// only used by IMPORT
|
// only used by IMPORT
|
||||||
public static final String EXTRA_TEXT = "text";
|
public static final String EXTRA_KEYRING_BYTES = "keyring_bytes";
|
||||||
public static final String EXTRA_KEYRING_BYTES = "keyringBytes";
|
|
||||||
|
|
||||||
|
// TODO: import keys from server
|
||||||
// public static final String EXTRA_KEY_ID = "keyId";
|
// public static final String EXTRA_KEY_ID = "keyId";
|
||||||
|
|
||||||
protected String mImportFilename;
|
protected String mImportFilename;
|
||||||
@ -140,35 +143,32 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
|
|||||||
* Android Standard Actions
|
* Android Standard Actions
|
||||||
*/
|
*/
|
||||||
if (Intent.ACTION_VIEW.equals(action)) {
|
if (Intent.ACTION_VIEW.equals(action)) {
|
||||||
// Android's Action when opening file associated to APG (see AndroidManifest.xml)
|
// Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
|
||||||
// override action to delegate it to APGs ACTION_IMPORT
|
// override action to delegate it to Keychains ACTION_IMPORT
|
||||||
action = ACTION_IMPORT;
|
action = ACTION_KEY_IMPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APG's own Actions
|
* APG's own Actions
|
||||||
*/
|
*/
|
||||||
if (ACTION_IMPORT.equals(action)) {
|
if (ACTION_KEY_IMPORT.equals(action)) {
|
||||||
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) {
|
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) {
|
||||||
mImportFilename = intent.getData().getPath();
|
mImportFilename = intent.getData().getPath();
|
||||||
mImportData = null;
|
mImportData = null;
|
||||||
} else if (extras.containsKey(EXTRA_TEXT)) {
|
|
||||||
mImportData = intent.getStringExtra(EXTRA_TEXT).getBytes();
|
|
||||||
mImportFilename = null;
|
|
||||||
} else if (extras.containsKey(EXTRA_KEYRING_BYTES)) {
|
} else if (extras.containsKey(EXTRA_KEYRING_BYTES)) {
|
||||||
mImportData = intent.getByteArrayExtra(EXTRA_KEYRING_BYTES);
|
mImportData = intent.getByteArrayExtra(EXTRA_KEYRING_BYTES);
|
||||||
mImportFilename = null;
|
mImportFilename = null;
|
||||||
}
|
}
|
||||||
loadKeyListFragment();
|
loadKeyListFragment();
|
||||||
} else if (ACTION_IMPORT_FROM_FILE.equals(action)) {
|
} else if (ACTION_KEY_IMPORT_FROM_FILE.equals(action)) {
|
||||||
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) {
|
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) {
|
||||||
mImportFilename = intent.getData().getPath();
|
mImportFilename = intent.getData().getPath();
|
||||||
mImportData = null;
|
mImportData = null;
|
||||||
}
|
}
|
||||||
showImportFromFileDialog();
|
showImportFromFileDialog();
|
||||||
} else if (ACTION_IMPORT_FROM_QR_CODE.equals(action)) {
|
} else if (ACTION_KEY_IMPORT_FROM_QR_CODE.equals(action)) {
|
||||||
importFromQrCode();
|
importFromQrCode();
|
||||||
} else if (ACTION_IMPORT_FROM_NFC.equals(action)) {
|
} else if (ACTION_KEY_IMPORT_FROM_NFC.equals(action)) {
|
||||||
importFromNfc();
|
importFromNfc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
|
|||||||
Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
|
|
||||||
// TODO: check for key type?
|
// TODO: check for key type?
|
||||||
// data.putInt(ApgIntentService.IMPORT_KEY_TYPE, Id.type.secret_key);
|
// data.putInt(KeychainIntentService.IMPORT_KEY_TYPE, Id.type.secret_key);
|
||||||
|
|
||||||
if (mImportData != null) {
|
if (mImportData != null) {
|
||||||
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
|
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES);
|
||||||
@ -349,7 +349,8 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
|
|||||||
Bundle returnData = message.getData();
|
Bundle returnData = message.getData();
|
||||||
|
|
||||||
int added = returnData.getInt(KeychainIntentService.RESULT_IMPORT_ADDED);
|
int added = returnData.getInt(KeychainIntentService.RESULT_IMPORT_ADDED);
|
||||||
int updated = returnData.getInt(KeychainIntentService.RESULT_IMPORT_UPDATED);
|
int updated = returnData
|
||||||
|
.getInt(KeychainIntentService.RESULT_IMPORT_UPDATED);
|
||||||
int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD);
|
int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD);
|
||||||
String toastMessage;
|
String toastMessage;
|
||||||
if (added > 0 && updated > 0) {
|
if (added > 0 && updated > 0) {
|
||||||
|
@ -154,7 +154,7 @@ public class KeyListActivity extends SherlockFragmentActivity {
|
|||||||
|
|
||||||
case Id.menu.option.import_from_file: {
|
case Id.menu.option.import_from_file: {
|
||||||
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
||||||
intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_FROM_FILE);
|
intentImportFromFile.setAction(ImportKeysActivity.ACTION_KEY_IMPORT_FROM_FILE);
|
||||||
startActivityForResult(intentImportFromFile, 0);
|
startActivityForResult(intentImportFromFile, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ public class KeyListPublicActivity extends KeyListActivity {
|
|||||||
}
|
}
|
||||||
case Id.menu.option.import_from_file: {
|
case Id.menu.option.import_from_file: {
|
||||||
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
||||||
intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_FROM_FILE);
|
intentImportFromFile.setAction(ImportKeysActivity.ACTION_KEY_IMPORT_FROM_FILE);
|
||||||
startActivityForResult(intentImportFromFile, 0);
|
startActivityForResult(intentImportFromFile, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -75,7 +75,7 @@ public class KeyListPublicActivity extends KeyListActivity {
|
|||||||
|
|
||||||
case Id.menu.option.import_from_qr_code: {
|
case Id.menu.option.import_from_qr_code: {
|
||||||
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
||||||
intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_FROM_QR_CODE);
|
intentImportFromFile.setAction(ImportKeysActivity.ACTION_KEY_IMPORT_FROM_QR_CODE);
|
||||||
startActivityForResult(intentImportFromFile, Id.request.import_from_qr_code);
|
startActivityForResult(intentImportFromFile, Id.request.import_from_qr_code);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -83,7 +83,7 @@ public class KeyListPublicActivity extends KeyListActivity {
|
|||||||
|
|
||||||
case Id.menu.option.import_from_nfc: {
|
case Id.menu.option.import_from_nfc: {
|
||||||
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class);
|
||||||
intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_FROM_NFC);
|
intentImportFromFile.setAction(ImportKeysActivity.ACTION_KEY_IMPORT_FROM_NFC);
|
||||||
startActivityForResult(intentImportFromFile, 0);
|
startActivityForResult(intentImportFromFile, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -227,8 +227,8 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity {
|
|||||||
if (mKeyData != null) {
|
if (mKeyData != null) {
|
||||||
Intent intent = new Intent(KeyServerQueryActivity.this,
|
Intent intent = new Intent(KeyServerQueryActivity.this,
|
||||||
ImportKeysActivity.class);
|
ImportKeysActivity.class);
|
||||||
intent.setAction(ImportKeysActivity.ACTION_IMPORT);
|
intent.setAction(ImportKeysActivity.ACTION_KEY_IMPORT);
|
||||||
intent.putExtra(ImportKeysActivity.EXTRA_TEXT, mKeyData);
|
intent.putExtra(ImportKeysActivity.EXTRA_KEYRING_BYTES, mKeyData.getBytes());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,14 @@ import com.actionbarsherlock.app.SherlockFragmentActivity;
|
|||||||
|
|
||||||
public class SelectPublicKeyActivity extends SherlockFragmentActivity {
|
public class SelectPublicKeyActivity extends SherlockFragmentActivity {
|
||||||
|
|
||||||
// Not used in sourcode, but listed in AndroidManifest!
|
// Actions for internal use only:
|
||||||
public static final String ACTION_SELECT_PUBLIC_KEYS = Constants.INTENT_PREFIX
|
public static final String ACTION_SELECT_PUBLIC_KEYS = Constants.INTENT_PREFIX
|
||||||
+ "SELECT_PUBLIC_KEYRINGS";
|
+ "SELECT_PUBLIC_KEYRINGS";
|
||||||
|
|
||||||
public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "masterKeyIds";
|
public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids";
|
||||||
|
|
||||||
public static final String RESULT_EXTRA_MASTER_KEY_IDS = "masterKeyIds";
|
public static final String RESULT_EXTRA_MASTER_KEY_IDS = "master_key_ids";
|
||||||
public static final String RESULT_EXTRA_USER_IDS = "userIds";
|
public static final String RESULT_EXTRA_USER_IDS = "user_ids";
|
||||||
|
|
||||||
SelectPublicKeyFragment mSelectFragment;
|
SelectPublicKeyFragment mSelectFragment;
|
||||||
|
|
||||||
|
@ -30,14 +30,14 @@ import android.os.Bundle;
|
|||||||
|
|
||||||
public class SelectSecretKeyActivity extends SherlockFragmentActivity {
|
public class SelectSecretKeyActivity extends SherlockFragmentActivity {
|
||||||
|
|
||||||
// Not used in sourcode, but listed in AndroidManifest!
|
// Actions for internal use only:
|
||||||
public static final String ACTION_SELECT_SECRET_KEY = Constants.INTENT_PREFIX
|
public static final String ACTION_SELECT_SECRET_KEY = Constants.INTENT_PREFIX
|
||||||
+ "SELECT_SECRET_KEYRING";
|
+ "SELECT_SECRET_KEYRING";
|
||||||
|
|
||||||
public static final String EXTRA_FILTER_CERTIFY = "filter_certify";
|
public static final String EXTRA_FILTER_CERTIFY = "filter_certify";
|
||||||
|
|
||||||
public static final String RESULT_EXTRA_MASTER_KEY_ID = "masterKeyId";
|
public static final String RESULT_EXTRA_MASTER_KEY_ID = "master_key_id";
|
||||||
public static final String RESULT_EXTRA_USER_ID = "userId";
|
public static final String RESULT_EXTRA_USER_ID = "user_id";
|
||||||
|
|
||||||
private boolean mFilterCertify = false;
|
private boolean mFilterCertify = false;
|
||||||
private SelectSecretKeyFragment mSelectFragment;
|
private SelectSecretKeyFragment mSelectFragment;
|
||||||
|
@ -30,11 +30,12 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
public class ShareActivity extends SherlockFragmentActivity {
|
public class ShareActivity extends SherlockFragmentActivity {
|
||||||
|
// Actions for internal use only:
|
||||||
public static final String ACTION_SHARE_KEYRING = Constants.INTENT_PREFIX + "SHARE_KEYRING";
|
public static final String ACTION_SHARE_KEYRING = Constants.INTENT_PREFIX + "SHARE_KEYRING";
|
||||||
public static final String ACTION_SHARE_KEYRING_WITH_QR_CODE = Constants.INTENT_PREFIX
|
public static final String ACTION_SHARE_KEYRING_WITH_QR_CODE = Constants.INTENT_PREFIX
|
||||||
+ "SHARE_KEYRING_WITH_QR_CODE";
|
+ "SHARE_KEYRING_WITH_QR_CODE";
|
||||||
|
|
||||||
public static final String EXTRA_MASTER_KEY_ID = "masterKeyId";
|
public static final String EXTRA_MASTER_KEY_ID = "master_key_id";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -115,7 +115,7 @@ public class ShareNfcBeamActivity extends SherlockFragmentActivity implements
|
|||||||
byte[] receivedKeyringBytes = msg.getRecords()[0].getPayload();
|
byte[] receivedKeyringBytes = msg.getRecords()[0].getPayload();
|
||||||
|
|
||||||
Intent importIntent = new Intent(this, ImportKeysActivity.class);
|
Intent importIntent = new Intent(this, ImportKeysActivity.class);
|
||||||
importIntent.setAction(ImportKeysActivity.ACTION_IMPORT);
|
importIntent.setAction(ImportKeysActivity.ACTION_KEY_IMPORT);
|
||||||
importIntent.putExtra(ImportKeysActivity.EXTRA_KEYRING_BYTES, receivedKeyringBytes);
|
importIntent.putExtra(ImportKeysActivity.EXTRA_KEYRING_BYTES, receivedKeyringBytes);
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
|
Loading…
Reference in New Issue
Block a user