diff options
| author | Ashley Hughes <spirit.returned@gmail.com> | 2014-02-22 10:27:03 +0000 | 
|---|---|---|
| committer | Ashley Hughes <spirit.returned@gmail.com> | 2014-02-22 10:27:03 +0000 | 
| commit | 1b25ec5a0c011f5024d5f14f9919645a455e8a41 (patch) | |
| tree | f819ac3cea715f3c5cfc5f40bbf8673013ccc7ff /libraries/keychain-api-library | |
| parent | c3c311152ef33a6887909dbbeae40e8d01f96a9d (diff) | |
| parent | d1e8acd3027dce6fd34620b67a2d2be1634822cf (diff) | |
| download | open-keychain-1b25ec5a0c011f5024d5f14f9919645a455e8a41.tar.gz open-keychain-1b25ec5a0c011f5024d5f14f9919645a455e8a41.tar.bz2 open-keychain-1b25ec5a0c011f5024d5f14f9919645a455e8a41.zip | |
master merge
Diffstat (limited to 'libraries/keychain-api-library')
20 files changed, 1328 insertions, 0 deletions
| diff --git a/libraries/keychain-api-library/.gitignore b/libraries/keychain-api-library/.gitignore new file mode 100644 index 000000000..aa8bb5760 --- /dev/null +++ b/libraries/keychain-api-library/.gitignore @@ -0,0 +1,29 @@ +#Android specific +bin +gen +obj +lint.xml +local.properties +release.properties +ant.properties +*.class +*.apk + +#Gradle +.gradle +build +gradle.properties + +#Maven +target +pom.xml.* + +#Eclipse +.project +.classpath +.settings +.metadata + +#IntelliJ IDEA +.idea +*.iml diff --git a/libraries/keychain-api-library/AndroidManifest.xml b/libraries/keychain-api-library/AndroidManifest.xml new file mode 100644 index 000000000..768922c22 --- /dev/null +++ b/libraries/keychain-api-library/AndroidManifest.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" +    package="org.sufficientlysecure.keychain.api" +    android:versionCode="1" +    android:versionName="1.0" > + +    <uses-sdk +        android:minSdkVersion="9" +        android:targetSdkVersion="19" /> + +    <application/> + +</manifest>
\ No newline at end of file diff --git a/libraries/keychain-api-library/LICENSE b/libraries/keychain-api-library/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/libraries/keychain-api-library/LICENSE @@ -0,0 +1,202 @@ + +                                 Apache License +                           Version 2.0, January 2004 +                        http://www.apache.org/licenses/ + +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +   1. Definitions. + +      "License" shall mean the terms and conditions for use, reproduction, +      and distribution as defined by Sections 1 through 9 of this document. + +      "Licensor" shall mean the copyright owner or entity authorized by +      the copyright owner that is granting the License. + +      "Legal Entity" shall mean the union of the acting entity and all +      other entities that control, are controlled by, or are under common +      control with that entity. For the purposes of this definition, +      "control" means (i) the power, direct or indirect, to cause the +      direction or management of such entity, whether by contract or +      otherwise, or (ii) ownership of fifty percent (50%) or more of the +      outstanding shares, or (iii) beneficial ownership of such entity. + +      "You" (or "Your") shall mean an individual or Legal Entity +      exercising permissions granted by this License. + +      "Source" form shall mean the preferred form for making modifications, +      including but not limited to software source code, documentation +      source, and configuration files. + +      "Object" form shall mean any form resulting from mechanical +      transformation or translation of a Source form, including but +      not limited to compiled object code, generated documentation, +      and conversions to other media types. + +      "Work" shall mean the work of authorship, whether in Source or +      Object form, made available under the License, as indicated by a +      copyright notice that is included in or attached to the work +      (an example is provided in the Appendix below). + +      "Derivative Works" shall mean any work, whether in Source or Object +      form, that is based on (or derived from) the Work and for which the +      editorial revisions, annotations, elaborations, or other modifications +      represent, as a whole, an original work of authorship. For the purposes +      of this License, Derivative Works shall not include works that remain +      separable from, or merely link (or bind by name) to the interfaces of, +      the Work and Derivative Works thereof. + +      "Contribution" shall mean any work of authorship, including +      the original version of the Work and any modifications or additions +      to that Work or Derivative Works thereof, that is intentionally +      submitted to Licensor for inclusion in the Work by the copyright owner +      or by an individual or Legal Entity authorized to submit on behalf of +      the copyright owner. For the purposes of this definition, "submitted" +      means any form of electronic, verbal, or written communication sent +      to the Licensor or its representatives, including but not limited to +      communication on electronic mailing lists, source code control systems, +      and issue tracking systems that are managed by, or on behalf of, the +      Licensor for the purpose of discussing and improving the Work, but +      excluding communication that is conspicuously marked or otherwise +      designated in writing by the copyright owner as "Not a Contribution." + +      "Contributor" shall mean Licensor and any individual or Legal Entity +      on behalf of whom a Contribution has been received by Licensor and +      subsequently incorporated within the Work. + +   2. Grant of Copyright License. Subject to the terms and conditions of +      this License, each Contributor hereby grants to You a perpetual, +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable +      copyright license to reproduce, prepare Derivative Works of, +      publicly display, publicly perform, sublicense, and distribute the +      Work and such Derivative Works in Source or Object form. + +   3. Grant of Patent License. Subject to the terms and conditions of +      this License, each Contributor hereby grants to You a perpetual, +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable +      (except as stated in this section) patent license to make, have made, +      use, offer to sell, sell, import, and otherwise transfer the Work, +      where such license applies only to those patent claims licensable +      by such Contributor that are necessarily infringed by their +      Contribution(s) alone or by combination of their Contribution(s) +      with the Work to which such Contribution(s) was submitted. If You +      institute patent litigation against any entity (including a +      cross-claim or counterclaim in a lawsuit) alleging that the Work +      or a Contribution incorporated within the Work constitutes direct +      or contributory patent infringement, then any patent licenses +      granted to You under this License for that Work shall terminate +      as of the date such litigation is filed. + +   4. Redistribution. You may reproduce and distribute copies of the +      Work or Derivative Works thereof in any medium, with or without +      modifications, and in Source or Object form, provided that You +      meet the following conditions: + +      (a) You must give any other recipients of the Work or +          Derivative Works a copy of this License; and + +      (b) You must cause any modified files to carry prominent notices +          stating that You changed the files; and + +      (c) You must retain, in the Source form of any Derivative Works +          that You distribute, all copyright, patent, trademark, and +          attribution notices from the Source form of the Work, +          excluding those notices that do not pertain to any part of +          the Derivative Works; and + +      (d) If the Work includes a "NOTICE" text file as part of its +          distribution, then any Derivative Works that You distribute must +          include a readable copy of the attribution notices contained +          within such NOTICE file, excluding those notices that do not +          pertain to any part of the Derivative Works, in at least one +          of the following places: within a NOTICE text file distributed +          as part of the Derivative Works; within the Source form or +          documentation, if provided along with the Derivative Works; or, +          within a display generated by the Derivative Works, if and +          wherever such third-party notices normally appear. The contents +          of the NOTICE file are for informational purposes only and +          do not modify the License. You may add Your own attribution +          notices within Derivative Works that You distribute, alongside +          or as an addendum to the NOTICE text from the Work, provided +          that such additional attribution notices cannot be construed +          as modifying the License. + +      You may add Your own copyright statement to Your modifications and +      may provide additional or different license terms and conditions +      for use, reproduction, or distribution of Your modifications, or +      for any such Derivative Works as a whole, provided Your use, +      reproduction, and distribution of the Work otherwise complies with +      the conditions stated in this License. + +   5. Submission of Contributions. Unless You explicitly state otherwise, +      any Contribution intentionally submitted for inclusion in the Work +      by You to the Licensor shall be under the terms and conditions of +      this License, without any additional terms or conditions. +      Notwithstanding the above, nothing herein shall supersede or modify +      the terms of any separate license agreement you may have executed +      with Licensor regarding such Contributions. + +   6. Trademarks. This License does not grant permission to use the trade +      names, trademarks, service marks, or product names of the Licensor, +      except as required for reasonable and customary use in describing the +      origin of the Work and reproducing the content of the NOTICE file. + +   7. Disclaimer of Warranty. Unless required by applicable law or +      agreed to in writing, Licensor provides the Work (and each +      Contributor provides its Contributions) on an "AS IS" BASIS, +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +      implied, including, without limitation, any warranties or conditions +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +      PARTICULAR PURPOSE. You are solely responsible for determining the +      appropriateness of using or redistributing the Work and assume any +      risks associated with Your exercise of permissions under this License. + +   8. Limitation of Liability. In no event and under no legal theory, +      whether in tort (including negligence), contract, or otherwise, +      unless required by applicable law (such as deliberate and grossly +      negligent acts) or agreed to in writing, shall any Contributor be +      liable to You for damages, including any direct, indirect, special, +      incidental, or consequential damages of any character arising as a +      result of this License or out of the use or inability to use the +      Work (including but not limited to damages for loss of goodwill, +      work stoppage, computer failure or malfunction, or any and all +      other commercial damages or losses), even if such Contributor +      has been advised of the possibility of such damages. + +   9. Accepting Warranty or Additional Liability. While redistributing +      the Work or Derivative Works thereof, You may choose to offer, +      and charge a fee for, acceptance of support, warranty, indemnity, +      or other liability obligations and/or rights consistent with this +      License. However, in accepting such obligations, You may act only +      on Your own behalf and on Your sole responsibility, not on behalf +      of any other Contributor, and only if You agree to indemnify, +      defend, and hold each Contributor harmless for any liability +      incurred by, or claims asserted against, such Contributor by reason +      of your accepting any such warranty or additional liability. + +   END OF TERMS AND CONDITIONS + +   APPENDIX: How to apply the Apache License to your work. + +      To apply the Apache License to your work, attach the following +      boilerplate notice, with the fields enclosed by brackets "[]" +      replaced with your own identifying information. (Don't include +      the brackets!)  The text should be enclosed in the appropriate +      comment syntax for the file format. We also recommend that a +      file or class name and description of purpose be included on the +      same "printed page" as the copyright notice for easier +      identification within third-party archives. + +   Copyright [yyyy] [name of copyright owner] + +   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. diff --git a/libraries/keychain-api-library/build.gradle b/libraries/keychain-api-library/build.gradle new file mode 100644 index 000000000..1d5911783 --- /dev/null +++ b/libraries/keychain-api-library/build.gradle @@ -0,0 +1,35 @@ +// please leave this here, so this library builds on its own +buildscript { +    repositories { +        mavenCentral() +    } + +    dependencies { +        classpath 'com.android.tools.build:gradle:0.8.3' +    } +} + +apply plugin: 'android-library' + +android { +    compileSdkVersion 19 +    buildToolsVersion '19.0.1' +     +    // NOTE: We are using the old folder structure to also support Eclipse +    sourceSets { +        main { +            manifest.srcFile 'AndroidManifest.xml' +            java.srcDirs = ['src'] +            resources.srcDirs = ['src'] +            aidl.srcDirs = ['src'] +            renderscript.srcDirs = ['src'] +            res.srcDirs = ['res'] +            assets.srcDirs = ['assets'] +        } +    } +     +    // Do not abort build if lint finds errors +    lintOptions { +        abortOnError false +    } +} diff --git a/libraries/keychain-api-library/project.properties b/libraries/keychain-api-library/project.properties new file mode 100644 index 000000000..91d2b0246 --- /dev/null +++ b/libraries/keychain-api-library/project.properties @@ -0,0 +1,15 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-19 +android.library=true diff --git a/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png b/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.pngBinary files differ new file mode 100644 index 000000000..71b9118dc --- /dev/null +++ b/libraries/keychain-api-library/res/drawable-hdpi/ic_action_cancel_launchersize.png diff --git a/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png b/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.pngBinary files differ new file mode 100644 index 000000000..270abf45f --- /dev/null +++ b/libraries/keychain-api-library/res/drawable-mdpi/ic_action_cancel_launchersize.png diff --git a/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png b/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.pngBinary files differ new file mode 100644 index 000000000..1e3571fa5 --- /dev/null +++ b/libraries/keychain-api-library/res/drawable-xhdpi/ic_action_cancel_launchersize.png diff --git a/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png b/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.pngBinary files differ new file mode 100644 index 000000000..52044601e --- /dev/null +++ b/libraries/keychain-api-library/res/drawable-xxhdpi/ic_action_cancel_launchersize.png diff --git a/libraries/keychain-api-library/res/values/strings.xml b/libraries/keychain-api-library/res/values/strings.xml new file mode 100644 index 000000000..a198d0b5e --- /dev/null +++ b/libraries/keychain-api-library/res/values/strings.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + +    <string name="openpgp_list_preference_none">None</string> + +</resources>
\ No newline at end of file diff --git a/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl b/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl new file mode 100644 index 000000000..578a7d4b5 --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/IOpenPgpService.aidl @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +  +package org.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/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java b/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java new file mode 100644 index 000000000..4dd2cc641 --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpError.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.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<OpenPgpError> CREATOR = new Creator<OpenPgpError>() { +        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/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java b/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java new file mode 100644 index 000000000..16c79ca27 --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/OpenPgpSignatureResult.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.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<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() { +        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/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java new file mode 100644 index 000000000..f121c345d --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpApi.java @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.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<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 { +            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/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java new file mode 100644 index 000000000..263b42aaa --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpConstants.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.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/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java new file mode 100644 index 000000000..034186a3a --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpListPreference.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.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.content.res.TypedArray; +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; + +import org.sufficientlysecure.keychain.api.R; + +/** + * Does not extend ListPreference, but is very similar to it! + * http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/preference/ListPreference.java/?v=source + */ +public class OpenPgpListPreference extends DialogPreference { +    private ArrayList<OpenPgpProviderEntry> mProviderList = new ArrayList<OpenPgpProviderEntry>(); +    private String mSelectedPackage; + +    public OpenPgpListPreference(Context context, AttributeSet attrs) { +        super(context, attrs); +    } + +    public OpenPgpListPreference(Context context) { +        this(context, null); +    } + +    /** +     * Public method to add new entries for legacy applications +     * +     * @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) { + +        // get providers +        mProviderList.clear(); +        Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); +        List<ResolveInfo> resInfo = getContext().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(getContext() +                        .getPackageManager())); +                Drawable icon = resolveInfo.serviceInfo.loadIcon(getContext().getPackageManager()); + +                mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon)); +            } +        } + +        // add "none"-entry +        mProviderList.add(0, new OpenPgpProviderEntry("", +                getContext().getString(R.string.openpgp_list_preference_none), +                getContext().getResources().getDrawable(R.drawable.ic_action_cancel_launchersize))); + +        // Init ArrayAdapter with OpenPGP Providers +        ListAdapter adapter = new ArrayAdapter<OpenPgpProviderEntry>(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); +    } + +    @Override +    protected Object onGetDefaultValue(TypedArray a, int index) { +        return a.getString(index); +    } + +    @Override +    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { +        setValue(restoreValue ? getPersistedString(mSelectedPackage) : (String) defaultValue); +    } + +    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/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java new file mode 100644 index 000000000..c80656c52 --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpServiceConnection.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.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; + +public class OpenPgpServiceConnection { +    private Context mApplicationContext; + +    private boolean mBound; +    private IOpenPgpService mService; +    private String mProviderPackageName; + +    public OpenPgpServiceConnection(Context context, String providerPackageName) { +        this.mApplicationContext = context.getApplicationContext(); +        this.mProviderPackageName = providerPackageName; +    } + +    public IOpenPgpService getService() { +        return mService; +    } + +    public boolean isBound() { +        return mBound; +    } + +    private ServiceConnection mServiceConnection = new ServiceConnection() { +        public void onServiceConnected(ComponentName name, IBinder service) { +            mService = IOpenPgpService.Stub.asInterface(service); +            mBound = true; +        } + +        public void onServiceDisconnected(ComponentName name) { +            mService = null; +            mBound = false; +        } +    }; + +    /** +     * If not already bound, bind to service! +     * +     * @return +     */ +    public boolean bindToService() { +        // if not already bound... +        if (mService == null && !mBound) { +            try { +                Intent serviceIntent = new Intent(); +                serviceIntent.setAction(IOpenPgpService.class.getName()); +                // NOTE: setPackage is very important to restrict the intent to this provider only! +                serviceIntent.setPackage(mProviderPackageName); +                mApplicationContext.bindService(serviceIntent, mServiceConnection, +                        Context.BIND_AUTO_CREATE); + +                return true; +            } catch (Exception e) { +                return false; +            } +        } else { +            return true; +        } +    } + +    public void unbindFromService() { +        mApplicationContext.unbindService(mServiceConnection); +    } + +} diff --git a/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java new file mode 100644 index 000000000..ffecaceba --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/util/OpenPgpUtils.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.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<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(intent, 0); +        if (!resInfo.isEmpty()) { +            return true; +        } else { +            return false; +        } +    } + +} diff --git a/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java b/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java new file mode 100644 index 000000000..3569caf5b --- /dev/null +++ b/libraries/keychain-api-library/src/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + *               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 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/libraries/keychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java b/libraries/keychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java new file mode 100644 index 000000000..15aceb534 --- /dev/null +++ b/libraries/keychain-api-library/src/org/sufficientlysecure/keychain/api/OpenKeychainIntents.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sufficientlysecure.keychain.api; + +public class OpenKeychainIntents { + +    public static final String ENCRYPT = "org.sufficientlysecure.keychain.action.ENCRYPT"; +    public static final String ENCRYPT_EXTRA_TEXT = "text"; // String +    public static final String ENCRYPT_ASCII_ARMOR = "ascii_armor"; // boolean + +    public static final String DECRYPT = "org.sufficientlysecure.keychain.action.DECRYPT"; +    public static final String DECRYPT_EXTRA_TEXT = "text"; // String + +    public static final String IMPORT_KEY = "org.sufficientlysecure.keychain.action.IMPORT_KEY"; +    public static final String IMPORT_KEY_EXTRA_KEY_BYTES = "key_bytes"; // byte[] + +    public static final String IMPORT_KEY_FROM_KEYSERVER = "org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_KEYSERVER"; +    public static final String IMPORT_KEY_FROM_KEYSERVER_QUERY = "query"; // String +    public static final String IMPORT_KEY_FROM_KEYSERVER_FINGERPRINT = "fingerprint"; // String + +    public static final String IMPORT_KEY_FROM_QR_CODE = "org.sufficientlysecure.keychain.action.IMPORT_KEY_FROM_QR_CODE"; + +} | 
