PendingIntent to handle user input
This commit is contained in:
@@ -18,11 +18,14 @@ package org.sufficientlysecure.keychain.demo;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentSender;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.TaskStackBuilder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -54,6 +57,11 @@ public class OpenPgpProviderActivity extends Activity {
|
|||||||
|
|
||||||
private OpenPgpServiceConnection mCryptoServiceConnection;
|
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
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
@@ -210,30 +218,60 @@ public class OpenPgpProviderActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void signOnClick(View view) {
|
public void signOnClick(View view) {
|
||||||
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
String inputStr = mMessage.getText().toString();
|
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) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
e.printStackTrace();
|
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 {
|
// @Override
|
||||||
// mCryptoServiceConnection.getService().sign(input,
|
// public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras) {
|
||||||
// new OpenPgpData(OpenPgpData.TYPE_STRING), encryptCallback);
|
// Log.d(Constants.TAG, "onSendFinished");
|
||||||
// } catch (RemoteException e) {
|
// Log.d(Constants.TAG, "resultCode: " + resultCode);
|
||||||
// Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
//
|
||||||
// }
|
// }
|
||||||
|
// }, null);
|
||||||
|
// } catch (PendingIntent.CanceledException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signAndEncryptOnClick(View view) {
|
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
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|||||||
@@ -23,145 +23,52 @@ import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
|||||||
interface IOpenPgpService {
|
interface IOpenPgpService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle params:
|
* General extras
|
||||||
* api_version 1,2,3,... (current: 1)
|
* --------------
|
||||||
* ascii_armor true/false (for output)
|
*
|
||||||
* key_ids long[] (for encrypt method)
|
* params:
|
||||||
|
* int api_version (current: 1)
|
||||||
|
* boolean ascii_armor true/false (for output)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Bundle return:
|
* 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)
|
* int result_code 0,1, or 2 (see OpenPgpConstants)
|
||||||
* signature_result OpenPgpSignatureResult
|
* OpenPgpSignatureResult signature_result
|
||||||
* error OpenPgpError
|
* OpenPgpError error
|
||||||
* intent Intent
|
* Intent intent
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sign only
|
||||||
|
*
|
||||||
|
* params:
|
||||||
|
* String passphrase (optional)
|
||||||
|
*/
|
||||||
Bundle sign(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output);
|
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);
|
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 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,
|
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
||||||
* and also signed-only input.
|
* 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);
|
Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -16,15 +16,14 @@
|
|||||||
|
|
||||||
package org.openintents.openpgp.util;
|
package org.openintents.openpgp.util;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.openintents.openpgp.IOpenPgpService;
|
import org.openintents.openpgp.IOpenPgpService;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
@@ -32,11 +31,98 @@ public class OpenPgpApi {
|
|||||||
|
|
||||||
IOpenPgpService mService;
|
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) {
|
public OpenPgpApi(IOpenPgpService service) {
|
||||||
this.mService = service;
|
this.mService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bundle sign(InputStream is, final OutputStream os) {
|
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<Void, Integer, Bundle> {
|
||||||
|
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 {
|
try {
|
||||||
// send the input and output pfds
|
// send the input and output pfds
|
||||||
ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is,
|
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);
|
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
|
// 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
|
// close() is required to halt the TransferThread
|
||||||
output.close();
|
output.close();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (RemoteException e) {
|
} catch (Exception e) {
|
||||||
Log.e(OpenPgpConstants.TAG, "RemoteException", 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,
|
|
||||||
new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage()));
|
|
||||||
return result;
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(OpenPgpConstants.TAG, "IOException", e);
|
|
||||||
Bundle result = new Bundle();
|
Bundle result = new Bundle();
|
||||||
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
||||||
result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
|
result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class OpenPgpConstants {
|
|||||||
public static final int RESULT_CODE_ERROR = 0;
|
public static final int RESULT_CODE_ERROR = 0;
|
||||||
// success!
|
// success!
|
||||||
public static final int RESULT_CODE_SUCCESS = 1;
|
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;
|
public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -362,10 +362,9 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name="org.sufficientlysecure.keychain.service.remote.RemoteServiceActivity"
|
android:name="org.sufficientlysecure.keychain.service.remote.RemoteServiceActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name" />
|
||||||
android:launchMode="singleTop"
|
<!--android:launchMode="singleTop"-->
|
||||||
android:process=":remote_api"
|
<!--android:process=":remote_api"-->
|
||||||
android:taskAffinity=":remote_api" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity"
|
android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial
|
|||||||
|
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
|
|
||||||
// execute action from extra bundle
|
// executeServiceMethod action from extra bundle
|
||||||
if (ACTION_ENCRYPT_SIGN.equals(action)) {
|
if (ACTION_ENCRYPT_SIGN.equals(action)) {
|
||||||
try {
|
try {
|
||||||
/* Input */
|
/* Input */
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ import org.sufficientlysecure.keychain.service.exception.WrongPassphraseExceptio
|
|||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -308,8 +310,20 @@ public class OpenPgpService extends RemoteService {
|
|||||||
String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
|
String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId());
|
||||||
if (passphrase == null) {
|
if (passphrase == null) {
|
||||||
// TODO: we need to abort and return a passphrase Intent!
|
// TODO: we need to abort and return a passphrase Intent!
|
||||||
|
|
||||||
|
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
|
||||||
|
// TODO: setComponent really needed for security?
|
||||||
|
// intent.setComponent(new ComponentName(Constants.PACKAGE_NAME,
|
||||||
|
// "org.sufficientlysecure.keychain.service.remote.RemoteServiceActivity"));
|
||||||
|
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE);
|
||||||
|
intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, appSettings.getKeyId());
|
||||||
|
PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 42, intent, 0);
|
||||||
|
|
||||||
|
|
||||||
Bundle result = new Bundle();
|
Bundle result = new Bundle();
|
||||||
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
|
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
|
||||||
|
result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -328,19 +342,19 @@ public class OpenPgpService extends RemoteService {
|
|||||||
|
|
||||||
is.close();
|
is.close();
|
||||||
os.close();
|
os.close();
|
||||||
} catch (IOException e) {
|
// } catch (IOException e) {
|
||||||
Log.e(Constants.TAG, "Fail", e);
|
// Log.e(Constants.TAG, "Fail", e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
// try {
|
||||||
is.close();
|
is.close();
|
||||||
} catch (IOException e) {
|
// } catch (IOException e) {
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
// }
|
||||||
try {
|
// try {
|
||||||
os.close();
|
os.close();
|
||||||
} catch (IOException e) {
|
// } catch (IOException e) {
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Bundle result = new Bundle();
|
Bundle result = new Bundle();
|
||||||
@@ -516,27 +530,42 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that params != null and API version fits
|
||||||
|
*
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Bundle validateParamsAndVersion(Bundle params) {
|
||||||
|
if (params == null) {
|
||||||
|
Bundle result = new Bundle();
|
||||||
|
OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
|
||||||
|
result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
|
||||||
|
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) {
|
||||||
|
// not compatible!
|
||||||
|
Bundle result = new Bundle();
|
||||||
|
OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
|
||||||
|
result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
|
||||||
|
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
|
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) {
|
public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) {
|
||||||
final AppSettings appSettings = getAppSettings();
|
final AppSettings appSettings = getAppSettings();
|
||||||
|
|
||||||
if (params == null) {
|
Bundle errorResult = validateParamsAndVersion(params);
|
||||||
Bundle result = new Bundle();
|
if (errorResult != null) {
|
||||||
OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!");
|
return errorResult;
|
||||||
result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
|
|
||||||
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) {
|
|
||||||
// not compatible!
|
|
||||||
Bundle result = new Bundle();
|
|
||||||
OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
|
|
||||||
result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error);
|
|
||||||
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runnable r = new Runnable() {
|
// Runnable r = new Runnable() {
|
||||||
|
|||||||
@@ -86,15 +86,15 @@ public class RemoteServiceActivity extends ActionBarActivity {
|
|||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
|
||||||
if (!finishHandled) {
|
// if (!finishHandled) {
|
||||||
Message msg = Message.obtain();
|
// Message msg = Message.obtain();
|
||||||
msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL;
|
// msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL;
|
||||||
try {
|
// try {
|
||||||
mMessenger.send(msg);
|
// mMessenger.send(msg);
|
||||||
} catch (RemoteException e) {
|
// } catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoServiceActivity", e);
|
// Log.e(Constants.TAG, "CryptoServiceActivity", e);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleActions(Intent intent, Bundle savedInstanceState) {
|
protected void handleActions(Intent intent, Bundle savedInstanceState) {
|
||||||
@@ -237,7 +237,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
|
|||||||
|
|
||||||
Message msg = Message.obtain();
|
Message msg = Message.obtain();
|
||||||
msg.arg1 = OpenPgpService.SelectPubKeysActivityCallback.CANCEL;
|
msg.arg1 = OpenPgpService.SelectPubKeysActivityCallback.CANCEL;
|
||||||
;
|
|
||||||
try {
|
try {
|
||||||
mMessenger.send(msg);
|
mMessenger.send(msg);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -313,25 +313,31 @@ public class RemoteServiceActivity extends ActionBarActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||||
Message msg = Message.obtain();
|
// Message msg = Message.obtain();
|
||||||
msg.arg1 = OpenPgpService.PassphraseActivityCallback.OKAY;
|
// msg.arg1 = OpenPgpService.PassphraseActivityCallback.OKAY;
|
||||||
try {
|
// try {
|
||||||
mMessenger.send(msg);
|
// mMessenger.send(msg);
|
||||||
} catch (RemoteException e) {
|
// } catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoServiceActivity", e);
|
// Log.e(Constants.TAG, "CryptoServiceActivity", e);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
RemoteServiceActivity.this.setResult(RESULT_OK);
|
||||||
|
RemoteServiceActivity.this.finish();
|
||||||
} else {
|
} else {
|
||||||
Message msg = Message.obtain();
|
// Message msg = Message.obtain();
|
||||||
msg.arg1 = OpenPgpService.PassphraseActivityCallback.CANCEL;
|
// msg.arg1 = OpenPgpService.PassphraseActivityCallback.CANCEL;
|
||||||
try {
|
// try {
|
||||||
mMessenger.send(msg);
|
// mMessenger.send(msg);
|
||||||
} catch (RemoteException e) {
|
// } catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoServiceActivity", e);
|
// Log.e(Constants.TAG, "CryptoServiceActivity", e);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
RemoteServiceActivity.this.setResult(RESULT_CANCELED);
|
||||||
|
RemoteServiceActivity.this.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
finishHandled = true;
|
// finishHandled = true;
|
||||||
finish();
|
// finish();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -346,7 +352,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
|
|||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
||||||
// send message to handler to start encryption directly
|
// send message to handler to start encryption directly
|
||||||
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
// returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ public class DecryptActivity extends DrawerActivity {
|
|||||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
if (sharedText != null) {
|
if (sharedText != null) {
|
||||||
// handle like normal text decryption, override action and extras to later
|
// handle like normal text decryption, override action and extras to later
|
||||||
// execute ACTION_DECRYPT in main actions
|
// executeServiceMethod ACTION_DECRYPT in main actions
|
||||||
extras.putString(EXTRA_TEXT, sharedText);
|
extras.putString(EXTRA_TEXT, sharedText);
|
||||||
action = ACTION_DECRYPT;
|
action = ACTION_DECRYPT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ public class EncryptActivity extends DrawerActivity {
|
|||||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
if (sharedText != null) {
|
if (sharedText != null) {
|
||||||
// handle like normal text encryption, override action and extras to later
|
// handle like normal text encryption, override action and extras to later
|
||||||
// execute ACTION_ENCRYPT in main actions
|
// executeServiceMethod ACTION_ENCRYPT in main actions
|
||||||
extras.putString(EXTRA_TEXT, sharedText);
|
extras.putString(EXTRA_TEXT, sharedText);
|
||||||
extras.putBoolean(EXTRA_ASCII_ARMOR, true);
|
extras.putBoolean(EXTRA_ASCII_ARMOR, true);
|
||||||
action = ACTION_ENCRYPT;
|
action = ACTION_ENCRYPT;
|
||||||
|
|||||||
@@ -383,7 +383,7 @@
|
|||||||
<string name="api_settings_revoke">Revoke access</string>
|
<string name="api_settings_revoke">Revoke access</string>
|
||||||
<string name="api_settings_package_name">Package Name</string>
|
<string name="api_settings_package_name">Package Name</string>
|
||||||
<string name="api_settings_package_signature">SHA-256 of Package Signature</string>
|
<string name="api_settings_package_signature">SHA-256 of Package Signature</string>
|
||||||
<string name="api_register_text">The following application requests access to OpenPGP Keychain.\n\nAllow permanent access?</string>
|
<string name="api_register_text">The following application requests access to OpenPGP Keychain.\n\nAllow access (you can revoke it later)?</string>
|
||||||
<string name="api_register_allow">Allow access</string>
|
<string name="api_register_allow">Allow access</string>
|
||||||
<string name="api_register_disallow">Disallow access</string>
|
<string name="api_register_disallow">Disallow access</string>
|
||||||
<string name="api_register_error_select_key">Please select a key!</string>
|
<string name="api_register_error_select_key">Please select a key!</string>
|
||||||
|
|||||||
@@ -23,145 +23,52 @@ import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
|||||||
interface IOpenPgpService {
|
interface IOpenPgpService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle params:
|
* General extras
|
||||||
* api_version 1,2,3,... (current: 1)
|
* --------------
|
||||||
* ascii_armor true/false (for output)
|
*
|
||||||
* key_ids long[] (for encrypt method)
|
* params:
|
||||||
|
* int api_version (current: 1)
|
||||||
|
* boolean ascii_armor true/false (for output)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Bundle return:
|
* 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)
|
* int result_code 0,1, or 2 (see OpenPgpConstants)
|
||||||
* signature_result OpenPgpSignatureResult
|
* OpenPgpSignatureResult signature_result
|
||||||
* error OpenPgpError
|
* OpenPgpError error
|
||||||
* intent Intent
|
* Intent intent
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sign only
|
||||||
|
*
|
||||||
|
* params:
|
||||||
|
* String passphrase (optional)
|
||||||
|
*/
|
||||||
Bundle sign(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output);
|
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);
|
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 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,
|
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
||||||
* and also signed-only input.
|
* 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);
|
Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -16,15 +16,14 @@
|
|||||||
|
|
||||||
package org.openintents.openpgp.util;
|
package org.openintents.openpgp.util;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.openintents.openpgp.IOpenPgpService;
|
import org.openintents.openpgp.IOpenPgpService;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
@@ -32,11 +31,98 @@ public class OpenPgpApi {
|
|||||||
|
|
||||||
IOpenPgpService mService;
|
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) {
|
public OpenPgpApi(IOpenPgpService service) {
|
||||||
this.mService = service;
|
this.mService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bundle sign(InputStream is, final OutputStream os) {
|
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<Void, Integer, Bundle> {
|
||||||
|
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 {
|
try {
|
||||||
// send the input and output pfds
|
// send the input and output pfds
|
||||||
ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is,
|
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);
|
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
|
// 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
|
// close() is required to halt the TransferThread
|
||||||
output.close();
|
output.close();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (RemoteException e) {
|
} catch (Exception e) {
|
||||||
Log.e(OpenPgpConstants.TAG, "RemoteException", 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,
|
|
||||||
new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage()));
|
|
||||||
return result;
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(OpenPgpConstants.TAG, "IOException", e);
|
|
||||||
Bundle result = new Bundle();
|
Bundle result = new Bundle();
|
||||||
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
|
||||||
result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
|
result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class OpenPgpConstants {
|
|||||||
public static final int RESULT_CODE_ERROR = 0;
|
public static final int RESULT_CODE_ERROR = 0;
|
||||||
// success!
|
// success!
|
||||||
public static final int RESULT_CODE_SUCCESS = 1;
|
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;
|
public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user