diff options
9 files changed, 113 insertions, 60 deletions
diff --git a/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpCallback.aidl b/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpCallback.aidl index e0ac43d22..ca00c8ce1 100644 --- a/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpCallback.aidl +++ b/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpCallback.aidl @@ -22,10 +22,23 @@ import org.openintents.openpgp.OpenPgpError; interface IOpenPgpCallback { /** - * CryptoSignatureResult is only returned if the Callback was used from decryptAndVerify - * + * onSuccess returns on successful OpenPGP operations. + * + * @param outputBytes + * contains resulting output bytes (decrypted content (when input was encrypted) + * or content without signature (when input was signed-only)) + * @param signatureResult + * signatureResult is only non-null if decryptAndVerify() was called and the content + * was encrypted or signed-and-encrypted. */ oneway void onSuccess(in byte[] outputBytes, in OpenPgpSignatureResult signatureResult); + /** + * onError returns on errors or when allowUserInteraction was set to false, but user interaction + * was required execute an OpenPGP operation. + * + * @param error + * See OpenPgpError class for more information. + */ oneway void onError(in OpenPgpError error); }
\ No newline at end of file diff --git a/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpService.aidl b/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpService.aidl index ca291469c..ab7ec8b1a 100644 --- a/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpService.aidl +++ b/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/IOpenPgpService.aidl @@ -23,61 +23,67 @@ import org.openintents.openpgp.IOpenPgpCallback; * Results are returned to the callback, which has to be implemented on client side. */ interface IOpenPgpService { - + /** * Encrypt * + * After successful encryption, callback's onSuccess will contain the resulting output bytes. + * * @param inputBytes * Byte array you want to encrypt * @param encryptionUserIds * User Ids (emails) of recipients * @param asciiArmor - * Encode for ASCII (Radix-64, 33 percent overhead compared to binary) + * Encode result for ASCII (Radix-64, 33 percent overhead compared to binary) * @param allowUserInteraction * Allows the OpenPGP Provider to handle missing keys by showing activities * @param callback * Callback where to return results */ - oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, - in boolean asciiArmor, in boolean allowUserInteraction, in IOpenPgpCallback callback); + oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, + in IOpenPgpCallback callback); /** * Sign + * + * After successful signing, callback's onSuccess will contain the resulting output bytes. * * @param inputBytes - * Byte array you want to encrypt + * Byte array you want to sign * @param asciiArmor - * Encode for ASCII (Radix-64, 33 percent overhead compared to binary) + * Encode result for ASCII (Radix-64, 33 percent overhead compared to binary) * @param allowUserInteraction * Allows the OpenPGP Provider to handle missing keys by showing activities * @param callback * Callback where to return results */ - oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in boolean allowUserInteraction, - in IOpenPgpCallback callback); + oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in IOpenPgpCallback callback); /** * Sign then encrypt + * + * After successful signing and encryption, callback's onSuccess will contain the resulting output bytes. * * @param inputBytes - * Byte array you want to encrypt + * Byte array you want to sign and encrypt * @param encryptionUserIds * User Ids (emails) of recipients - * @param signatureUserId - * User Ids (email) of sender * @param asciiArmor - * Encode for ASCII (Radix-64, 33 percent overhead compared to binary) + * Encode result for ASCII (Radix-64, 33 percent overhead compared to binary) * @param allowUserInteraction * Allows the OpenPGP Provider to handle missing keys by showing activities * @param callback * Callback where to return results */ - oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, - in boolean asciiArmor, in boolean allowUserInteraction, in IOpenPgpCallback callback); + oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, + in IOpenPgpCallback callback); /** - * Decrypts and verifies given input bytes. If no signature is present this method - * will only decrypt. + * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, + * and also signed-only inputBytes. + * + * After successful decryption/verification, callback's onSuccess will contain the resulting output bytes. + * The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given. * * @param inputBytes * Byte array you want to decrypt and verify @@ -86,7 +92,8 @@ interface IOpenPgpService { * @param callback * Callback where to return results */ - oneway void decryptAndVerify(in byte[] inputBytes, in boolean allowUserInteraction, - in IOpenPgpCallback callback); + oneway void decryptAndVerify(in byte[] inputBytes, in IOpenPgpCallback callback); + + boolean isKeyAvailable(in String[] userIds); }
\ No newline at end of file diff --git a/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/OpenPgpSignatureResult.java b/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/OpenPgpSignatureResult.java index 0d24e7bd4..4446614dd 100644 --- a/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/OpenPgpSignatureResult.java +++ b/OpenPGP-Keychain-API-Demo/src/org/openintents/openpgp/OpenPgpSignatureResult.java @@ -20,9 +20,13 @@ import android.os.Parcel; import android.os.Parcelable; public class OpenPgpSignatureResult implements Parcelable { + // generic error on signature verification public static final int SIGNATURE_ERROR = 0; + // successfully verified signature, with trusted public key public static final int SIGNATURE_SUCCESS_TRUSTED = 1; - public static final int SIGNATURE_UNKNOWN = 2; + // no public key was found for this signature verification + public static final int SIGNATURE_UNKNOWN_PUB_KEY = 2; + // successfully verified signature, but with untrusted public key public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3; int signatureStatus; diff --git a/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java b/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java index 94c68ce5a..8f56c124a 100644 --- a/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java +++ b/OpenPGP-Keychain-API-Demo/src/org/sufficientlysecure/keychain/demo/OpenPgpProviderActivity.java @@ -139,7 +139,7 @@ public class OpenPgpProviderActivity extends Activity { try { mCryptoServiceConnection.getService().encrypt(inputBytes, - mEncryptUserIds.getText().toString().split(","), true, true, encryptCallback); + mEncryptUserIds.getText().toString().split(","), true, encryptCallback); } catch (RemoteException e) { Log.e(Constants.TAG, "CryptoProviderDemo", e); } @@ -149,7 +149,7 @@ public class OpenPgpProviderActivity extends Activity { byte[] inputBytes = mMessage.getText().toString().getBytes(); try { - mCryptoServiceConnection.getService().sign(inputBytes, true, true, encryptCallback); + mCryptoServiceConnection.getService().sign(inputBytes, true, encryptCallback); } catch (RemoteException e) { Log.e(Constants.TAG, "CryptoProviderDemo", e); } @@ -160,7 +160,7 @@ public class OpenPgpProviderActivity extends Activity { try { mCryptoServiceConnection.getService().signAndEncrypt(inputBytes, - mEncryptUserIds.getText().toString().split(","), true, true, encryptCallback); + mEncryptUserIds.getText().toString().split(","), true, encryptCallback); } catch (RemoteException e) { Log.e(Constants.TAG, "CryptoProviderDemo", e); } @@ -170,7 +170,7 @@ public class OpenPgpProviderActivity extends Activity { byte[] inputBytes = mCiphertext.getText().toString().getBytes(); try { - mCryptoServiceConnection.getService().decryptAndVerify(inputBytes, true, + mCryptoServiceConnection.getService().decryptAndVerify(inputBytes, decryptAndVerifyCallback); } catch (RemoteException e) { Log.e(Constants.TAG, "CryptoProviderDemo", e); diff --git a/OpenPGP-Keychain/AndroidManifest.xml b/OpenPGP-Keychain/AndroidManifest.xml index 634d02459..cee186daf 100644 --- a/OpenPGP-Keychain/AndroidManifest.xml +++ b/OpenPGP-Keychain/AndroidManifest.xml @@ -18,7 +18,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.sufficientlysecure.keychain" android:installLocation="auto" - android:versionCode="21102" + android:versionCode="21103" android:versionName="2.1.1" > <!-- diff --git a/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpCallback.aidl b/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpCallback.aidl index 68773afb9..ca00c8ce1 100644 --- a/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpCallback.aidl +++ b/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpCallback.aidl @@ -25,7 +25,8 @@ interface IOpenPgpCallback { * onSuccess returns on successful OpenPGP operations. * * @param outputBytes - * contains resulting output bytes (decrypted content/content without signature) + * contains resulting output bytes (decrypted content (when input was encrypted) + * or content without signature (when input was signed-only)) * @param signatureResult * signatureResult is only non-null if decryptAndVerify() was called and the content * was encrypted or signed-and-encrypted. diff --git a/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpService.aidl b/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpService.aidl index 4ddad8e4e..ab7ec8b1a 100644 --- a/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpService.aidl +++ b/OpenPGP-Keychain/src/org/openintents/openpgp/IOpenPgpService.aidl @@ -34,14 +34,14 @@ interface IOpenPgpService { * @param encryptionUserIds * User Ids (emails) of recipients * @param asciiArmor - * Encode for ASCII (Radix-64, 33 percent overhead compared to binary) + * Encode result for ASCII (Radix-64, 33 percent overhead compared to binary) * @param allowUserInteraction * Allows the OpenPGP Provider to handle missing keys by showing activities * @param callback * Callback where to return results */ - oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, - in boolean asciiArmor, in boolean allowUserInteraction, in IOpenPgpCallback callback); + oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, + in IOpenPgpCallback callback); /** * Sign @@ -51,14 +51,13 @@ interface IOpenPgpService { * @param inputBytes * Byte array you want to sign * @param asciiArmor - * Encode for ASCII (Radix-64, 33 percent overhead compared to binary) + * Encode result for ASCII (Radix-64, 33 percent overhead compared to binary) * @param allowUserInteraction * Allows the OpenPGP Provider to handle missing keys by showing activities * @param callback * Callback where to return results */ - oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in boolean allowUserInteraction, - in IOpenPgpCallback callback); + oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in IOpenPgpCallback callback); /** * Sign then encrypt @@ -70,14 +69,14 @@ interface IOpenPgpService { * @param encryptionUserIds * User Ids (emails) of recipients * @param asciiArmor - * Encode for ASCII (Radix-64, 33 percent overhead compared to binary) + * Encode result for ASCII (Radix-64, 33 percent overhead compared to binary) * @param allowUserInteraction * Allows the OpenPGP Provider to handle missing keys by showing activities * @param callback * Callback where to return results */ - oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, - in boolean asciiArmor, in boolean allowUserInteraction, in IOpenPgpCallback callback); + oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, + in IOpenPgpCallback callback); /** * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, @@ -93,7 +92,8 @@ interface IOpenPgpService { * @param callback * Callback where to return results */ - oneway void decryptAndVerify(in byte[] inputBytes, in boolean allowUserInteraction, - in IOpenPgpCallback callback); + oneway void decryptAndVerify(in byte[] inputBytes, in IOpenPgpCallback callback); + + boolean isKeyAvailable(in String[] userIds); }
\ No newline at end of file diff --git a/OpenPGP-Keychain/src/org/openintents/openpgp/OpenPgpListPreference.java b/OpenPGP-Keychain/src/org/openintents/openpgp/OpenPgpListPreference.java index 4d40616dd..551401b18 100644 --- a/OpenPGP-Keychain/src/org/openintents/openpgp/OpenPgpListPreference.java +++ b/OpenPGP-Keychain/src/org/openintents/openpgp/OpenPgpListPreference.java @@ -23,7 +23,9 @@ import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; import android.graphics.drawable.Drawable; import android.preference.DialogPreference; import android.util.AttributeSet; @@ -34,15 +36,17 @@ import android.widget.ListAdapter; import android.widget.TextView; public class OpenPgpListPreference extends DialogPreference { - static final Intent intent = new Intent(IOpenPgpService.class.getName()); - ArrayList<OpenPgpProviderEntry> mProviderList = new ArrayList<OpenPgpProviderEntry>(); private String mSelectedPackage; + public static final int REQUIRED_API_VERSION = 1; + public OpenPgpListPreference(Context context, AttributeSet attrs) { super(context, attrs); - List<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(intent, 0); + List<ResolveInfo> resInfo = + context.getPackageManager().queryIntentServices( + new Intent(IOpenPgpService.class.getName()), PackageManager.GET_META_DATA); if (!resInfo.isEmpty()) { for (ResolveInfo resolveInfo : resInfo) { if (resolveInfo.serviceInfo == null) @@ -52,7 +56,13 @@ public class OpenPgpListPreference extends DialogPreference { String simpleName = String.valueOf(resolveInfo.serviceInfo .loadLabel(context.getPackageManager())); Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager()); - mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon)); + + // get api version + ServiceInfo si = resolveInfo.serviceInfo; + int apiVersion = si.metaData.getInt("api_version"); + + mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon, + apiVersion)); } } } @@ -68,8 +78,10 @@ public class OpenPgpListPreference extends DialogPreference { * @param simpleName * @param icon */ - public void addProvider(int position, String packageName, String simpleName, Drawable icon) { - mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon)); + public void addProvider(int position, String packageName, String simpleName, Drawable icon, + int apiVersion) { + mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon, + apiVersion)); } @Override @@ -91,13 +103,23 @@ public class OpenPgpListPreference extends DialogPreference { int dp5 = (int) (5 * getContext().getResources().getDisplayMetrics().density + 0.5f); tv.setCompoundDrawablePadding(dp5); + // disable if it has the wrong api_version + if (mProviderList.get(position).apiVersion == REQUIRED_API_VERSION) { + tv.setEnabled(true); + } else { + tv.setEnabled(false); + tv.setText(tv.getText() + " (API v" + + mProviderList.get(position).apiVersion + ", needs v" + + REQUIRED_API_VERSION + ")"); + } + return v; } }; builder.setSingleChoiceItems(adapter, getIndexOfProviderList(getValue()), new DialogInterface.OnClickListener() { - + @Override public void onClick(DialogInterface dialog, int which) { mSelectedPackage = mProviderList.get(which).packageName; @@ -167,11 +189,14 @@ public class OpenPgpListPreference extends DialogPreference { private String packageName; private String simpleName; private Drawable icon; + private int apiVersion; - public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon) { + public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon, + int apiVersion) { this.packageName = packageName; this.simpleName = simpleName; this.icon = icon; + this.apiVersion = apiVersion; } @Override diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 01d7ac252..50e49a2ab 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -456,15 +456,14 @@ public class OpenPgpService extends RemoteService { @Override public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds, - final boolean asciiArmor, final boolean allowUserInteraction, - final IOpenPgpCallback callback) throws RemoteException { + final boolean asciiArmor, final IOpenPgpCallback callback) throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, - allowUserInteraction, callback, settings, false); + encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, true, callback, + settings, false); } }; @@ -473,15 +472,14 @@ public class OpenPgpService extends RemoteService { @Override public void signAndEncrypt(final byte[] inputBytes, final String[] encryptionUserIds, - final boolean asciiArmor, final boolean allowUserInteraction, - final IOpenPgpCallback callback) throws RemoteException { + final boolean asciiArmor, final IOpenPgpCallback callback) throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, - allowUserInteraction, callback, settings, true); + encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, true, callback, + settings, true); } }; @@ -490,14 +488,13 @@ public class OpenPgpService extends RemoteService { @Override public void sign(final byte[] inputBytes, boolean asciiArmor, - final boolean allowUserInteraction, final IOpenPgpCallback callback) - throws RemoteException { + final IOpenPgpCallback callback) throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - signSafe(inputBytes, allowUserInteraction, callback, settings); + signSafe(inputBytes, true, callback, settings); } }; @@ -505,21 +502,27 @@ public class OpenPgpService extends RemoteService { } @Override - public void decryptAndVerify(final byte[] inputBytes, final boolean allowUserInteraction, - final IOpenPgpCallback callback) throws RemoteException { + public void decryptAndVerify(final byte[] inputBytes, final IOpenPgpCallback callback) + throws RemoteException { final AppSettings settings = getAppSettings(); Runnable r = new Runnable() { @Override public void run() { - decryptAndVerifySafe(inputBytes, allowUserInteraction, callback, settings); + decryptAndVerifySafe(inputBytes, true, callback, settings); } }; checkAndEnqueue(r); } + @Override + public boolean isKeyAvailable(String[] userIds) throws RemoteException { + // TODO + return false; + } + }; @Override |