diff --git a/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java b/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java index 81f9eee68..39843eb82 100644 --- a/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java +++ b/OpenPGP-Keychain-API/example-app/src/main/java/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java @@ -18,11 +18,14 @@ package org.sufficientlysecure.keychain.demo; import android.app.Activity; import android.app.AlertDialog; +import android.app.PendingIntent; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentSender; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.support.v4.app.TaskStackBuilder; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -54,6 +57,11 @@ public class OpenPgpProviderActivity extends Activity { private OpenPgpServiceConnection mCryptoServiceConnection; + public static final int REQUEST_CODE_SIGN = 9910; + public static final int REQUEST_CODE_ENCRYPT = 9911; + public static final int REQUEST_CODE_SIGN_AND_ENC = 9912; + public static final int REQUEST_CODE_DECRYPT = 9913; + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -210,30 +218,60 @@ public class OpenPgpProviderActivity extends Activity { } public void signOnClick(View view) { + InputStream is = null; try { String inputStr = mMessage.getText().toString(); - InputStream is = new ByteArrayInputStream(inputStr.getBytes("UTF-8")); + is = new ByteArrayInputStream(inputStr.getBytes("UTF-8")); - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - - OpenPgpApi api = new OpenPgpApi(mCryptoServiceConnection.getService()); - api.sign(is, os); - - Log.d(OpenPgpConstants.TAG, "Test #1 read result: " + os.toByteArray().length - + " str=" + os.toString("UTF-8")); - - mCiphertext.setText(os.toString("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } -// OpenPgpData input = new OpenPgpData(inputStr); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + + OpenPgpApi api = new OpenPgpApi(mCryptoServiceConnection.getService()); + api.sign(new Bundle(), is, os, new OpenPgpApi.IOpenPgpCallback() { + @Override + public void onReturn(Bundle result) { + switch (result.getInt(OpenPgpConstants.RESULT_CODE)) { + case OpenPgpConstants.RESULT_CODE_SUCCESS: { + try { + Log.d(OpenPgpConstants.TAG, "result: " + os.toByteArray().length + + " str=" + os.toString("UTF-8")); + + mCiphertext.setText(os.toString("UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + break; + } + case OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED: { + PendingIntent pi = result.getParcelable(OpenPgpConstants.RESULT_INTENT); + try { + OpenPgpProviderActivity.this.startIntentSenderForResult(pi.getIntentSender(), + REQUEST_CODE_SIGN, null, // or new Intent() (in billing) + 0, 0, 0); + } catch (IntentSender.SendIntentException e) { + e.printStackTrace(); + } +// try { +// pi.send(OpenPgpProviderActivity.this, 42, null, new PendingIntent.OnFinished() { // -// try { -// mCryptoServiceConnection.getService().sign(input, -// new OpenPgpData(OpenPgpData.TYPE_STRING), encryptCallback); -// } catch (RemoteException e) { -// Log.e(Constants.TAG, "CryptoProviderDemo", e); -// } +// @Override +// public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras) { +// Log.d(Constants.TAG, "onSendFinished"); +// Log.d(Constants.TAG, "resultCode: " + resultCode); +// +// } +// }, null); +// } catch (PendingIntent.CanceledException e) { +// e.printStackTrace(); +// } + break; + } + } + } + }); + } public void signAndEncryptOnClick(View view) { @@ -258,6 +296,21 @@ public class OpenPgpProviderActivity extends Activity { // } } + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { +// super.onActivityResult(requestCode, resultCode, data); + Log.d(Constants.TAG, "onActivityResult"); + switch (requestCode) { + case REQUEST_CODE_SIGN: { + Log.d(Constants.TAG, "resultCode: " + resultCode); + + if (resultCode == RESULT_OK) { + signOnClick(null); + } + } + } + } + @Override public void onDestroy() { super.onDestroy(); diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl index ef390a7f6..714ca040e 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl @@ -23,145 +23,52 @@ import org.openintents.openpgp.IOpenPgpKeyIdsCallback; interface IOpenPgpService { /** - * Bundle params: - * api_version 1,2,3,... (current: 1) - * ascii_armor true/false (for output) - * key_ids long[] (for encrypt method) + * General extras + * -------------- + * + * params: + * int api_version (current: 1) + * boolean ascii_armor true/false (for output) * * * Bundle return: - * result_code RESULT_ERROR=0 (see error), RESULT_OK=1, RESULT_USER_INTERACTION_REQUIRED=2 (execute intent and do it again with params from intent) - * signature_result OpenPgpSignatureResult - * error OpenPgpError - * intent Intent + * int result_code 0,1, or 2 (see OpenPgpConstants) + * OpenPgpSignatureResult signature_result + * OpenPgpError error + * Intent intent * */ + /** + * sign only + * + * params: + * String passphrase (optional) + */ Bundle sign(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + /** + * encrypt + * + * params: + * long[] key_ids + * or + * String[] user_ids (= emails of recipients) (if more than one key has this user_id, an Intent is returned) + */ Bundle encrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + /** + * sign and encrypt + * + * params: + * same as in encrypt() + */ Bundle signAndEncrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - - -/* - ------------------OLD-------------------------- -*/ - /** - * Sign - * - * After successful signing, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param callback - * Callback where to return results - */ - //oneway void sign(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback); - - - /** - * Encrypt - * - * After successful encryption, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param keyIds - * Key Ids of recipients. Can be retrieved with getKeyIds() - * @param callback - * Callback where to return results - */ - //oneway void encrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback); - - /** - * Sign then encrypt - * - * After successful signing and encryption, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param keyIds - * Key Ids of recipients. Can be retrieved with getKeyIds() - * @param callback - * Callback where to return results - */ - //oneway void signAndEncrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback); - /** * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, * and also signed-only input. - * - * After successful decryption/verification, callback's onSuccess will contain the resulting output. - * The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param callback - * Callback where to return results */ - //oneway void decryptAndVerify(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback); - - /** - * Get available key ids based on given user ids - * - * @param ids - * User Ids (emails) of recipients OR key ids - * @param allowUserInteraction - * Enable user interaction to lookup and import unknown keys - * @param callback - * Callback where to return results (different type than callback in other functions!) - */ - //oneway void getKeyIds(in String[] ids, in boolean allowUserInteraction, in IOpenPgpKeyIdsCallback callback); - + Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + } \ No newline at end of file diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java index d490bca0c..adb187c04 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java @@ -16,15 +16,14 @@ package org.openintents.openpgp.util; +import android.os.AsyncTask; import android.os.Bundle; import android.os.ParcelFileDescriptor; -import android.os.RemoteException; import android.util.Log; import org.openintents.openpgp.IOpenPgpService; import org.openintents.openpgp.OpenPgpError; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -32,11 +31,98 @@ public class OpenPgpApi { IOpenPgpService mService; + private static final int OPERATION_SIGN = 0; + private static final int OPERATION_ENCRYPT = 1; + private static final int OPERATION_SIGN_ENCRYPT = 2; + private static final int OPERATION_DECRYPT_VERIFY = 3; + public OpenPgpApi(IOpenPgpService service) { this.mService = service; } public Bundle sign(InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN, new Bundle(), is, os); + } + + public Bundle sign(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN, params, is, os); + } + + public void sign(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_SIGN, params, is, os, callback); + } + + public Bundle encrypt(InputStream is, final OutputStream os) { + return executeApi(OPERATION_ENCRYPT, new Bundle(), is, os); + } + + public Bundle encrypt(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_ENCRYPT, params, is, os); + } + + public void encrypt(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_ENCRYPT, params, is, os, callback); + } + + public Bundle signAndEncrypt(InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN_ENCRYPT, new Bundle(), is, os); + } + + public Bundle signAndEncrypt(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN_ENCRYPT, params, is, os); + } + + public void signAndEncrypt(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_SIGN_ENCRYPT, params, is, os, callback); + } + + public Bundle decryptAndVerify(InputStream is, final OutputStream os) { + return executeApi(OPERATION_DECRYPT_VERIFY, new Bundle(), is, os); + } + + public Bundle decryptAndVerify(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_DECRYPT_VERIFY, params, is, os); + } + + public void decryptAndVerify(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_DECRYPT_VERIFY, params, is, os, callback); + } + + public interface IOpenPgpCallback { + void onReturn(final Bundle result); + } + + private class OpenPgpAsyncTask extends AsyncTask { + int operationId; + Bundle params; + InputStream is; + OutputStream os; + IOpenPgpCallback callback; + + private OpenPgpAsyncTask(int operationId, Bundle params, InputStream is, OutputStream os, IOpenPgpCallback callback) { + this.operationId = operationId; + this.params = params; + this.is = is; + this.os = os; + this.callback = callback; + } + + @Override + protected Bundle doInBackground(Void... unused) { + return executeApi(operationId, params, is, os); + } + + protected void onPostExecute(Bundle result) { + callback.onReturn(result); + } + + } + + private void executeApiAsync(int operationId, Bundle params, InputStream is, OutputStream os, IOpenPgpCallback callback) { + new OpenPgpAsyncTask(operationId, params, is, os, callback).execute((Void[]) null); + } + + private Bundle executeApi(int operationId, Bundle params, InputStream is, OutputStream os) { try { // send the input and output pfds ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is, @@ -56,24 +142,35 @@ public class OpenPgpApi { } }); - Bundle params = new Bundle(); params.putInt(OpenPgpConstants.PARAMS_API_VERSION, OpenPgpConstants.API_VERSION); + // default result is error + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, "This should never happen!")); + // blocks until result is ready - Bundle result = mService.sign(params, input, output); + switch (operationId) { + case OPERATION_SIGN: + result = mService.sign(params, input, output); + break; + case OPERATION_ENCRYPT: + result = mService.encrypt(params, input, output); + break; + case OPERATION_SIGN_ENCRYPT: + result = mService.signAndEncrypt(params, input, output); + break; + case OPERATION_DECRYPT_VERIFY: + result = mService.decryptAndVerify(params, input, output); + break; + } // close() is required to halt the TransferThread output.close(); return result; - } catch (RemoteException e) { - Log.e(OpenPgpConstants.TAG, "RemoteException", e); - Bundle result = new Bundle(); - result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); - result.putParcelable(OpenPgpConstants.RESULT_ERRORS, - new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage())); - return result; - } catch (IOException e) { - Log.e(OpenPgpConstants.TAG, "IOException", e); + } catch (Exception e) { + Log.e(OpenPgpConstants.TAG, "Exception", e); Bundle result = new Bundle(); result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); result.putParcelable(OpenPgpConstants.RESULT_ERRORS, diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java index 3dd9391d0..1bf3d76a3 100644 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java @@ -42,7 +42,7 @@ public class OpenPgpConstants { public static final int RESULT_CODE_ERROR = 0; // success! public static final int RESULT_CODE_SUCCESS = 1; - // execute intent and do it again with params from intent + // executeServiceMethod intent and do it again with params from intent public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2; } diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 45b034b97..ba2bd5571 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -362,10 +362,9 @@ + android:label="@string/app_name" /> + + Revoke access Package Name SHA-256 of Package Signature - The following application requests access to OpenPGP Keychain.\n\nAllow permanent access? + The following application requests access to OpenPGP Keychain.\n\nAllow access (you can revoke it later)? Allow access Disallow access Please select a key! diff --git a/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl b/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl index ef390a7f6..714ca040e 100644 --- a/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl +++ b/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl @@ -23,145 +23,52 @@ import org.openintents.openpgp.IOpenPgpKeyIdsCallback; interface IOpenPgpService { /** - * Bundle params: - * api_version 1,2,3,... (current: 1) - * ascii_armor true/false (for output) - * key_ids long[] (for encrypt method) + * General extras + * -------------- + * + * params: + * int api_version (current: 1) + * boolean ascii_armor true/false (for output) * * * Bundle return: - * result_code RESULT_ERROR=0 (see error), RESULT_OK=1, RESULT_USER_INTERACTION_REQUIRED=2 (execute intent and do it again with params from intent) - * signature_result OpenPgpSignatureResult - * error OpenPgpError - * intent Intent + * int result_code 0,1, or 2 (see OpenPgpConstants) + * OpenPgpSignatureResult signature_result + * OpenPgpError error + * Intent intent * */ + /** + * sign only + * + * params: + * String passphrase (optional) + */ Bundle sign(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + /** + * encrypt + * + * params: + * long[] key_ids + * or + * String[] user_ids (= emails of recipients) (if more than one key has this user_id, an Intent is returned) + */ Bundle encrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + /** + * sign and encrypt + * + * params: + * same as in encrypt() + */ Bundle signAndEncrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - - -/* - ------------------OLD-------------------------- -*/ - /** - * Sign - * - * After successful signing, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param callback - * Callback where to return results - */ - //oneway void sign(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback); - - - /** - * Encrypt - * - * After successful encryption, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param keyIds - * Key Ids of recipients. Can be retrieved with getKeyIds() - * @param callback - * Callback where to return results - */ - //oneway void encrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback); - - /** - * Sign then encrypt - * - * After successful signing and encryption, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param keyIds - * Key Ids of recipients. Can be retrieved with getKeyIds() - * @param callback - * Callback where to return results - */ - //oneway void signAndEncrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback); - /** * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, * and also signed-only input. - * - * After successful decryption/verification, callback's onSuccess will contain the resulting output. - * The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param callback - * Callback where to return results */ - //oneway void decryptAndVerify(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback); - - /** - * Get available key ids based on given user ids - * - * @param ids - * User Ids (emails) of recipients OR key ids - * @param allowUserInteraction - * Enable user interaction to lookup and import unknown keys - * @param callback - * Callback where to return results (different type than callback in other functions!) - */ - //oneway void getKeyIds(in String[] ids, in boolean allowUserInteraction, in IOpenPgpKeyIdsCallback callback); - + Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + } \ No newline at end of file diff --git a/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java b/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java index d490bca0c..adb187c04 100644 --- a/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java +++ b/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java @@ -16,15 +16,14 @@ package org.openintents.openpgp.util; +import android.os.AsyncTask; import android.os.Bundle; import android.os.ParcelFileDescriptor; -import android.os.RemoteException; import android.util.Log; import org.openintents.openpgp.IOpenPgpService; import org.openintents.openpgp.OpenPgpError; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -32,11 +31,98 @@ public class OpenPgpApi { IOpenPgpService mService; + private static final int OPERATION_SIGN = 0; + private static final int OPERATION_ENCRYPT = 1; + private static final int OPERATION_SIGN_ENCRYPT = 2; + private static final int OPERATION_DECRYPT_VERIFY = 3; + public OpenPgpApi(IOpenPgpService service) { this.mService = service; } public Bundle sign(InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN, new Bundle(), is, os); + } + + public Bundle sign(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN, params, is, os); + } + + public void sign(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_SIGN, params, is, os, callback); + } + + public Bundle encrypt(InputStream is, final OutputStream os) { + return executeApi(OPERATION_ENCRYPT, new Bundle(), is, os); + } + + public Bundle encrypt(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_ENCRYPT, params, is, os); + } + + public void encrypt(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_ENCRYPT, params, is, os, callback); + } + + public Bundle signAndEncrypt(InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN_ENCRYPT, new Bundle(), is, os); + } + + public Bundle signAndEncrypt(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_SIGN_ENCRYPT, params, is, os); + } + + public void signAndEncrypt(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_SIGN_ENCRYPT, params, is, os, callback); + } + + public Bundle decryptAndVerify(InputStream is, final OutputStream os) { + return executeApi(OPERATION_DECRYPT_VERIFY, new Bundle(), is, os); + } + + public Bundle decryptAndVerify(Bundle params, InputStream is, final OutputStream os) { + return executeApi(OPERATION_DECRYPT_VERIFY, params, is, os); + } + + public void decryptAndVerify(Bundle params, InputStream is, final OutputStream os, IOpenPgpCallback callback) { + executeApiAsync(OPERATION_DECRYPT_VERIFY, params, is, os, callback); + } + + public interface IOpenPgpCallback { + void onReturn(final Bundle result); + } + + private class OpenPgpAsyncTask extends AsyncTask { + int operationId; + Bundle params; + InputStream is; + OutputStream os; + IOpenPgpCallback callback; + + private OpenPgpAsyncTask(int operationId, Bundle params, InputStream is, OutputStream os, IOpenPgpCallback callback) { + this.operationId = operationId; + this.params = params; + this.is = is; + this.os = os; + this.callback = callback; + } + + @Override + protected Bundle doInBackground(Void... unused) { + return executeApi(operationId, params, is, os); + } + + protected void onPostExecute(Bundle result) { + callback.onReturn(result); + } + + } + + private void executeApiAsync(int operationId, Bundle params, InputStream is, OutputStream os, IOpenPgpCallback callback) { + new OpenPgpAsyncTask(operationId, params, is, os, callback).execute((Void[]) null); + } + + private Bundle executeApi(int operationId, Bundle params, InputStream is, OutputStream os) { try { // send the input and output pfds ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is, @@ -56,24 +142,35 @@ public class OpenPgpApi { } }); - Bundle params = new Bundle(); params.putInt(OpenPgpConstants.PARAMS_API_VERSION, OpenPgpConstants.API_VERSION); + // default result is error + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, "This should never happen!")); + // blocks until result is ready - Bundle result = mService.sign(params, input, output); + switch (operationId) { + case OPERATION_SIGN: + result = mService.sign(params, input, output); + break; + case OPERATION_ENCRYPT: + result = mService.encrypt(params, input, output); + break; + case OPERATION_SIGN_ENCRYPT: + result = mService.signAndEncrypt(params, input, output); + break; + case OPERATION_DECRYPT_VERIFY: + result = mService.decryptAndVerify(params, input, output); + break; + } // close() is required to halt the TransferThread output.close(); return result; - } catch (RemoteException e) { - Log.e(OpenPgpConstants.TAG, "RemoteException", e); - Bundle result = new Bundle(); - result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); - result.putParcelable(OpenPgpConstants.RESULT_ERRORS, - new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage())); - return result; - } catch (IOException e) { - Log.e(OpenPgpConstants.TAG, "IOException", e); + } catch (Exception e) { + Log.e(OpenPgpConstants.TAG, "Exception", e); Bundle result = new Bundle(); result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); result.putParcelable(OpenPgpConstants.RESULT_ERRORS, diff --git a/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java b/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java index 3dd9391d0..1bf3d76a3 100644 --- a/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java +++ b/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java @@ -42,7 +42,7 @@ public class OpenPgpConstants { public static final int RESULT_CODE_ERROR = 0; // success! public static final int RESULT_CODE_SUCCESS = 1; - // execute intent and do it again with params from intent + // executeServiceMethod intent and do it again with params from intent public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2; }