mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
New API version, import from clipboard
This commit is contained in:
parent
c75c00f935
commit
bef6977aad
@ -26,7 +26,7 @@
|
|||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/crypto_provider_demo_message"
|
android:id="@+id/crypto_provider_demo_message"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="150dip"
|
android:layout_height="100dip"
|
||||||
android:scrollHorizontally="true"
|
android:scrollHorizontally="true"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:text="message"
|
android:text="message"
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/crypto_provider_demo_ciphertext"
|
android:id="@+id/crypto_provider_demo_ciphertext"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="150dip"
|
android:layout_height="100dip"
|
||||||
android:text="ciphertext"
|
android:text="ciphertext"
|
||||||
android:textAppearance="@android:style/TextAppearance.Small" />
|
android:textAppearance="@android:style/TextAppearance.Small" />
|
||||||
|
|
||||||
@ -67,19 +67,17 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/crypto_provider_demo_encrypt_and_sign"
|
android:id="@+id/crypto_provider_demo_encrypt_and_sign"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:onClick="signAndEncryptOnClick"
|
||||||
android:onClick="encryptAndSignOnClick"
|
android:text="Sign and Encrypt" />
|
||||||
android:text="Encrypt and Sign" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/crypto_provider_demo_decrypt_and_verify"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:onClick="decryptAndVerifyOnClick"
|
|
||||||
android:text="Decrypt and Verify" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/crypto_provider_demo_decrypt_and_verify"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="decryptAndVerifyOnClick"
|
||||||
|
android:text="Decrypt and Verify" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.openintents.openpgp;
|
package org.openintents.openpgp;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpData;
|
||||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
|
|
||||||
@ -24,14 +25,14 @@ interface IOpenPgpCallback {
|
|||||||
/**
|
/**
|
||||||
* onSuccess returns on successful OpenPGP operations.
|
* onSuccess returns on successful OpenPGP operations.
|
||||||
*
|
*
|
||||||
* @param outputBytes
|
* @param output
|
||||||
* contains resulting output bytes (decrypted content (when input was encrypted)
|
* contains resulting output (decrypted content (when input was encrypted)
|
||||||
* or content without signature (when input was signed-only))
|
* or content without signature (when input was signed-only))
|
||||||
* @param signatureResult
|
* @param signatureResult
|
||||||
* signatureResult is only non-null if decryptAndVerify() was called and the content
|
* signatureResult is only non-null if decryptAndVerify() was called and the content
|
||||||
* was encrypted or signed-and-encrypted.
|
* was encrypted or signed-and-encrypted.
|
||||||
*/
|
*/
|
||||||
oneway void onSuccess(in byte[] outputBytes, in OpenPgpSignatureResult signatureResult);
|
oneway void onSuccess(in OpenPgpData output, in OpenPgpSignatureResult signatureResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
|
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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 org.openintents.openpgp.OpenPgpError;
|
||||||
|
|
||||||
|
interface IOpenPgpKeyIdsCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onSuccess returns on successful getKeyIds operations.
|
||||||
|
*
|
||||||
|
* @param keyIds
|
||||||
|
* returned key ids
|
||||||
|
*/
|
||||||
|
oneway void onSuccess(in long[] keyIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
|
||||||
|
* was required execute an OpenPGP operation.
|
||||||
|
*
|
||||||
|
* @param error
|
||||||
|
* See OpenPgpError class for more information.
|
||||||
|
*/
|
||||||
|
oneway void onError(in OpenPgpError error);
|
||||||
|
}
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.openintents.openpgp;
|
package org.openintents.openpgp;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpData;
|
||||||
import org.openintents.openpgp.IOpenPgpCallback;
|
import org.openintents.openpgp.IOpenPgpCallback;
|
||||||
|
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All methods are oneway, which means they are asynchronous and non-blocking.
|
* All methods are oneway, which means they are asynchronous and non-blocking.
|
||||||
@ -29,54 +31,76 @@ interface IOpenPgpService {
|
|||||||
*
|
*
|
||||||
* After successful encryption, callback's onSuccess will contain the resulting output bytes.
|
* After successful encryption, callback's onSuccess will contain the resulting output bytes.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to encrypt
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param encryptionUserIds
|
* @param output
|
||||||
* User Ids (emails) of recipients
|
* Request output format by defining OpenPgpData object
|
||||||
* @param asciiArmor
|
*
|
||||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
* @param allowUserInteraction
|
* Returns as String
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
|
* @param keyIds
|
||||||
|
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
oneway void encrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||||
in IOpenPgpCallback callback);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign
|
* Sign
|
||||||
*
|
*
|
||||||
* After successful signing, callback's onSuccess will contain the resulting output bytes.
|
* After successful signing, callback's onSuccess will contain the resulting output bytes.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to sign
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param asciiArmor
|
* @param output
|
||||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
* Request output format by defining OpenPgpData object
|
||||||
* @param allowUserInteraction
|
*
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
|
* Returns as String
|
||||||
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in IOpenPgpCallback callback);
|
oneway void sign(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign then encrypt
|
* Sign then encrypt
|
||||||
*
|
*
|
||||||
* After successful signing and encryption, callback's onSuccess will contain the resulting output bytes.
|
* After successful signing and encryption, callback's onSuccess will contain the resulting output bytes.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to sign and encrypt
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param encryptionUserIds
|
* @param output
|
||||||
* User Ids (emails) of recipients
|
* Request output format by defining OpenPgpData object
|
||||||
* @param asciiArmor
|
*
|
||||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
* @param allowUserInteraction
|
* Returns as String
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
|
* @param keyIds
|
||||||
|
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
oneway void signAndEncrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||||
in IOpenPgpCallback callback);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
||||||
@ -85,15 +109,35 @@ interface IOpenPgpService {
|
|||||||
* After successful decryption/verification, callback's onSuccess will contain the resulting output bytes.
|
* After successful decryption/verification, callback's onSuccess will contain the resulting output bytes.
|
||||||
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
|
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to decrypt and verify
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param allowUserInteraction
|
* @param output
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* Request output format by defining OpenPgpData object
|
||||||
|
*
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
|
* Returns as String
|
||||||
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void decryptAndVerify(in byte[] inputBytes, in IOpenPgpCallback callback);
|
oneway void decryptAndVerify(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
|
||||||
|
|
||||||
boolean isKeyAvailable(in String[] userIds);
|
/**
|
||||||
|
* Get available key ids based on given user ids
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* User Ids (emails) of recipients OR key ids
|
||||||
|
* @param allowUserInteraction
|
||||||
|
* Enable user interaction to lookup and import unknown keys
|
||||||
|
* @param callback
|
||||||
|
* Callback where to return results (different type than callback in other functions!)
|
||||||
|
*/
|
||||||
|
oneway void getKeyIds(in String[] ids, in boolean allowUserInteraction, in IOpenPgpKeyIdsCallback callback);
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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;
|
||||||
|
|
||||||
|
// Declare OpenPgpData so AIDL can find it and knows that it implements the parcelable protocol.
|
||||||
|
parcelable OpenPgpData;
|
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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.net.Uri;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public class OpenPgpData implements Parcelable {
|
||||||
|
public static final int TYPE_STRING = 0;
|
||||||
|
public static final int TYPE_BYTE_ARRAY = 1;
|
||||||
|
public static final int TYPE_FILE_DESCRIPTOR = 2;
|
||||||
|
public static final int TYPE_URI = 3;
|
||||||
|
|
||||||
|
int type;
|
||||||
|
|
||||||
|
String string;
|
||||||
|
byte[] bytes = new byte[0];
|
||||||
|
ParcelFileDescriptor fileDescriptor;
|
||||||
|
Uri uri;
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString() {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBytes() {
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParcelFileDescriptor getFileDescriptor() {
|
||||||
|
return fileDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri getUri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not a real constructor. This can be used to define requested output type.
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
public OpenPgpData(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(String string) {
|
||||||
|
this.string = string;
|
||||||
|
this.type = TYPE_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(byte[] bytes) {
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.type = TYPE_BYTE_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(ParcelFileDescriptor fileDescriptor) {
|
||||||
|
this.fileDescriptor = fileDescriptor;
|
||||||
|
this.type = TYPE_FILE_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(Uri uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.type = TYPE_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(OpenPgpData b) {
|
||||||
|
this.string = b.string;
|
||||||
|
this.bytes = b.bytes;
|
||||||
|
this.fileDescriptor = b.fileDescriptor;
|
||||||
|
this.uri = b.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(string);
|
||||||
|
dest.writeInt(bytes.length);
|
||||||
|
dest.writeByteArray(bytes);
|
||||||
|
dest.writeParcelable(fileDescriptor, 0);
|
||||||
|
dest.writeParcelable(uri, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<OpenPgpData> CREATOR = new Creator<OpenPgpData>() {
|
||||||
|
public OpenPgpData createFromParcel(final Parcel source) {
|
||||||
|
OpenPgpData vr = new OpenPgpData();
|
||||||
|
vr.string = source.readString();
|
||||||
|
vr.bytes = new byte[source.readInt()];
|
||||||
|
source.readByteArray(vr.bytes);
|
||||||
|
vr.fileDescriptor = source.readParcelable(ParcelFileDescriptor.class.getClassLoader());
|
||||||
|
vr.fileDescriptor = source.readParcelable(Uri.class.getClassLoader());
|
||||||
|
return vr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData[] newArray(final int size) {
|
||||||
|
return new OpenPgpData[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,9 @@ import android.app.AlertDialog.Builder;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.content.pm.ServiceInfo;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.preference.DialogPreference;
|
import android.preference.DialogPreference;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@ -34,15 +36,17 @@ import android.widget.ListAdapter;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
public class OpenPgpListPreference extends DialogPreference {
|
public class OpenPgpListPreference extends DialogPreference {
|
||||||
static final Intent intent = new Intent(IOpenPgpService.class.getName());
|
|
||||||
|
|
||||||
ArrayList<OpenPgpProviderEntry> mProviderList = new ArrayList<OpenPgpProviderEntry>();
|
ArrayList<OpenPgpProviderEntry> mProviderList = new ArrayList<OpenPgpProviderEntry>();
|
||||||
private String mSelectedPackage;
|
private String mSelectedPackage;
|
||||||
|
|
||||||
|
public static final int REQUIRED_API_VERSION = 1;
|
||||||
|
|
||||||
public OpenPgpListPreference(Context context, AttributeSet attrs) {
|
public OpenPgpListPreference(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
|
||||||
List<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(intent, 0);
|
List<ResolveInfo> resInfo =
|
||||||
|
context.getPackageManager().queryIntentServices(
|
||||||
|
new Intent(IOpenPgpService.class.getName()), PackageManager.GET_META_DATA);
|
||||||
if (!resInfo.isEmpty()) {
|
if (!resInfo.isEmpty()) {
|
||||||
for (ResolveInfo resolveInfo : resInfo) {
|
for (ResolveInfo resolveInfo : resInfo) {
|
||||||
if (resolveInfo.serviceInfo == null)
|
if (resolveInfo.serviceInfo == null)
|
||||||
@ -52,7 +56,13 @@ public class OpenPgpListPreference extends DialogPreference {
|
|||||||
String simpleName = String.valueOf(resolveInfo.serviceInfo
|
String simpleName = String.valueOf(resolveInfo.serviceInfo
|
||||||
.loadLabel(context.getPackageManager()));
|
.loadLabel(context.getPackageManager()));
|
||||||
Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager());
|
Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager());
|
||||||
mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon));
|
|
||||||
|
// get api version
|
||||||
|
ServiceInfo si = resolveInfo.serviceInfo;
|
||||||
|
int apiVersion = si.metaData.getInt("api_version");
|
||||||
|
|
||||||
|
mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon,
|
||||||
|
apiVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,8 +78,10 @@ public class OpenPgpListPreference extends DialogPreference {
|
|||||||
* @param simpleName
|
* @param simpleName
|
||||||
* @param icon
|
* @param icon
|
||||||
*/
|
*/
|
||||||
public void addProvider(int position, String packageName, String simpleName, Drawable icon) {
|
public void addProvider(int position, String packageName, String simpleName, Drawable icon,
|
||||||
mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon));
|
int apiVersion) {
|
||||||
|
mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon,
|
||||||
|
apiVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -91,6 +103,16 @@ public class OpenPgpListPreference extends DialogPreference {
|
|||||||
int dp5 = (int) (5 * getContext().getResources().getDisplayMetrics().density + 0.5f);
|
int dp5 = (int) (5 * getContext().getResources().getDisplayMetrics().density + 0.5f);
|
||||||
tv.setCompoundDrawablePadding(dp5);
|
tv.setCompoundDrawablePadding(dp5);
|
||||||
|
|
||||||
|
// disable if it has the wrong api_version
|
||||||
|
if (mProviderList.get(position).apiVersion == REQUIRED_API_VERSION) {
|
||||||
|
tv.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
tv.setEnabled(false);
|
||||||
|
tv.setText(tv.getText() + " (API v"
|
||||||
|
+ mProviderList.get(position).apiVersion + ", needs v"
|
||||||
|
+ REQUIRED_API_VERSION + ")");
|
||||||
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -167,11 +189,14 @@ public class OpenPgpListPreference extends DialogPreference {
|
|||||||
private String packageName;
|
private String packageName;
|
||||||
private String simpleName;
|
private String simpleName;
|
||||||
private Drawable icon;
|
private Drawable icon;
|
||||||
|
private int apiVersion;
|
||||||
|
|
||||||
public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon) {
|
public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon,
|
||||||
|
int apiVersion) {
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
this.simpleName = simpleName;
|
this.simpleName = simpleName;
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
|
this.apiVersion = apiVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,40 +25,50 @@ public class OpenPgpSignatureResult implements Parcelable {
|
|||||||
// successfully verified signature, with trusted public key
|
// successfully verified signature, with trusted public key
|
||||||
public static final int SIGNATURE_SUCCESS_TRUSTED = 1;
|
public static final int SIGNATURE_SUCCESS_TRUSTED = 1;
|
||||||
// no public key was found for this signature verification
|
// 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;
|
public static final int SIGNATURE_UNKNOWN_PUB_KEY = 2;
|
||||||
// successfully verified signature, but with untrusted public key
|
// successfully verified signature, but with untrusted public key
|
||||||
public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3;
|
public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3;
|
||||||
|
|
||||||
int signatureStatus;
|
int status;
|
||||||
String signatureUserId;
|
|
||||||
boolean signatureOnly;
|
boolean signatureOnly;
|
||||||
|
String userId;
|
||||||
|
long keyId;
|
||||||
|
|
||||||
public int getSignatureStatus() {
|
public int getStatus() {
|
||||||
return signatureStatus;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignatureUserId() {
|
|
||||||
return signatureUserId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSignatureOnly() {
|
public boolean isSignatureOnly() {
|
||||||
return signatureOnly;
|
return signatureOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getKeyId() {
|
||||||
|
return keyId;
|
||||||
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult() {
|
public OpenPgpSignatureResult() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult(int signatureStatus, String signatureUserId, boolean signatureOnly) {
|
public OpenPgpSignatureResult(int signatureStatus, String signatureUserId,
|
||||||
this.signatureStatus = signatureStatus;
|
boolean signatureOnly, long keyId) {
|
||||||
this.signatureUserId = signatureUserId;
|
this.status = signatureStatus;
|
||||||
this.signatureOnly = signatureOnly;
|
this.signatureOnly = signatureOnly;
|
||||||
|
this.userId = signatureUserId;
|
||||||
|
this.keyId = keyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult(OpenPgpSignatureResult b) {
|
public OpenPgpSignatureResult(OpenPgpSignatureResult b) {
|
||||||
this.signatureStatus = b.signatureStatus;
|
this.status = b.status;
|
||||||
this.signatureUserId = b.signatureUserId;
|
this.userId = b.userId;
|
||||||
this.signatureOnly = b.signatureOnly;
|
this.signatureOnly = b.signatureOnly;
|
||||||
|
this.keyId = b.keyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
@ -66,17 +76,19 @@ public class OpenPgpSignatureResult implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeInt(signatureStatus);
|
dest.writeInt(status);
|
||||||
dest.writeString(signatureUserId);
|
|
||||||
dest.writeByte((byte) (signatureOnly ? 1 : 0));
|
dest.writeByte((byte) (signatureOnly ? 1 : 0));
|
||||||
|
dest.writeString(userId);
|
||||||
|
dest.writeLong(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() {
|
public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() {
|
||||||
public OpenPgpSignatureResult createFromParcel(final Parcel source) {
|
public OpenPgpSignatureResult createFromParcel(final Parcel source) {
|
||||||
OpenPgpSignatureResult vr = new OpenPgpSignatureResult();
|
OpenPgpSignatureResult vr = new OpenPgpSignatureResult();
|
||||||
vr.signatureStatus = source.readInt();
|
vr.status = source.readInt();
|
||||||
vr.signatureUserId = source.readString();
|
|
||||||
vr.signatureOnly = source.readByte() == 1;
|
vr.signatureOnly = source.readByte() == 1;
|
||||||
|
vr.userId = source.readString();
|
||||||
|
vr.keyId = source.readLong();
|
||||||
return vr;
|
return vr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,9 +100,10 @@ public class OpenPgpSignatureResult implements Parcelable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String out = new String();
|
String out = new String();
|
||||||
out += "\nsignatureStatus: " + signatureStatus;
|
out += "\nstatus: " + status;
|
||||||
out += "\nsignatureUserId: " + signatureUserId;
|
out += "\nuserId: " + userId;
|
||||||
out += "\nsignatureOnly: " + signatureOnly;
|
out += "\nsignatureOnly: " + signatureOnly;
|
||||||
|
out += "\nkeyId: " + keyId;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,6 @@ public final class Constants {
|
|||||||
|
|
||||||
public static final boolean DEBUG = BuildConfig.DEBUG;
|
public static final boolean DEBUG = BuildConfig.DEBUG;
|
||||||
|
|
||||||
public static final String TAG = "Keychain API";
|
public static final String TAG = "Keychain";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package org.sufficientlysecure.keychain.demo;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||||
|
import org.openintents.openpgp.OpenPgpData;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
import org.openintents.openpgp.OpenPgpServiceConnection;
|
import org.openintents.openpgp.OpenPgpServiceConnection;
|
||||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
@ -66,12 +68,75 @@ public class OpenPgpProviderActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback from remote crypto service
|
* Callback from remote openpgp service
|
||||||
*/
|
*/
|
||||||
|
final IOpenPgpKeyIdsCallback.Stub getKeysEncryptCallback = new IOpenPgpKeyIdsCallback.Stub() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final long[] keyIds) throws RemoteException {
|
||||||
|
Log.d(Constants.TAG, "getKeysEncryptCallback keyId " + keyIds[0]);
|
||||||
|
mActivity.runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// encrypt after getting key ids
|
||||||
|
String inputStr = mMessage.getText().toString();
|
||||||
|
OpenPgpData input = new OpenPgpData(inputStr);
|
||||||
|
|
||||||
|
Log.d(Constants.TAG, "getKeysEncryptCallback inputStr " + inputStr);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mCryptoServiceConnection.getService().encrypt(input,
|
||||||
|
new OpenPgpData(OpenPgpData.TYPE_STRING), keyIds, encryptCallback);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(OpenPgpError error) throws RemoteException {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
final IOpenPgpKeyIdsCallback.Stub getKeysSignAndEncryptCallback = new IOpenPgpKeyIdsCallback.Stub() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(final long[] keyIds) throws RemoteException {
|
||||||
|
Log.d(Constants.TAG, "getKeysSignAndEncryptCallback keyId " + keyIds[0]);
|
||||||
|
|
||||||
|
mActivity.runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// encrypt after getting key ids
|
||||||
|
String inputStr = mMessage.getText().toString();
|
||||||
|
OpenPgpData input = new OpenPgpData(inputStr);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mCryptoServiceConnection.getService().signAndEncrypt(input,
|
||||||
|
new OpenPgpData(OpenPgpData.TYPE_STRING), keyIds, encryptCallback);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(OpenPgpError error) throws RemoteException {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
final IOpenPgpCallback.Stub encryptCallback = new IOpenPgpCallback.Stub() {
|
final IOpenPgpCallback.Stub encryptCallback = new IOpenPgpCallback.Stub() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final byte[] outputBytes, OpenPgpSignatureResult signatureResult)
|
public void onSuccess(final OpenPgpData output, OpenPgpSignatureResult signatureResult)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
Log.d(Constants.TAG, "encryptCallback");
|
Log.d(Constants.TAG, "encryptCallback");
|
||||||
|
|
||||||
@ -79,7 +144,7 @@ public class OpenPgpProviderActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mCiphertext.setText(new String(outputBytes));
|
mCiphertext.setText(output.getString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -94,7 +159,7 @@ public class OpenPgpProviderActivity extends Activity {
|
|||||||
final IOpenPgpCallback.Stub decryptAndVerifyCallback = new IOpenPgpCallback.Stub() {
|
final IOpenPgpCallback.Stub decryptAndVerifyCallback = new IOpenPgpCallback.Stub() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final byte[] outputBytes, final OpenPgpSignatureResult signatureResult)
|
public void onSuccess(final OpenPgpData output, final OpenPgpSignatureResult signatureResult)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
Log.d(Constants.TAG, "decryptAndVerifyCallback");
|
Log.d(Constants.TAG, "decryptAndVerifyCallback");
|
||||||
|
|
||||||
@ -102,7 +167,7 @@ public class OpenPgpProviderActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mMessage.setText(new String(outputBytes));
|
mMessage.setText(output.getString());
|
||||||
if (signatureResult != null) {
|
if (signatureResult != null) {
|
||||||
Toast.makeText(OpenPgpProviderActivity.this,
|
Toast.makeText(OpenPgpProviderActivity.this,
|
||||||
"signature result:\n" + signatureResult.toString(),
|
"signature result:\n" + signatureResult.toString(),
|
||||||
@ -135,43 +200,43 @@ public class OpenPgpProviderActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void encryptOnClick(View view) {
|
public void encryptOnClick(View view) {
|
||||||
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().encrypt(inputBytes,
|
mCryptoServiceConnection.getService().getKeyIds(
|
||||||
mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
|
mEncryptUserIds.getText().toString().split(","), true, getKeysEncryptCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signOnClick(View view) {
|
public void signOnClick(View view) {
|
||||||
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
String inputStr = mMessage.getText().toString();
|
||||||
|
OpenPgpData input = new OpenPgpData(inputStr);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().sign(inputBytes, true, encryptCallback);
|
mCryptoServiceConnection.getService().sign(input,
|
||||||
|
new OpenPgpData(OpenPgpData.TYPE_STRING), encryptCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encryptAndSignOnClick(View view) {
|
public void signAndEncryptOnClick(View view) {
|
||||||
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().signAndEncrypt(inputBytes,
|
mCryptoServiceConnection.getService().getKeyIds(
|
||||||
mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
|
mEncryptUserIds.getText().toString().split(","), true,
|
||||||
|
getKeysSignAndEncryptCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void decryptAndVerifyOnClick(View view) {
|
public void decryptAndVerifyOnClick(View view) {
|
||||||
byte[] inputBytes = mCiphertext.getText().toString().getBytes();
|
String inputStr = mCiphertext.getText().toString();
|
||||||
|
OpenPgpData input = new OpenPgpData(inputStr);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().decryptAndVerify(inputBytes,
|
mCryptoServiceConnection.getService().decryptAndVerify(input,
|
||||||
decryptAndVerifyCallback);
|
new OpenPgpData(OpenPgpData.TYPE_STRING), decryptAndVerifyCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/import_clipboard_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/import_from_clipboard" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -53,6 +53,7 @@
|
|||||||
<item>@string/menu_importFromFile</item>
|
<item>@string/menu_importFromFile</item>
|
||||||
<item>@string/menu_keyServer</item>
|
<item>@string/menu_keyServer</item>
|
||||||
<item>@string/menu_importFromQrCode</item>
|
<item>@string/menu_importFromQrCode</item>
|
||||||
|
<item>@string/import_from_clipboard</item>
|
||||||
<item>@string/menu_importFromNfc</item>
|
<item>@string/menu_importFromNfc</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
@ -351,6 +351,7 @@
|
|||||||
<string name="import_import">Import selected keys</string>
|
<string name="import_import">Import selected keys</string>
|
||||||
<string name="import_sign_and_upload">Import, Sign, and upload selected keys</string>
|
<string name="import_sign_and_upload">Import, Sign, and upload selected keys</string>
|
||||||
<string name="import_finish">Finish</string>
|
<string name="import_finish">Finish</string>
|
||||||
|
<string name="import_from_clipboard">Import from Clipboard</string>
|
||||||
|
|
||||||
<!-- Intent labels -->
|
<!-- Intent labels -->
|
||||||
<string name="intent_decrypt_file">OpenPGP: Decrypt File</string>
|
<string name="intent_decrypt_file">OpenPGP: Decrypt File</string>
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.openintents.openpgp;
|
package org.openintents.openpgp;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpData;
|
||||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
|
|
||||||
@ -24,14 +25,14 @@ interface IOpenPgpCallback {
|
|||||||
/**
|
/**
|
||||||
* onSuccess returns on successful OpenPGP operations.
|
* onSuccess returns on successful OpenPGP operations.
|
||||||
*
|
*
|
||||||
* @param outputBytes
|
* @param output
|
||||||
* contains resulting output bytes (decrypted content (when input was encrypted)
|
* contains resulting output (decrypted content (when input was encrypted)
|
||||||
* or content without signature (when input was signed-only))
|
* or content without signature (when input was signed-only))
|
||||||
* @param signatureResult
|
* @param signatureResult
|
||||||
* signatureResult is only non-null if decryptAndVerify() was called and the content
|
* signatureResult is only non-null if decryptAndVerify() was called and the content
|
||||||
* was encrypted or signed-and-encrypted.
|
* was encrypted or signed-and-encrypted.
|
||||||
*/
|
*/
|
||||||
oneway void onSuccess(in byte[] outputBytes, in OpenPgpSignatureResult signatureResult);
|
oneway void onSuccess(in OpenPgpData output, in OpenPgpSignatureResult signatureResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
|
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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 org.openintents.openpgp.OpenPgpError;
|
||||||
|
|
||||||
|
interface IOpenPgpKeyIdsCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onSuccess returns on successful getKeyIds operations.
|
||||||
|
*
|
||||||
|
* @param keyIds
|
||||||
|
* returned key ids
|
||||||
|
*/
|
||||||
|
oneway void onSuccess(in long[] keyIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
|
||||||
|
* was required execute an OpenPGP operation.
|
||||||
|
*
|
||||||
|
* @param error
|
||||||
|
* See OpenPgpError class for more information.
|
||||||
|
*/
|
||||||
|
oneway void onError(in OpenPgpError error);
|
||||||
|
}
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.openintents.openpgp;
|
package org.openintents.openpgp;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.OpenPgpData;
|
||||||
import org.openintents.openpgp.IOpenPgpCallback;
|
import org.openintents.openpgp.IOpenPgpCallback;
|
||||||
|
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All methods are oneway, which means they are asynchronous and non-blocking.
|
* All methods are oneway, which means they are asynchronous and non-blocking.
|
||||||
@ -29,54 +31,76 @@ interface IOpenPgpService {
|
|||||||
*
|
*
|
||||||
* After successful encryption, callback's onSuccess will contain the resulting output bytes.
|
* After successful encryption, callback's onSuccess will contain the resulting output bytes.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to encrypt
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param encryptionUserIds
|
* @param output
|
||||||
* User Ids (emails) of recipients
|
* Request output format by defining OpenPgpData object
|
||||||
* @param asciiArmor
|
*
|
||||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
* @param allowUserInteraction
|
* Returns as String
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
|
* @param keyIds
|
||||||
|
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
oneway void encrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||||
in IOpenPgpCallback callback);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign
|
* Sign
|
||||||
*
|
*
|
||||||
* After successful signing, callback's onSuccess will contain the resulting output bytes.
|
* After successful signing, callback's onSuccess will contain the resulting output bytes.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to sign
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param asciiArmor
|
* @param output
|
||||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
* Request output format by defining OpenPgpData object
|
||||||
* @param allowUserInteraction
|
*
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
|
* Returns as String
|
||||||
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in IOpenPgpCallback callback);
|
oneway void sign(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign then encrypt
|
* Sign then encrypt
|
||||||
*
|
*
|
||||||
* After successful signing and encryption, callback's onSuccess will contain the resulting output bytes.
|
* After successful signing and encryption, callback's onSuccess will contain the resulting output bytes.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to sign and encrypt
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param encryptionUserIds
|
* @param output
|
||||||
* User Ids (emails) of recipients
|
* Request output format by defining OpenPgpData object
|
||||||
* @param asciiArmor
|
*
|
||||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
* @param allowUserInteraction
|
* Returns as String
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
|
* @param keyIds
|
||||||
|
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
oneway void signAndEncrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||||
in IOpenPgpCallback callback);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
||||||
@ -85,15 +109,35 @@ interface IOpenPgpService {
|
|||||||
* After successful decryption/verification, callback's onSuccess will contain the resulting output bytes.
|
* After successful decryption/verification, callback's onSuccess will contain the resulting output bytes.
|
||||||
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
|
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
|
||||||
*
|
*
|
||||||
* @param inputBytes
|
* @param input
|
||||||
* Byte array you want to decrypt and verify
|
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||||
* @param allowUserInteraction
|
* @param output
|
||||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
* Request output format by defining OpenPgpData object
|
||||||
|
*
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||||
|
* Returns as String
|
||||||
|
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||||
|
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||||
|
* Returns as byte[]
|
||||||
|
* new OpenPgpData(uri)
|
||||||
|
* Writes output to given Uri
|
||||||
|
* new OpenPgpData(fileDescriptor)
|
||||||
|
* Writes output to given ParcelFileDescriptor
|
||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void decryptAndVerify(in byte[] inputBytes, in IOpenPgpCallback callback);
|
oneway void decryptAndVerify(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
|
||||||
|
|
||||||
boolean isKeyAvailable(in String[] userIds);
|
/**
|
||||||
|
* Get available key ids based on given user ids
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* User Ids (emails) of recipients OR key ids
|
||||||
|
* @param allowUserInteraction
|
||||||
|
* Enable user interaction to lookup and import unknown keys
|
||||||
|
* @param callback
|
||||||
|
* Callback where to return results (different type than callback in other functions!)
|
||||||
|
*/
|
||||||
|
oneway void getKeyIds(in String[] ids, in boolean allowUserInteraction, in IOpenPgpKeyIdsCallback callback);
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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;
|
||||||
|
|
||||||
|
// Declare OpenPgpData so AIDL can find it and knows that it implements the parcelable protocol.
|
||||||
|
parcelable OpenPgpData;
|
125
OpenPGP-Keychain/src/org/openintents/openpgp/OpenPgpData.java
Normal file
125
OpenPGP-Keychain/src/org/openintents/openpgp/OpenPgpData.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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.net.Uri;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public class OpenPgpData implements Parcelable {
|
||||||
|
public static final int TYPE_STRING = 0;
|
||||||
|
public static final int TYPE_BYTE_ARRAY = 1;
|
||||||
|
public static final int TYPE_FILE_DESCRIPTOR = 2;
|
||||||
|
public static final int TYPE_URI = 3;
|
||||||
|
|
||||||
|
int type;
|
||||||
|
|
||||||
|
String string;
|
||||||
|
byte[] bytes = new byte[0];
|
||||||
|
ParcelFileDescriptor fileDescriptor;
|
||||||
|
Uri uri;
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString() {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBytes() {
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParcelFileDescriptor getFileDescriptor() {
|
||||||
|
return fileDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri getUri() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not a real constructor. This can be used to define requested output type.
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
public OpenPgpData(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(String string) {
|
||||||
|
this.string = string;
|
||||||
|
this.type = TYPE_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(byte[] bytes) {
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.type = TYPE_BYTE_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(ParcelFileDescriptor fileDescriptor) {
|
||||||
|
this.fileDescriptor = fileDescriptor;
|
||||||
|
this.type = TYPE_FILE_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(Uri uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
this.type = TYPE_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData(OpenPgpData b) {
|
||||||
|
this.string = b.string;
|
||||||
|
this.bytes = b.bytes;
|
||||||
|
this.fileDescriptor = b.fileDescriptor;
|
||||||
|
this.uri = b.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(string);
|
||||||
|
dest.writeInt(bytes.length);
|
||||||
|
dest.writeByteArray(bytes);
|
||||||
|
dest.writeParcelable(fileDescriptor, 0);
|
||||||
|
dest.writeParcelable(uri, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<OpenPgpData> CREATOR = new Creator<OpenPgpData>() {
|
||||||
|
public OpenPgpData createFromParcel(final Parcel source) {
|
||||||
|
OpenPgpData vr = new OpenPgpData();
|
||||||
|
vr.string = source.readString();
|
||||||
|
vr.bytes = new byte[source.readInt()];
|
||||||
|
source.readByteArray(vr.bytes);
|
||||||
|
vr.fileDescriptor = source.readParcelable(ParcelFileDescriptor.class.getClassLoader());
|
||||||
|
vr.fileDescriptor = source.readParcelable(Uri.class.getClassLoader());
|
||||||
|
return vr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpData[] newArray(final int size) {
|
||||||
|
return new OpenPgpData[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -25,40 +25,50 @@ public class OpenPgpSignatureResult implements Parcelable {
|
|||||||
// successfully verified signature, with trusted public key
|
// successfully verified signature, with trusted public key
|
||||||
public static final int SIGNATURE_SUCCESS_TRUSTED = 1;
|
public static final int SIGNATURE_SUCCESS_TRUSTED = 1;
|
||||||
// no public key was found for this signature verification
|
// 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;
|
public static final int SIGNATURE_UNKNOWN_PUB_KEY = 2;
|
||||||
// successfully verified signature, but with untrusted public key
|
// successfully verified signature, but with untrusted public key
|
||||||
public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3;
|
public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3;
|
||||||
|
|
||||||
int signatureStatus;
|
int status;
|
||||||
String signatureUserId;
|
|
||||||
boolean signatureOnly;
|
boolean signatureOnly;
|
||||||
|
String userId;
|
||||||
|
long keyId;
|
||||||
|
|
||||||
public int getSignatureStatus() {
|
public int getStatus() {
|
||||||
return signatureStatus;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignatureUserId() {
|
|
||||||
return signatureUserId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSignatureOnly() {
|
public boolean isSignatureOnly() {
|
||||||
return signatureOnly;
|
return signatureOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getKeyId() {
|
||||||
|
return keyId;
|
||||||
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult() {
|
public OpenPgpSignatureResult() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult(int signatureStatus, String signatureUserId, boolean signatureOnly) {
|
public OpenPgpSignatureResult(int signatureStatus, String signatureUserId,
|
||||||
this.signatureStatus = signatureStatus;
|
boolean signatureOnly, long keyId) {
|
||||||
this.signatureUserId = signatureUserId;
|
this.status = signatureStatus;
|
||||||
this.signatureOnly = signatureOnly;
|
this.signatureOnly = signatureOnly;
|
||||||
|
this.userId = signatureUserId;
|
||||||
|
this.keyId = keyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpSignatureResult(OpenPgpSignatureResult b) {
|
public OpenPgpSignatureResult(OpenPgpSignatureResult b) {
|
||||||
this.signatureStatus = b.signatureStatus;
|
this.status = b.status;
|
||||||
this.signatureUserId = b.signatureUserId;
|
this.userId = b.userId;
|
||||||
this.signatureOnly = b.signatureOnly;
|
this.signatureOnly = b.signatureOnly;
|
||||||
|
this.keyId = b.keyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
@ -66,17 +76,19 @@ public class OpenPgpSignatureResult implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeInt(signatureStatus);
|
dest.writeInt(status);
|
||||||
dest.writeString(signatureUserId);
|
|
||||||
dest.writeByte((byte) (signatureOnly ? 1 : 0));
|
dest.writeByte((byte) (signatureOnly ? 1 : 0));
|
||||||
|
dest.writeString(userId);
|
||||||
|
dest.writeLong(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() {
|
public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() {
|
||||||
public OpenPgpSignatureResult createFromParcel(final Parcel source) {
|
public OpenPgpSignatureResult createFromParcel(final Parcel source) {
|
||||||
OpenPgpSignatureResult vr = new OpenPgpSignatureResult();
|
OpenPgpSignatureResult vr = new OpenPgpSignatureResult();
|
||||||
vr.signatureStatus = source.readInt();
|
vr.status = source.readInt();
|
||||||
vr.signatureUserId = source.readString();
|
|
||||||
vr.signatureOnly = source.readByte() == 1;
|
vr.signatureOnly = source.readByte() == 1;
|
||||||
|
vr.userId = source.readString();
|
||||||
|
vr.keyId = source.readLong();
|
||||||
return vr;
|
return vr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,9 +100,10 @@ public class OpenPgpSignatureResult implements Parcelable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String out = new String();
|
String out = new String();
|
||||||
out += "\nsignatureStatus: " + signatureStatus;
|
out += "\nstatus: " + status;
|
||||||
out += "\nsignatureUserId: " + signatureUserId;
|
out += "\nuserId: " + userId;
|
||||||
out += "\nsignatureOnly: " + signatureOnly;
|
out += "\nsignatureOnly: " + signatureOnly;
|
||||||
|
out += "\nkeyId: " + keyId;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,9 +25,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import org.openintents.openpgp.IOpenPgpCallback;
|
import org.openintents.openpgp.IOpenPgpCallback;
|
||||||
|
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||||
import org.openintents.openpgp.IOpenPgpService;
|
import org.openintents.openpgp.IOpenPgpService;
|
||||||
|
import org.openintents.openpgp.OpenPgpData;
|
||||||
import org.openintents.openpgp.OpenPgpError;
|
import org.openintents.openpgp.OpenPgpError;
|
||||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@ -114,8 +117,8 @@ public class OpenPgpService extends RemoteService {
|
|||||||
* @param encryptionUserIds
|
* @param encryptionUserIds
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private long[] getKeyIdsFromEmails(String[] encryptionUserIds, long ownKeyId,
|
private long[] getKeyIdsFromEmails(String[] encryptionUserIds, boolean allowUserInteraction)
|
||||||
boolean allowUserInteraction) throws UserInteractionRequiredException {
|
throws UserInteractionRequiredException {
|
||||||
// find key ids to given emails in database
|
// find key ids to given emails in database
|
||||||
ArrayList<Long> keyIds = new ArrayList<Long>();
|
ArrayList<Long> keyIds = new ArrayList<Long>();
|
||||||
|
|
||||||
@ -142,9 +145,6 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// also encrypt to our self (so that we can decrypt it later!)
|
|
||||||
keyIds.add(ownKeyId);
|
|
||||||
|
|
||||||
// convert to long[]
|
// convert to long[]
|
||||||
long[] keyIdsArray = new long[keyIds.size()];
|
long[] keyIdsArray = new long[keyIds.size()];
|
||||||
for (int i = 0; i < keyIdsArray.length; i++) {
|
for (int i = 0; i < keyIdsArray.length; i++) {
|
||||||
@ -215,24 +215,47 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private synchronized void encryptAndSignSafe(byte[] inputBytes, String[] encryptionUserIds,
|
private synchronized void getKeyIdsSafe(String[] userIds, boolean allowUserInteraction,
|
||||||
boolean asciiArmor, boolean allowUserInteraction, IOpenPgpCallback callback,
|
IOpenPgpKeyIdsCallback callback, AppSettings appSettings) {
|
||||||
AppSettings appSettings, boolean sign) {
|
|
||||||
try {
|
try {
|
||||||
// build InputData and write into OutputStream
|
long[] keyIds = getKeyIdsFromEmails(userIds, allowUserInteraction);
|
||||||
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
|
||||||
long inputLength = inputBytes.length;
|
|
||||||
InputData inputData = new InputData(inputStream, inputLength);
|
|
||||||
|
|
||||||
OutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
long[] keyIds = getKeyIdsFromEmails(encryptionUserIds, appSettings.getKeyId(),
|
|
||||||
allowUserInteraction);
|
|
||||||
if (keyIds == null) {
|
if (keyIds == null) {
|
||||||
throw new NoUserIdsException("No user ids!");
|
throw new NoUserIdsException("No user ids!");
|
||||||
}
|
}
|
||||||
|
|
||||||
PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream);
|
callback.onSuccess(keyIds);
|
||||||
|
} catch (UserInteractionRequiredException e) {
|
||||||
|
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
||||||
|
} catch (NoUserIdsException e) {
|
||||||
|
callbackOpenPgpError(callback, OpenPgpError.NO_USER_IDS, e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void encryptAndSignSafe(OpenPgpData inputData,
|
||||||
|
final OpenPgpData outputData, long[] keyIds, boolean allowUserInteraction,
|
||||||
|
IOpenPgpCallback callback, AppSettings appSettings, boolean sign) {
|
||||||
|
try {
|
||||||
|
// TODO: other options of OpenPgpData!
|
||||||
|
byte[] inputBytes = getInput(inputData);
|
||||||
|
boolean asciiArmor = false;
|
||||||
|
if (outputData.getType() == OpenPgpData.TYPE_STRING) {
|
||||||
|
asciiArmor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add own key for encryption
|
||||||
|
keyIds = Arrays.copyOf(keyIds, keyIds.length + 1);
|
||||||
|
keyIds[keyIds.length - 1] = appSettings.getKeyId();
|
||||||
|
|
||||||
|
// build InputData and write into OutputStream
|
||||||
|
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
||||||
|
long inputLength = inputBytes.length;
|
||||||
|
InputData inputDt = new InputData(inputStream, inputLength);
|
||||||
|
|
||||||
|
OutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
PgpOperation operation = new PgpOperation(getContext(), null, inputDt, outputStream);
|
||||||
if (sign) {
|
if (sign) {
|
||||||
String passphrase = getCachedPassphrase(appSettings.getKeyId(),
|
String passphrase = getCachedPassphrase(appSettings.getKeyId(),
|
||||||
allowUserInteraction);
|
allowUserInteraction);
|
||||||
@ -253,12 +276,17 @@ public class OpenPgpService extends RemoteService {
|
|||||||
|
|
||||||
byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
|
byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
|
||||||
|
|
||||||
|
OpenPgpData output = null;
|
||||||
|
if (asciiArmor) {
|
||||||
|
output = new OpenPgpData(new String(outputBytes));
|
||||||
|
} else {
|
||||||
|
output = new OpenPgpData(outputBytes);
|
||||||
|
}
|
||||||
|
|
||||||
// return over handler on client side
|
// return over handler on client side
|
||||||
callback.onSuccess(outputBytes, null);
|
callback.onSuccess(output, null);
|
||||||
} catch (UserInteractionRequiredException e) {
|
} catch (UserInteractionRequiredException e) {
|
||||||
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
||||||
} catch (NoUserIdsException e) {
|
|
||||||
callbackOpenPgpError(callback, OpenPgpError.NO_USER_IDS, e.getMessage());
|
|
||||||
} catch (WrongPassphraseException e) {
|
} catch (WrongPassphraseException e) {
|
||||||
callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage());
|
callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -289,9 +317,10 @@ public class OpenPgpService extends RemoteService {
|
|||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
|
||||||
byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
|
byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
|
||||||
|
OpenPgpData output = new OpenPgpData(new String(outputBytes));
|
||||||
|
|
||||||
// return over handler on client side
|
// return over handler on client side
|
||||||
callback.onSuccess(outputBytes, null);
|
callback.onSuccess(output, null);
|
||||||
} catch (UserInteractionRequiredException e) {
|
} catch (UserInteractionRequiredException e) {
|
||||||
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
||||||
} catch (WrongPassphraseException e) {
|
} catch (WrongPassphraseException e) {
|
||||||
@ -406,8 +435,8 @@ public class OpenPgpService extends RemoteService {
|
|||||||
|
|
||||||
OpenPgpSignatureResult sigResult = null;
|
OpenPgpSignatureResult sigResult = null;
|
||||||
if (signature) {
|
if (signature) {
|
||||||
// long signatureKeyId = outputBundle
|
long signatureKeyId = outputBundle
|
||||||
// .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
||||||
String signatureUserId = outputBundle
|
String signatureUserId = outputBundle
|
||||||
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
||||||
boolean signatureSuccess = outputBundle
|
boolean signatureSuccess = outputBundle
|
||||||
@ -422,11 +451,13 @@ public class OpenPgpService extends RemoteService {
|
|||||||
signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
|
signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId, signedOnly);
|
sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId,
|
||||||
|
signedOnly, signatureKeyId);
|
||||||
}
|
}
|
||||||
|
OpenPgpData output = new OpenPgpData(new String(outputBytes));
|
||||||
|
|
||||||
// return over handler on client side
|
// return over handler on client side
|
||||||
callback.onSuccess(outputBytes, sigResult);
|
callback.onSuccess(output, sigResult);
|
||||||
} catch (UserInteractionRequiredException e) {
|
} catch (UserInteractionRequiredException e) {
|
||||||
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
||||||
} catch (WrongPassphraseException e) {
|
} catch (WrongPassphraseException e) {
|
||||||
@ -452,49 +483,26 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void callbackOpenPgpError(IOpenPgpKeyIdsCallback callback, int errorId, String message) {
|
||||||
|
try {
|
||||||
|
callback.onError(new OpenPgpError(0, message));
|
||||||
|
} catch (Exception t) {
|
||||||
|
Log.e(Constants.TAG,
|
||||||
|
"Exception while returning OpenPgpError to client via callback.onError()", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
|
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds,
|
public void encrypt(final OpenPgpData input, final OpenPgpData output, final long[] keyIds,
|
||||||
final boolean asciiArmor, final IOpenPgpCallback callback) throws RemoteException {
|
|
||||||
final AppSettings settings = getAppSettings();
|
|
||||||
|
|
||||||
Runnable r = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, true, callback,
|
|
||||||
settings, false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
checkAndEnqueue(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void signAndEncrypt(final byte[] inputBytes, final String[] encryptionUserIds,
|
|
||||||
final boolean asciiArmor, final IOpenPgpCallback callback) throws RemoteException {
|
|
||||||
final AppSettings settings = getAppSettings();
|
|
||||||
|
|
||||||
Runnable r = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, true, callback,
|
|
||||||
settings, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
checkAndEnqueue(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sign(final byte[] inputBytes, boolean asciiArmor,
|
|
||||||
final IOpenPgpCallback callback) throws RemoteException {
|
final IOpenPgpCallback callback) throws RemoteException {
|
||||||
final AppSettings settings = getAppSettings();
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
Runnable r = new Runnable() {
|
Runnable r = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
signSafe(inputBytes, true, callback, settings);
|
encryptAndSignSafe(input, output, keyIds, true, callback, settings, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -502,15 +510,45 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decryptAndVerify(final byte[] inputBytes, final IOpenPgpCallback callback)
|
public void signAndEncrypt(final OpenPgpData input, final OpenPgpData output,
|
||||||
throws RemoteException {
|
final long[] keyIds, final IOpenPgpCallback callback) throws RemoteException {
|
||||||
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
encryptAndSignSafe(input, output, keyIds, true, callback, settings, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkAndEnqueue(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sign(final OpenPgpData input, final OpenPgpData output,
|
||||||
|
final IOpenPgpCallback callback) throws RemoteException {
|
||||||
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
signSafe(getInput(input), true, callback, settings);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkAndEnqueue(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decryptAndVerify(final OpenPgpData input, final OpenPgpData output,
|
||||||
|
final IOpenPgpCallback callback) throws RemoteException {
|
||||||
|
|
||||||
final AppSettings settings = getAppSettings();
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
Runnable r = new Runnable() {
|
Runnable r = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
decryptAndVerifySafe(inputBytes, true, callback, settings);
|
decryptAndVerifySafe(getInput(input), true, callback, settings);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -518,13 +556,44 @@ public class OpenPgpService extends RemoteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isKeyAvailable(String[] userIds) throws RemoteException {
|
public void getKeyIds(final String[] userIds, final boolean allowUserInteraction,
|
||||||
// TODO
|
final IOpenPgpKeyIdsCallback callback) throws RemoteException {
|
||||||
return false;
|
|
||||||
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getKeyIdsSafe(userIds, allowUserInteraction, callback, settings);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkAndEnqueue(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static byte[] getInput(OpenPgpData data) {
|
||||||
|
// TODO: support Uri and ParcelFileDescriptor
|
||||||
|
|
||||||
|
byte[] inBytes = null;
|
||||||
|
switch (data.getType()) {
|
||||||
|
case OpenPgpData.TYPE_STRING:
|
||||||
|
inBytes = data.getString().getBytes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpenPgpData.TYPE_BYTE_ARRAY:
|
||||||
|
inBytes = data.getBytes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log.e(Constants.TAG, "Uri and ParcelFileDescriptor not supported right now!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inBytes;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return mBinder;
|
return mBinder;
|
||||||
|
@ -166,7 +166,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
|
|||||||
mListFragment = ImportKeysListFragment.newInstance(bytes, filename);
|
mListFragment = ImportKeysListFragment.newInstance(bytes, filename);
|
||||||
|
|
||||||
// Add the fragment to the 'fragment_container' FrameLayout
|
// Add the fragment to the 'fragment_container' FrameLayout
|
||||||
// NOTE: We use commitAllowingStateLoss() to prevent wierd crashes!
|
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.replace(R.id.import_keys_list_container, mListFragment)
|
.replace(R.id.import_keys_list_container, mListFragment)
|
||||||
.commitAllowingStateLoss();
|
.commitAllowingStateLoss();
|
||||||
@ -189,6 +189,9 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
|
|||||||
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]);
|
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]);
|
loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
public class ImportKeysClipboardFragment extends Fragment {
|
||||||
|
|
||||||
|
private ImportKeysActivity mImportActivity;
|
||||||
|
private Button mButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new instance of this fragment
|
||||||
|
*/
|
||||||
|
public static ImportKeysClipboardFragment newInstance() {
|
||||||
|
ImportKeysClipboardFragment frag = new ImportKeysClipboardFragment();
|
||||||
|
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
frag.setArguments(args);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inflate the layout for this fragment
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.import_keys_clipboard_fragment, container, false);
|
||||||
|
|
||||||
|
mButton = (Button) view.findViewById(R.id.import_clipboard_button);
|
||||||
|
mButton.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
|
||||||
|
|
||||||
|
mImportActivity.loadCallback(clipboardText.toString().getBytes(), null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
|
||||||
|
mImportActivity = (ImportKeysActivity) getActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user