From 2b98f2a0d7e37542a062886437c3f7b14599a4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 17:09:21 +0100 Subject: Restructure API lib folder to support Eclipse --- .../src/main/AndroidManifest.xml | 13 -- .../org/openintents/openpgp/IOpenPgpService.aidl | 85 --------- .../java/org/openintents/openpgp/OpenPgpError.java | 84 --------- .../openpgp/OpenPgpSignatureResult.java | 110 ------------ .../org/openintents/openpgp/util/OpenPgpApi.java | 198 --------------------- .../openintents/openpgp/util/OpenPgpConstants.java | 54 ------ .../openpgp/util/OpenPgpListPreference.java | 180 ------------------- .../openpgp/util/OpenPgpServiceConnection.java | 94 ---------- .../org/openintents/openpgp/util/OpenPgpUtils.java | 64 ------- .../openpgp/util/ParcelFileDescriptorUtil.java | 104 ----------- .../org/openintents/openpgp/IOpenPgpService.aidl | 85 +++++++++ .../src/org/openintents/openpgp/OpenPgpError.java | 84 +++++++++ .../openpgp/OpenPgpSignatureResult.java | 110 ++++++++++++ .../org/openintents/openpgp/util/OpenPgpApi.java | 198 +++++++++++++++++++++ .../openintents/openpgp/util/OpenPgpConstants.java | 54 ++++++ .../openpgp/util/OpenPgpListPreference.java | 180 +++++++++++++++++++ .../openpgp/util/OpenPgpServiceConnection.java | 94 ++++++++++ .../org/openintents/openpgp/util/OpenPgpUtils.java | 64 +++++++ .../openpgp/util/ParcelFileDescriptorUtil.java | 104 +++++++++++ 19 files changed, 973 insertions(+), 986 deletions(-) delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/AndroidManifest.xml delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpError.java delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpListPreference.java delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java delete mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java create mode 100644 OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java (limited to 'OpenPGP-Keychain-API/libraries/keychain-api-library/src') diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/AndroidManifest.xml b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/AndroidManifest.xml deleted file mode 100644 index 768922c22..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/AndroidManifest.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file 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 deleted file mode 100644 index 578a7d4b5..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp; - -interface IOpenPgpService { - - /** - * General extras - * -------------- - * - * Bundle params: - * int api_version (required) - * boolean ascii_armor (request ascii armor for ouput) - * - * returned Bundle: - * int result_code (0, 1, or 2 (see OpenPgpConstants)) - * OpenPgpError error (if result_code == 0) - * Intent intent (if result_code == 2) - * - */ - - /** - * Sign only - * - * optional params: - * String passphrase (for key passphrase) - */ - Bundle sign(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - - /** - * Encrypt - * - * Bundle params: - * long[] key_ids - * or - * String[] user_ids (= emails of recipients) (if more than one key has this user_id, a PendingIntent is returned) - * - * optional params: - * String passphrase (for key passphrase) - */ - Bundle encrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - - /** - * Sign and encrypt - * - * Bundle params: - * same as in encrypt() - */ - Bundle signAndEncrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - - /** - * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, - * and also signed-only input. - * - * returned Bundle: - * OpenPgpSignatureResult signature_result - */ - Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); - - /** - * Retrieves key ids based on given user ids (=emails) - * - * Bundle params: - * String[] user_ids - * - * returned Bundle: - * long[] key_ids - */ - Bundle getKeyIds(in Bundle params); - -} \ No newline at end of file diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpError.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpError.java deleted file mode 100644 index 4dd2cc641..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpError.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp; - -import android.os.Parcel; -import android.os.Parcelable; - -public class OpenPgpError implements Parcelable { - public static final int CLIENT_SIDE_ERROR = -1; - - public static final int GENERIC_ERROR = 0; - public static final int INCOMPATIBLE_API_VERSIONS = 1; - - public static final int NO_OR_WRONG_PASSPHRASE = 2; - public static final int NO_USER_IDS = 3; - - int errorId; - String message; - - public OpenPgpError() { - } - - public OpenPgpError(int errorId, String message) { - this.errorId = errorId; - this.message = message; - } - - public OpenPgpError(OpenPgpError b) { - this.errorId = b.errorId; - this.message = b.message; - } - - public int getErrorId() { - return errorId; - } - - public void setErrorId(int errorId) { - this.errorId = errorId; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(errorId); - dest.writeString(message); - } - - public static final Creator CREATOR = new Creator() { - public OpenPgpError createFromParcel(final Parcel source) { - OpenPgpError error = new OpenPgpError(); - error.errorId = source.readInt(); - error.message = source.readString(); - return error; - } - - public OpenPgpError[] newArray(final int size) { - return new OpenPgpError[size]; - } - }; -} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java deleted file mode 100644 index 16c79ca27..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp; - -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 certified public key - public static final int SIGNATURE_SUCCESS_CERTIFIED = 1; - // no public key was found for this signature verification - // you can retrieve the key with - // getKeys(new String[] {String.valueOf(signatureResult.getKeyId)}, true, callback) - public static final int SIGNATURE_UNKNOWN_PUB_KEY = 2; - // successfully verified signature, but with certified public key - public static final int SIGNATURE_SUCCESS_UNCERTIFIED = 3; - - int status; - boolean signatureOnly; - String userId; - long keyId; - - public int getStatus() { - return status; - } - - public boolean isSignatureOnly() { - return signatureOnly; - } - - public String getUserId() { - return userId; - } - - public long getKeyId() { - return keyId; - } - - public OpenPgpSignatureResult() { - - } - - public OpenPgpSignatureResult(int signatureStatus, String signatureUserId, - boolean signatureOnly, long keyId) { - this.status = signatureStatus; - this.signatureOnly = signatureOnly; - this.userId = signatureUserId; - this.keyId = keyId; - } - - public OpenPgpSignatureResult(OpenPgpSignatureResult b) { - this.status = b.status; - this.userId = b.userId; - this.signatureOnly = b.signatureOnly; - this.keyId = b.keyId; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(status); - dest.writeByte((byte) (signatureOnly ? 1 : 0)); - dest.writeString(userId); - dest.writeLong(keyId); - } - - public static final Creator CREATOR = new Creator() { - public OpenPgpSignatureResult createFromParcel(final Parcel source) { - OpenPgpSignatureResult vr = new OpenPgpSignatureResult(); - vr.status = source.readInt(); - vr.signatureOnly = source.readByte() == 1; - vr.userId = source.readString(); - vr.keyId = source.readLong(); - return vr; - } - - public OpenPgpSignatureResult[] newArray(final int size) { - return new OpenPgpSignatureResult[size]; - } - }; - - @Override - public String toString() { - String out = new String(); - out += "\nstatus: " + status; - out += "\nuserId: " + userId; - out += "\nsignatureOnly: " + signatureOnly; - out += "\nkeyId: " + keyId; - return out; - } - -} 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 deleted file mode 100644 index f121c345d..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import android.content.Context; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.ParcelFileDescriptor; -import android.util.Log; - -import org.openintents.openpgp.IOpenPgpService; -import org.openintents.openpgp.OpenPgpError; - -import java.io.InputStream; -import java.io.OutputStream; - -public class OpenPgpApi { - - IOpenPgpService mService; - Context mContext; - - 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; - private static final int OPERATION_GET_KEY_IDS = 4; - - public OpenPgpApi(Context context, IOpenPgpService service) { - this.mContext = context; - 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 Bundle getKeyIds(Bundle params) { - return executeApi(OPERATION_GET_KEY_IDS, params, null, null); - } - - 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 { - params.putInt(OpenPgpConstants.PARAMS_API_VERSION, OpenPgpConstants.API_VERSION); - - Bundle result = null; - - if (operationId == OPERATION_GET_KEY_IDS) { - result = mService.getKeyIds(params); - return result; - } else { - // send the input and output pfds - ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is, - new ParcelFileDescriptorUtil.IThreadListener() { - - @Override - public void onThreadFinished(Thread thread) { - Log.d(OpenPgpConstants.TAG, "Copy to service finished"); - } - }); - ParcelFileDescriptor output = ParcelFileDescriptorUtil.pipeTo(os, - new ParcelFileDescriptorUtil.IThreadListener() { - - @Override - public void onThreadFinished(Thread thread) { - Log.d(OpenPgpConstants.TAG, "Service finished writing!"); - } - }); - - - // blocks until result is ready - 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(); - - // set class loader to current context to allow unparcelling - // of OpenPgpError and OpenPgpSignatureResult - // http://stackoverflow.com/a/3806769 - result.setClassLoader(mContext.getClassLoader()); - - return result; - } - } 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, - new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage())); - return result; - } - } - - -} 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 deleted file mode 100644 index 263b42aaa..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpConstants.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -public class OpenPgpConstants { - - public static final String TAG = "OpenPgp API"; - - public static final int API_VERSION = 1; - public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService"; - - - /* Bundle params */ - public static final String PARAMS_API_VERSION = "api_version"; - // request ASCII Armor for output - // OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - public static final String PARAMS_REQUEST_ASCII_ARMOR = "ascii_armor"; - // (for encrypt method) - public static final String PARAMS_USER_IDS = "user_ids"; - public static final String PARAMS_KEY_IDS = "key_ids"; - // optional parameter: - public static final String PARAMS_PASSPHRASE = "passphrase"; - - /* Service Bundle returns */ - public static final String RESULT_CODE = "result_code"; - public static final String RESULT_SIGNATURE = "signature"; - public static final String RESULT_ERRORS = "error"; - public static final String RESULT_INTENT = "intent"; - - // get actual error object from RESULT_ERRORS - public static final int RESULT_CODE_ERROR = 0; - // success! - public static final int RESULT_CODE_SUCCESS = 1; - // executeServiceMethod intent and do it again with params from intent - public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2; - - /* PendingIntent returns */ - public static final String PI_RESULT_PARAMS = "params"; - -} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpListPreference.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpListPreference.java deleted file mode 100644 index e29794e87..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpListPreference.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import android.app.AlertDialog.Builder; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.preference.DialogPreference; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ListAdapter; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.List; - -public class OpenPgpListPreference extends DialogPreference { - ArrayList mProviderList = new ArrayList(); - private String mSelectedPackage; - - public OpenPgpListPreference(Context context, AttributeSet attrs) { - super(context, attrs); - - Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); - List resInfo = context.getPackageManager().queryIntentServices(intent, 0); - if (!resInfo.isEmpty()) { - for (ResolveInfo resolveInfo : resInfo) { - if (resolveInfo.serviceInfo == null) - continue; - - String packageName = resolveInfo.serviceInfo.packageName; - String simpleName = String.valueOf(resolveInfo.serviceInfo.loadLabel(context - .getPackageManager())); - Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager()); - - mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon)); - } - } - } - - public OpenPgpListPreference(Context context) { - this(context, null); - } - - /** - * Can be used to add "no selection" - * - * @param packageName - * @param simpleName - * @param icon - */ - public void addProvider(int position, String packageName, String simpleName, Drawable icon) { - mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon)); - } - - @Override - protected void onPrepareDialogBuilder(Builder builder) { - // Init ArrayAdapter with OpenPGP Providers - ListAdapter adapter = new ArrayAdapter(getContext(), - android.R.layout.select_dialog_singlechoice, android.R.id.text1, mProviderList) { - public View getView(int position, View convertView, ViewGroup parent) { - // User super class to create the View - View v = super.getView(position, convertView, parent); - TextView tv = (TextView) v.findViewById(android.R.id.text1); - - // Put the image on the TextView - tv.setCompoundDrawablesWithIntrinsicBounds(mProviderList.get(position).icon, null, - null, null); - - // Add margin between image and text (support various screen densities) - int dp10 = (int) (10 * getContext().getResources().getDisplayMetrics().density + 0.5f); - tv.setCompoundDrawablePadding(dp10); - - return v; - } - }; - - builder.setSingleChoiceItems(adapter, getIndexOfProviderList(getValue()), - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - mSelectedPackage = mProviderList.get(which).packageName; - - /* - * Clicking on an item simulates the positive button click, and dismisses - * the dialog. - */ - OpenPgpListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); - dialog.dismiss(); - } - }); - - /* - * The typical interaction for list-based dialogs is to have click-on-an-item dismiss the - * dialog instead of the user having to press 'Ok'. - */ - builder.setPositiveButton(null, null); - } - - @Override - protected void onDialogClosed(boolean positiveResult) { - super.onDialogClosed(positiveResult); - - if (positiveResult && (mSelectedPackage != null)) { - if (callChangeListener(mSelectedPackage)) { - setValue(mSelectedPackage); - } - } - } - - private int getIndexOfProviderList(String packageName) { - for (OpenPgpProviderEntry app : mProviderList) { - if (app.packageName.equals(packageName)) { - return mProviderList.indexOf(app); - } - } - - return -1; - } - - public void setValue(String packageName) { - mSelectedPackage = packageName; - persistString(packageName); - } - - public String getValue() { - return mSelectedPackage; - } - - public String getEntry() { - return getEntryByValue(mSelectedPackage); - } - - public String getEntryByValue(String packageName) { - for (OpenPgpProviderEntry app : mProviderList) { - if (app.packageName.equals(packageName)) { - return app.simpleName; - } - } - - return null; - } - - private static class OpenPgpProviderEntry { - private String packageName; - private String simpleName; - private Drawable icon; - - public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon) { - this.packageName = packageName; - this.simpleName = simpleName; - this.icon = icon; - } - - @Override - public String toString() { - return simpleName; - } - } -} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java deleted file mode 100644 index 8e8812faa..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import org.openintents.openpgp.IOpenPgpService; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; -import android.util.Log; - -public class OpenPgpServiceConnection { - private Context mApplicationContext; - - private IOpenPgpService mService; - private boolean mBound; - private String mCryptoProviderPackageName; - - public OpenPgpServiceConnection(Context context, String cryptoProviderPackageName) { - this.mApplicationContext = context.getApplicationContext(); - this.mCryptoProviderPackageName = cryptoProviderPackageName; - } - - public IOpenPgpService getService() { - return mService; - } - - public boolean isBound() { - return mBound; - } - - private ServiceConnection mCryptoServiceConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName name, IBinder service) { - mService = IOpenPgpService.Stub.asInterface(service); - Log.d(OpenPgpConstants.TAG, "connected to service"); - mBound = true; - } - - public void onServiceDisconnected(ComponentName name) { - mService = null; - Log.d(OpenPgpConstants.TAG, "disconnected from service"); - mBound = false; - } - }; - - /** - * If not already bound, bind! - * - * @return - */ - public boolean bindToService() { - // if not already connected - if (mService == null && !mBound) { - try { - Log.d(OpenPgpConstants.TAG, "not bound yet"); - - Intent serviceIntent = new Intent(); - serviceIntent.setAction(IOpenPgpService.class.getName()); - serviceIntent.setPackage(mCryptoProviderPackageName); - mApplicationContext.bindService(serviceIntent, mCryptoServiceConnection, - Context.BIND_AUTO_CREATE); - - return true; - } catch (Exception e) { - Log.d(OpenPgpConstants.TAG, "Exception on binding", e); - return false; - } - } else { - Log.d(OpenPgpConstants.TAG, "already bound"); - return true; - } - } - - public void unbindFromService() { - mApplicationContext.unbindService(mCryptoServiceConnection); - } - -} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java deleted file mode 100644 index ffecaceba..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; - -public class OpenPgpUtils { - - public static final Pattern PGP_MESSAGE = Pattern.compile( - ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", - Pattern.DOTALL); - - public static final Pattern PGP_SIGNED_MESSAGE = Pattern.compile( - ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", - Pattern.DOTALL); - - public static final int PARSE_RESULT_NO_PGP = -1; - public static final int PARSE_RESULT_MESSAGE = 0; - public static final int PARSE_RESULT_SIGNED_MESSAGE = 1; - - public static int parseMessage(String message) { - Matcher matcherSigned = PGP_SIGNED_MESSAGE.matcher(message); - Matcher matcherMessage = PGP_MESSAGE.matcher(message); - - if (matcherMessage.matches()) { - return PARSE_RESULT_MESSAGE; - } else if (matcherSigned.matches()) { - return PARSE_RESULT_SIGNED_MESSAGE; - } else { - return PARSE_RESULT_NO_PGP; - } - } - - public static boolean isAvailable(Context context) { - Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); - List resInfo = context.getPackageManager().queryIntentServices(intent, 0); - if (!resInfo.isEmpty()) { - return true; - } else { - return false; - } - } - -} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java deleted file mode 100644 index 75d4b8c18..000000000 --- a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * 2013 Flow (http://stackoverflow.com/questions/18212152/transfer-inputstream-to-another-service-across-process-boundaries-with-parcelf) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openintents.openpgp.util; - -import android.os.ParcelFileDescriptor; -import android.util.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class ParcelFileDescriptorUtil { - - public interface IThreadListener { - void onThreadFinished(final Thread thread); - } - - public static ParcelFileDescriptor pipeFrom(InputStream inputStream, IThreadListener listener) - throws IOException { - ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); - ParcelFileDescriptor readSide = pipe[0]; - ParcelFileDescriptor writeSide = pipe[1]; - - // start the transfer thread - new TransferThread(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide), - listener) - .start(); - - return readSide; - } - - public static ParcelFileDescriptor pipeTo(OutputStream outputStream, IThreadListener listener) - throws IOException { - ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); - ParcelFileDescriptor readSide = pipe[0]; - ParcelFileDescriptor writeSide = pipe[1]; - - // start the transfer thread - new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(readSide), outputStream, - listener) - .start(); - - return writeSide; - } - - static class TransferThread extends Thread { - final InputStream mIn; - final OutputStream mOut; - final IThreadListener mListener; - - TransferThread(InputStream in, OutputStream out, IThreadListener listener) { - super("ParcelFileDescriptor Transfer Thread"); - mIn = in; - mOut = out; - mListener = listener; - setDaemon(true); - } - - @Override - public void run() { - byte[] buf = new byte[1024]; - int len; - - try { - while ((len = mIn.read(buf)) > 0) { - mOut.write(buf, 0, len); - } - mOut.flush(); // just to be safe - } catch (IOException e) { - Log.e(OpenPgpConstants.TAG, "TransferThread" + getId() + ": writing failed", e); - } finally { - try { - mIn.close(); - } catch (IOException e) { - Log.e(OpenPgpConstants.TAG, "TransferThread" + getId(), e); - } - try { - mOut.close(); - } catch (IOException e) { - Log.e(OpenPgpConstants.TAG, "TransferThread" + getId(), e); - } - } - if (mListener != null) { - Log.d(OpenPgpConstants.TAG, "TransferThread " + getId() + " finished!"); - mListener.onThreadFinished(this); - } - } - } -} \ No newline at end of file diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl new file mode 100644 index 000000000..578a7d4b5 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp; + +interface IOpenPgpService { + + /** + * General extras + * -------------- + * + * Bundle params: + * int api_version (required) + * boolean ascii_armor (request ascii armor for ouput) + * + * returned Bundle: + * int result_code (0, 1, or 2 (see OpenPgpConstants)) + * OpenPgpError error (if result_code == 0) + * Intent intent (if result_code == 2) + * + */ + + /** + * Sign only + * + * optional params: + * String passphrase (for key passphrase) + */ + Bundle sign(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + + /** + * Encrypt + * + * Bundle params: + * long[] key_ids + * or + * String[] user_ids (= emails of recipients) (if more than one key has this user_id, a PendingIntent is returned) + * + * optional params: + * String passphrase (for key passphrase) + */ + Bundle encrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + + /** + * Sign and encrypt + * + * Bundle params: + * same as in encrypt() + */ + Bundle signAndEncrypt(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + + /** + * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, + * and also signed-only input. + * + * returned Bundle: + * OpenPgpSignatureResult signature_result + */ + Bundle decryptAndVerify(in Bundle params, in ParcelFileDescriptor input, in ParcelFileDescriptor output); + + /** + * Retrieves key ids based on given user ids (=emails) + * + * Bundle params: + * String[] user_ids + * + * returned Bundle: + * long[] key_ids + */ + Bundle getKeyIds(in Bundle params); + +} \ No newline at end of file diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java new file mode 100644 index 000000000..4dd2cc641 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp; + +import android.os.Parcel; +import android.os.Parcelable; + +public class OpenPgpError implements Parcelable { + public static final int CLIENT_SIDE_ERROR = -1; + + public static final int GENERIC_ERROR = 0; + public static final int INCOMPATIBLE_API_VERSIONS = 1; + + public static final int NO_OR_WRONG_PASSPHRASE = 2; + public static final int NO_USER_IDS = 3; + + int errorId; + String message; + + public OpenPgpError() { + } + + public OpenPgpError(int errorId, String message) { + this.errorId = errorId; + this.message = message; + } + + public OpenPgpError(OpenPgpError b) { + this.errorId = b.errorId; + this.message = b.message; + } + + public int getErrorId() { + return errorId; + } + + public void setErrorId(int errorId) { + this.errorId = errorId; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(errorId); + dest.writeString(message); + } + + public static final Creator CREATOR = new Creator() { + public OpenPgpError createFromParcel(final Parcel source) { + OpenPgpError error = new OpenPgpError(); + error.errorId = source.readInt(); + error.message = source.readString(); + return error; + } + + public OpenPgpError[] newArray(final int size) { + return new OpenPgpError[size]; + } + }; +} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java new file mode 100644 index 000000000..16c79ca27 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp; + +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 certified public key + public static final int SIGNATURE_SUCCESS_CERTIFIED = 1; + // no public key was found for this signature verification + // you can retrieve the key with + // getKeys(new String[] {String.valueOf(signatureResult.getKeyId)}, true, callback) + public static final int SIGNATURE_UNKNOWN_PUB_KEY = 2; + // successfully verified signature, but with certified public key + public static final int SIGNATURE_SUCCESS_UNCERTIFIED = 3; + + int status; + boolean signatureOnly; + String userId; + long keyId; + + public int getStatus() { + return status; + } + + public boolean isSignatureOnly() { + return signatureOnly; + } + + public String getUserId() { + return userId; + } + + public long getKeyId() { + return keyId; + } + + public OpenPgpSignatureResult() { + + } + + public OpenPgpSignatureResult(int signatureStatus, String signatureUserId, + boolean signatureOnly, long keyId) { + this.status = signatureStatus; + this.signatureOnly = signatureOnly; + this.userId = signatureUserId; + this.keyId = keyId; + } + + public OpenPgpSignatureResult(OpenPgpSignatureResult b) { + this.status = b.status; + this.userId = b.userId; + this.signatureOnly = b.signatureOnly; + this.keyId = b.keyId; + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(status); + dest.writeByte((byte) (signatureOnly ? 1 : 0)); + dest.writeString(userId); + dest.writeLong(keyId); + } + + public static final Creator CREATOR = new Creator() { + public OpenPgpSignatureResult createFromParcel(final Parcel source) { + OpenPgpSignatureResult vr = new OpenPgpSignatureResult(); + vr.status = source.readInt(); + vr.signatureOnly = source.readByte() == 1; + vr.userId = source.readString(); + vr.keyId = source.readLong(); + return vr; + } + + public OpenPgpSignatureResult[] newArray(final int size) { + return new OpenPgpSignatureResult[size]; + } + }; + + @Override + public String toString() { + String out = new String(); + out += "\nstatus: " + status; + out += "\nuserId: " + userId; + out += "\nsignatureOnly: " + signatureOnly; + out += "\nkeyId: " + keyId; + return out; + } + +} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java new file mode 100644 index 000000000..f121c345d --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp.util; + +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.OpenPgpError; + +import java.io.InputStream; +import java.io.OutputStream; + +public class OpenPgpApi { + + IOpenPgpService mService; + Context mContext; + + 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; + private static final int OPERATION_GET_KEY_IDS = 4; + + public OpenPgpApi(Context context, IOpenPgpService service) { + this.mContext = context; + 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 Bundle getKeyIds(Bundle params) { + return executeApi(OPERATION_GET_KEY_IDS, params, null, null); + } + + 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 { + params.putInt(OpenPgpConstants.PARAMS_API_VERSION, OpenPgpConstants.API_VERSION); + + Bundle result = null; + + if (operationId == OPERATION_GET_KEY_IDS) { + result = mService.getKeyIds(params); + return result; + } else { + // send the input and output pfds + ParcelFileDescriptor input = ParcelFileDescriptorUtil.pipeFrom(is, + new ParcelFileDescriptorUtil.IThreadListener() { + + @Override + public void onThreadFinished(Thread thread) { + Log.d(OpenPgpConstants.TAG, "Copy to service finished"); + } + }); + ParcelFileDescriptor output = ParcelFileDescriptorUtil.pipeTo(os, + new ParcelFileDescriptorUtil.IThreadListener() { + + @Override + public void onThreadFinished(Thread thread) { + Log.d(OpenPgpConstants.TAG, "Service finished writing!"); + } + }); + + + // blocks until result is ready + 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(); + + // set class loader to current context to allow unparcelling + // of OpenPgpError and OpenPgpSignatureResult + // http://stackoverflow.com/a/3806769 + result.setClassLoader(mContext.getClassLoader()); + + return result; + } + } 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, + new OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.getMessage())); + return result; + } + } + + +} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java new file mode 100644 index 000000000..263b42aaa --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp.util; + +public class OpenPgpConstants { + + public static final String TAG = "OpenPgp API"; + + public static final int API_VERSION = 1; + public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService"; + + + /* Bundle params */ + public static final String PARAMS_API_VERSION = "api_version"; + // request ASCII Armor for output + // OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) + public static final String PARAMS_REQUEST_ASCII_ARMOR = "ascii_armor"; + // (for encrypt method) + public static final String PARAMS_USER_IDS = "user_ids"; + public static final String PARAMS_KEY_IDS = "key_ids"; + // optional parameter: + public static final String PARAMS_PASSPHRASE = "passphrase"; + + /* Service Bundle returns */ + public static final String RESULT_CODE = "result_code"; + public static final String RESULT_SIGNATURE = "signature"; + public static final String RESULT_ERRORS = "error"; + public static final String RESULT_INTENT = "intent"; + + // get actual error object from RESULT_ERRORS + public static final int RESULT_CODE_ERROR = 0; + // success! + public static final int RESULT_CODE_SUCCESS = 1; + // executeServiceMethod intent and do it again with params from intent + public static final int RESULT_CODE_USER_INTERACTION_REQUIRED = 2; + + /* PendingIntent returns */ + public static final String PI_RESULT_PARAMS = "params"; + +} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java new file mode 100644 index 000000000..e29794e87 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp.util; + +import android.app.AlertDialog.Builder; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ListAdapter; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +public class OpenPgpListPreference extends DialogPreference { + ArrayList mProviderList = new ArrayList(); + private String mSelectedPackage; + + public OpenPgpListPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); + List resInfo = context.getPackageManager().queryIntentServices(intent, 0); + if (!resInfo.isEmpty()) { + for (ResolveInfo resolveInfo : resInfo) { + if (resolveInfo.serviceInfo == null) + continue; + + String packageName = resolveInfo.serviceInfo.packageName; + String simpleName = String.valueOf(resolveInfo.serviceInfo.loadLabel(context + .getPackageManager())); + Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager()); + + mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon)); + } + } + } + + public OpenPgpListPreference(Context context) { + this(context, null); + } + + /** + * Can be used to add "no selection" + * + * @param packageName + * @param simpleName + * @param icon + */ + public void addProvider(int position, String packageName, String simpleName, Drawable icon) { + mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon)); + } + + @Override + protected void onPrepareDialogBuilder(Builder builder) { + // Init ArrayAdapter with OpenPGP Providers + ListAdapter adapter = new ArrayAdapter(getContext(), + android.R.layout.select_dialog_singlechoice, android.R.id.text1, mProviderList) { + public View getView(int position, View convertView, ViewGroup parent) { + // User super class to create the View + View v = super.getView(position, convertView, parent); + TextView tv = (TextView) v.findViewById(android.R.id.text1); + + // Put the image on the TextView + tv.setCompoundDrawablesWithIntrinsicBounds(mProviderList.get(position).icon, null, + null, null); + + // Add margin between image and text (support various screen densities) + int dp10 = (int) (10 * getContext().getResources().getDisplayMetrics().density + 0.5f); + tv.setCompoundDrawablePadding(dp10); + + return v; + } + }; + + builder.setSingleChoiceItems(adapter, getIndexOfProviderList(getValue()), + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + mSelectedPackage = mProviderList.get(which).packageName; + + /* + * Clicking on an item simulates the positive button click, and dismisses + * the dialog. + */ + OpenPgpListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); + dialog.dismiss(); + } + }); + + /* + * The typical interaction for list-based dialogs is to have click-on-an-item dismiss the + * dialog instead of the user having to press 'Ok'. + */ + builder.setPositiveButton(null, null); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + + if (positiveResult && (mSelectedPackage != null)) { + if (callChangeListener(mSelectedPackage)) { + setValue(mSelectedPackage); + } + } + } + + private int getIndexOfProviderList(String packageName) { + for (OpenPgpProviderEntry app : mProviderList) { + if (app.packageName.equals(packageName)) { + return mProviderList.indexOf(app); + } + } + + return -1; + } + + public void setValue(String packageName) { + mSelectedPackage = packageName; + persistString(packageName); + } + + public String getValue() { + return mSelectedPackage; + } + + public String getEntry() { + return getEntryByValue(mSelectedPackage); + } + + public String getEntryByValue(String packageName) { + for (OpenPgpProviderEntry app : mProviderList) { + if (app.packageName.equals(packageName)) { + return app.simpleName; + } + } + + return null; + } + + private static class OpenPgpProviderEntry { + private String packageName; + private String simpleName; + private Drawable icon; + + public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon) { + this.packageName = packageName; + this.simpleName = simpleName; + this.icon = icon; + } + + @Override + public String toString() { + return simpleName; + } + } +} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java new file mode 100644 index 000000000..8e8812faa --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp.util; + +import org.openintents.openpgp.IOpenPgpService; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.util.Log; + +public class OpenPgpServiceConnection { + private Context mApplicationContext; + + private IOpenPgpService mService; + private boolean mBound; + private String mCryptoProviderPackageName; + + public OpenPgpServiceConnection(Context context, String cryptoProviderPackageName) { + this.mApplicationContext = context.getApplicationContext(); + this.mCryptoProviderPackageName = cryptoProviderPackageName; + } + + public IOpenPgpService getService() { + return mService; + } + + public boolean isBound() { + return mBound; + } + + private ServiceConnection mCryptoServiceConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName name, IBinder service) { + mService = IOpenPgpService.Stub.asInterface(service); + Log.d(OpenPgpConstants.TAG, "connected to service"); + mBound = true; + } + + public void onServiceDisconnected(ComponentName name) { + mService = null; + Log.d(OpenPgpConstants.TAG, "disconnected from service"); + mBound = false; + } + }; + + /** + * If not already bound, bind! + * + * @return + */ + public boolean bindToService() { + // if not already connected + if (mService == null && !mBound) { + try { + Log.d(OpenPgpConstants.TAG, "not bound yet"); + + Intent serviceIntent = new Intent(); + serviceIntent.setAction(IOpenPgpService.class.getName()); + serviceIntent.setPackage(mCryptoProviderPackageName); + mApplicationContext.bindService(serviceIntent, mCryptoServiceConnection, + Context.BIND_AUTO_CREATE); + + return true; + } catch (Exception e) { + Log.d(OpenPgpConstants.TAG, "Exception on binding", e); + return false; + } + } else { + Log.d(OpenPgpConstants.TAG, "already bound"); + return true; + } + } + + public void unbindFromService() { + mApplicationContext.unbindService(mCryptoServiceConnection); + } + +} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java new file mode 100644 index 000000000..ffecaceba --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp.util; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; + +public class OpenPgpUtils { + + public static final Pattern PGP_MESSAGE = Pattern.compile( + ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", + Pattern.DOTALL); + + public static final Pattern PGP_SIGNED_MESSAGE = Pattern.compile( + ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", + Pattern.DOTALL); + + public static final int PARSE_RESULT_NO_PGP = -1; + public static final int PARSE_RESULT_MESSAGE = 0; + public static final int PARSE_RESULT_SIGNED_MESSAGE = 1; + + public static int parseMessage(String message) { + Matcher matcherSigned = PGP_SIGNED_MESSAGE.matcher(message); + Matcher matcherMessage = PGP_MESSAGE.matcher(message); + + if (matcherMessage.matches()) { + return PARSE_RESULT_MESSAGE; + } else if (matcherSigned.matches()) { + return PARSE_RESULT_SIGNED_MESSAGE; + } else { + return PARSE_RESULT_NO_PGP; + } + } + + public static boolean isAvailable(Context context) { + Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); + List resInfo = context.getPackageManager().queryIntentServices(intent, 0); + if (!resInfo.isEmpty()) { + return true; + } else { + return false; + } + } + +} diff --git a/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java new file mode 100644 index 000000000..75d4b8c18 --- /dev/null +++ b/OpenPGP-Keychain-API/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * 2013 Flow (http://stackoverflow.com/questions/18212152/transfer-inputstream-to-another-service-across-process-boundaries-with-parcelf) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openintents.openpgp.util; + +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class ParcelFileDescriptorUtil { + + public interface IThreadListener { + void onThreadFinished(final Thread thread); + } + + public static ParcelFileDescriptor pipeFrom(InputStream inputStream, IThreadListener listener) + throws IOException { + ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); + ParcelFileDescriptor readSide = pipe[0]; + ParcelFileDescriptor writeSide = pipe[1]; + + // start the transfer thread + new TransferThread(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide), + listener) + .start(); + + return readSide; + } + + public static ParcelFileDescriptor pipeTo(OutputStream outputStream, IThreadListener listener) + throws IOException { + ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); + ParcelFileDescriptor readSide = pipe[0]; + ParcelFileDescriptor writeSide = pipe[1]; + + // start the transfer thread + new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(readSide), outputStream, + listener) + .start(); + + return writeSide; + } + + static class TransferThread extends Thread { + final InputStream mIn; + final OutputStream mOut; + final IThreadListener mListener; + + TransferThread(InputStream in, OutputStream out, IThreadListener listener) { + super("ParcelFileDescriptor Transfer Thread"); + mIn = in; + mOut = out; + mListener = listener; + setDaemon(true); + } + + @Override + public void run() { + byte[] buf = new byte[1024]; + int len; + + try { + while ((len = mIn.read(buf)) > 0) { + mOut.write(buf, 0, len); + } + mOut.flush(); // just to be safe + } catch (IOException e) { + Log.e(OpenPgpConstants.TAG, "TransferThread" + getId() + ": writing failed", e); + } finally { + try { + mIn.close(); + } catch (IOException e) { + Log.e(OpenPgpConstants.TAG, "TransferThread" + getId(), e); + } + try { + mOut.close(); + } catch (IOException e) { + Log.e(OpenPgpConstants.TAG, "TransferThread" + getId(), e); + } + } + if (mListener != null) { + Log.d(OpenPgpConstants.TAG, "TransferThread " + getId() + " finished!"); + mListener.onThreadFinished(this); + } + } + } +} \ No newline at end of file -- cgit v1.2.3