mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 17:22:16 -05:00
New API version, import from clipboard
This commit is contained in:
parent
c75c00f935
commit
bef6977aad
@ -26,7 +26,7 @@
|
||||
<EditText
|
||||
android:id="@+id/crypto_provider_demo_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dip"
|
||||
android:layout_height="100dip"
|
||||
android:scrollHorizontally="true"
|
||||
android:scrollbars="vertical"
|
||||
android:text="message"
|
||||
@ -41,7 +41,7 @@
|
||||
<EditText
|
||||
android:id="@+id/crypto_provider_demo_ciphertext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dip"
|
||||
android:layout_height="100dip"
|
||||
android:text="ciphertext"
|
||||
android:textAppearance="@android:style/TextAppearance.Small" />
|
||||
|
||||
@ -67,19 +67,17 @@
|
||||
|
||||
<Button
|
||||
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_weight="1"
|
||||
android:onClick="encryptAndSignOnClick"
|
||||
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" />
|
||||
android:onClick="signAndEncryptOnClick"
|
||||
android:text="Sign and Encrypt" />
|
||||
</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>
|
@ -16,6 +16,7 @@
|
||||
|
||||
package org.openintents.openpgp;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpData;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
|
||||
@ -24,14 +25,14 @@ interface IOpenPgpCallback {
|
||||
/**
|
||||
* onSuccess returns on successful OpenPGP operations.
|
||||
*
|
||||
* @param outputBytes
|
||||
* contains resulting output bytes (decrypted content (when input was encrypted)
|
||||
* @param output
|
||||
* contains resulting output (decrypted content (when input was encrypted)
|
||||
* or content without signature (when input was signed-only))
|
||||
* @param signatureResult
|
||||
* signatureResult is only non-null if decryptAndVerify() was called and the content
|
||||
* was encrypted or signed-and-encrypted.
|
||||
*/
|
||||
oneway void onSuccess(in byte[] outputBytes, in OpenPgpSignatureResult signatureResult);
|
||||
oneway void onSuccess(in OpenPgpData output, in OpenPgpSignatureResult signatureResult);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpData;
|
||||
import org.openintents.openpgp.IOpenPgpCallback;
|
||||
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to encrypt
|
||||
* @param encryptionUserIds
|
||||
* User Ids (emails) of recipients
|
||||
* @param asciiArmor
|
||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param keyIds
|
||||
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
||||
in IOpenPgpCallback callback);
|
||||
oneway void encrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||
|
||||
/**
|
||||
* Sign
|
||||
*
|
||||
* After successful signing, callback's onSuccess will contain the resulting output bytes.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to sign
|
||||
* @param asciiArmor
|
||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in IOpenPgpCallback callback);
|
||||
oneway void sign(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
|
||||
|
||||
/**
|
||||
* Sign then encrypt
|
||||
*
|
||||
* After successful signing and encryption, callback's onSuccess will contain the resulting output bytes.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to sign and encrypt
|
||||
* @param encryptionUserIds
|
||||
* User Ids (emails) of recipients
|
||||
* @param asciiArmor
|
||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param keyIds
|
||||
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
||||
in IOpenPgpCallback callback);
|
||||
oneway void signAndEncrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||
|
||||
/**
|
||||
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
||||
@ -85,15 +109,35 @@ interface IOpenPgpService {
|
||||
* After successful decryption/verification, callback's onSuccess will contain the resulting output bytes.
|
||||
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to decrypt and verify
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void decryptAndVerify(in 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.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
@ -34,15 +36,17 @@ import android.widget.ListAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class OpenPgpListPreference extends DialogPreference {
|
||||
static final Intent intent = new Intent(IOpenPgpService.class.getName());
|
||||
|
||||
ArrayList<OpenPgpProviderEntry> mProviderList = new ArrayList<OpenPgpProviderEntry>();
|
||||
private String mSelectedPackage;
|
||||
|
||||
public static final int REQUIRED_API_VERSION = 1;
|
||||
|
||||
public OpenPgpListPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
List<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(intent, 0);
|
||||
List<ResolveInfo> resInfo =
|
||||
context.getPackageManager().queryIntentServices(
|
||||
new Intent(IOpenPgpService.class.getName()), PackageManager.GET_META_DATA);
|
||||
if (!resInfo.isEmpty()) {
|
||||
for (ResolveInfo resolveInfo : resInfo) {
|
||||
if (resolveInfo.serviceInfo == null)
|
||||
@ -52,7 +56,13 @@ public class OpenPgpListPreference extends DialogPreference {
|
||||
String simpleName = String.valueOf(resolveInfo.serviceInfo
|
||||
.loadLabel(context.getPackageManager()));
|
||||
Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager());
|
||||
mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon));
|
||||
|
||||
// get api version
|
||||
ServiceInfo si = resolveInfo.serviceInfo;
|
||||
int apiVersion = si.metaData.getInt("api_version");
|
||||
|
||||
mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon,
|
||||
apiVersion));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,8 +78,10 @@ public class OpenPgpListPreference extends DialogPreference {
|
||||
* @param simpleName
|
||||
* @param icon
|
||||
*/
|
||||
public void addProvider(int position, String packageName, String simpleName, Drawable icon) {
|
||||
mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon));
|
||||
public void addProvider(int position, String packageName, String simpleName, Drawable icon,
|
||||
int apiVersion) {
|
||||
mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon,
|
||||
apiVersion));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,13 +103,23 @@ public class OpenPgpListPreference extends DialogPreference {
|
||||
int dp5 = (int) (5 * getContext().getResources().getDisplayMetrics().density + 0.5f);
|
||||
tv.setCompoundDrawablePadding(dp5);
|
||||
|
||||
// disable if it has the wrong api_version
|
||||
if (mProviderList.get(position).apiVersion == REQUIRED_API_VERSION) {
|
||||
tv.setEnabled(true);
|
||||
} else {
|
||||
tv.setEnabled(false);
|
||||
tv.setText(tv.getText() + " (API v"
|
||||
+ mProviderList.get(position).apiVersion + ", needs v"
|
||||
+ REQUIRED_API_VERSION + ")");
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
builder.setSingleChoiceItems(adapter, getIndexOfProviderList(getValue()),
|
||||
new DialogInterface.OnClickListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mSelectedPackage = mProviderList.get(which).packageName;
|
||||
@ -167,11 +189,14 @@ public class OpenPgpListPreference extends DialogPreference {
|
||||
private String packageName;
|
||||
private String simpleName;
|
||||
private Drawable icon;
|
||||
private int apiVersion;
|
||||
|
||||
public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon) {
|
||||
public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon,
|
||||
int apiVersion) {
|
||||
this.packageName = packageName;
|
||||
this.simpleName = simpleName;
|
||||
this.icon = icon;
|
||||
this.apiVersion = apiVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,40 +25,50 @@ public class OpenPgpSignatureResult implements Parcelable {
|
||||
// successfully verified signature, with trusted public key
|
||||
public static final int SIGNATURE_SUCCESS_TRUSTED = 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 untrusted public key
|
||||
public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3;
|
||||
|
||||
int signatureStatus;
|
||||
String signatureUserId;
|
||||
int status;
|
||||
boolean signatureOnly;
|
||||
String userId;
|
||||
long keyId;
|
||||
|
||||
public int getSignatureStatus() {
|
||||
return signatureStatus;
|
||||
}
|
||||
|
||||
public String getSignatureUserId() {
|
||||
return signatureUserId;
|
||||
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) {
|
||||
this.signatureStatus = signatureStatus;
|
||||
this.signatureUserId = signatureUserId;
|
||||
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.signatureStatus = b.signatureStatus;
|
||||
this.signatureUserId = b.signatureUserId;
|
||||
this.status = b.status;
|
||||
this.userId = b.userId;
|
||||
this.signatureOnly = b.signatureOnly;
|
||||
this.keyId = b.keyId;
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
@ -66,17 +76,19 @@ public class OpenPgpSignatureResult implements Parcelable {
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(signatureStatus);
|
||||
dest.writeString(signatureUserId);
|
||||
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.signatureStatus = source.readInt();
|
||||
vr.signatureUserId = source.readString();
|
||||
vr.status = source.readInt();
|
||||
vr.signatureOnly = source.readByte() == 1;
|
||||
vr.userId = source.readString();
|
||||
vr.keyId = source.readLong();
|
||||
return vr;
|
||||
}
|
||||
|
||||
@ -88,9 +100,10 @@ public class OpenPgpSignatureResult implements Parcelable {
|
||||
@Override
|
||||
public String toString() {
|
||||
String out = new String();
|
||||
out += "\nsignatureStatus: " + signatureStatus;
|
||||
out += "\nsignatureUserId: " + signatureUserId;
|
||||
out += "\nstatus: " + status;
|
||||
out += "\nuserId: " + userId;
|
||||
out += "\nsignatureOnly: " + signatureOnly;
|
||||
out += "\nkeyId: " + keyId;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,6 @@ public final class Constants {
|
||||
|
||||
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.List;
|
||||
|
||||
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||
import org.openintents.openpgp.OpenPgpData;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
import org.openintents.openpgp.OpenPgpServiceConnection;
|
||||
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() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(final byte[] outputBytes, OpenPgpSignatureResult signatureResult)
|
||||
public void onSuccess(final OpenPgpData output, OpenPgpSignatureResult signatureResult)
|
||||
throws RemoteException {
|
||||
Log.d(Constants.TAG, "encryptCallback");
|
||||
|
||||
@ -79,7 +144,7 @@ public class OpenPgpProviderActivity extends Activity {
|
||||
|
||||
@Override
|
||||
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() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(final byte[] outputBytes, final OpenPgpSignatureResult signatureResult)
|
||||
public void onSuccess(final OpenPgpData output, final OpenPgpSignatureResult signatureResult)
|
||||
throws RemoteException {
|
||||
Log.d(Constants.TAG, "decryptAndVerifyCallback");
|
||||
|
||||
@ -102,7 +167,7 @@ public class OpenPgpProviderActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mMessage.setText(new String(outputBytes));
|
||||
mMessage.setText(output.getString());
|
||||
if (signatureResult != null) {
|
||||
Toast.makeText(OpenPgpProviderActivity.this,
|
||||
"signature result:\n" + signatureResult.toString(),
|
||||
@ -135,43 +200,43 @@ public class OpenPgpProviderActivity extends Activity {
|
||||
}
|
||||
|
||||
public void encryptOnClick(View view) {
|
||||
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
||||
|
||||
try {
|
||||
mCryptoServiceConnection.getService().encrypt(inputBytes,
|
||||
mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
|
||||
mCryptoServiceConnection.getService().getKeyIds(
|
||||
mEncryptUserIds.getText().toString().split(","), true, getKeysEncryptCallback);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void signOnClick(View view) {
|
||||
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
||||
String inputStr = mMessage.getText().toString();
|
||||
OpenPgpData input = new OpenPgpData(inputStr);
|
||||
|
||||
try {
|
||||
mCryptoServiceConnection.getService().sign(inputBytes, true, encryptCallback);
|
||||
mCryptoServiceConnection.getService().sign(input,
|
||||
new OpenPgpData(OpenPgpData.TYPE_STRING), encryptCallback);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void encryptAndSignOnClick(View view) {
|
||||
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
||||
|
||||
public void signAndEncryptOnClick(View view) {
|
||||
try {
|
||||
mCryptoServiceConnection.getService().signAndEncrypt(inputBytes,
|
||||
mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
|
||||
mCryptoServiceConnection.getService().getKeyIds(
|
||||
mEncryptUserIds.getText().toString().split(","), true,
|
||||
getKeysSignAndEncryptCallback);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void decryptAndVerifyOnClick(View view) {
|
||||
byte[] inputBytes = mCiphertext.getText().toString().getBytes();
|
||||
String inputStr = mCiphertext.getText().toString();
|
||||
OpenPgpData input = new OpenPgpData(inputStr);
|
||||
|
||||
try {
|
||||
mCryptoServiceConnection.getService().decryptAndVerify(inputBytes,
|
||||
decryptAndVerifyCallback);
|
||||
mCryptoServiceConnection.getService().decryptAndVerify(input,
|
||||
new OpenPgpData(OpenPgpData.TYPE_STRING), decryptAndVerifyCallback);
|
||||
} catch (RemoteException 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_keyServer</item>
|
||||
<item>@string/menu_importFromQrCode</item>
|
||||
<item>@string/import_from_clipboard</item>
|
||||
<item>@string/menu_importFromNfc</item>
|
||||
</string-array>
|
||||
|
||||
|
@ -351,6 +351,7 @@
|
||||
<string name="import_import">Import 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_from_clipboard">Import from Clipboard</string>
|
||||
|
||||
<!-- Intent labels -->
|
||||
<string name="intent_decrypt_file">OpenPGP: Decrypt File</string>
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package org.openintents.openpgp;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpData;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
|
||||
@ -24,14 +25,14 @@ interface IOpenPgpCallback {
|
||||
/**
|
||||
* onSuccess returns on successful OpenPGP operations.
|
||||
*
|
||||
* @param outputBytes
|
||||
* contains resulting output bytes (decrypted content (when input was encrypted)
|
||||
* @param output
|
||||
* contains resulting output (decrypted content (when input was encrypted)
|
||||
* or content without signature (when input was signed-only))
|
||||
* @param signatureResult
|
||||
* signatureResult is only non-null if decryptAndVerify() was called and the content
|
||||
* was encrypted or signed-and-encrypted.
|
||||
*/
|
||||
oneway void onSuccess(in byte[] outputBytes, in OpenPgpSignatureResult signatureResult);
|
||||
oneway void onSuccess(in OpenPgpData output, in OpenPgpSignatureResult signatureResult);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpData;
|
||||
import org.openintents.openpgp.IOpenPgpCallback;
|
||||
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to encrypt
|
||||
* @param encryptionUserIds
|
||||
* User Ids (emails) of recipients
|
||||
* @param asciiArmor
|
||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param keyIds
|
||||
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
||||
in IOpenPgpCallback callback);
|
||||
oneway void encrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||
|
||||
/**
|
||||
* Sign
|
||||
*
|
||||
* After successful signing, callback's onSuccess will contain the resulting output bytes.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to sign
|
||||
* @param asciiArmor
|
||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in IOpenPgpCallback callback);
|
||||
oneway void sign(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
|
||||
|
||||
/**
|
||||
* Sign then encrypt
|
||||
*
|
||||
* After successful signing and encryption, callback's onSuccess will contain the resulting output bytes.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to sign and encrypt
|
||||
* @param encryptionUserIds
|
||||
* User Ids (emails) of recipients
|
||||
* @param asciiArmor
|
||||
* Encode result for ASCII (Radix-64, 33 percent overhead compared to binary)
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param keyIds
|
||||
* Key Ids of recipients. Can be retrieved with getKeyIds()
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void signAndEncrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor,
|
||||
in IOpenPgpCallback callback);
|
||||
oneway void signAndEncrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
|
||||
|
||||
/**
|
||||
* Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted,
|
||||
@ -85,15 +109,35 @@ interface IOpenPgpService {
|
||||
* After successful decryption/verification, callback's onSuccess will contain the resulting output bytes.
|
||||
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
|
||||
*
|
||||
* @param inputBytes
|
||||
* Byte array you want to decrypt and verify
|
||||
* @param allowUserInteraction
|
||||
* Allows the OpenPGP Provider to handle missing keys by showing activities
|
||||
* @param input
|
||||
* OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri
|
||||
* @param output
|
||||
* Request output format by defining OpenPgpData object
|
||||
*
|
||||
* new OpenPgpData(OpenPgpData.TYPE_STRING)
|
||||
* Returns as String
|
||||
* (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
|
||||
* new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY)
|
||||
* Returns as byte[]
|
||||
* new OpenPgpData(uri)
|
||||
* Writes output to given Uri
|
||||
* new OpenPgpData(fileDescriptor)
|
||||
* Writes output to given ParcelFileDescriptor
|
||||
* @param callback
|
||||
* Callback where to return results
|
||||
*/
|
||||
oneway void decryptAndVerify(in 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
|
||||
public static final int SIGNATURE_SUCCESS_TRUSTED = 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 untrusted public key
|
||||
public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3;
|
||||
|
||||
int signatureStatus;
|
||||
String signatureUserId;
|
||||
int status;
|
||||
boolean signatureOnly;
|
||||
String userId;
|
||||
long keyId;
|
||||
|
||||
public int getSignatureStatus() {
|
||||
return signatureStatus;
|
||||
}
|
||||
|
||||
public String getSignatureUserId() {
|
||||
return signatureUserId;
|
||||
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) {
|
||||
this.signatureStatus = signatureStatus;
|
||||
this.signatureUserId = signatureUserId;
|
||||
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.signatureStatus = b.signatureStatus;
|
||||
this.signatureUserId = b.signatureUserId;
|
||||
this.status = b.status;
|
||||
this.userId = b.userId;
|
||||
this.signatureOnly = b.signatureOnly;
|
||||
this.keyId = b.keyId;
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
@ -66,17 +76,19 @@ public class OpenPgpSignatureResult implements Parcelable {
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(signatureStatus);
|
||||
dest.writeString(signatureUserId);
|
||||
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.signatureStatus = source.readInt();
|
||||
vr.signatureUserId = source.readString();
|
||||
vr.status = source.readInt();
|
||||
vr.signatureOnly = source.readByte() == 1;
|
||||
vr.userId = source.readString();
|
||||
vr.keyId = source.readLong();
|
||||
return vr;
|
||||
}
|
||||
|
||||
@ -88,9 +100,10 @@ public class OpenPgpSignatureResult implements Parcelable {
|
||||
@Override
|
||||
public String toString() {
|
||||
String out = new String();
|
||||
out += "\nsignatureStatus: " + signatureStatus;
|
||||
out += "\nsignatureUserId: " + signatureUserId;
|
||||
out += "\nstatus: " + status;
|
||||
out += "\nuserId: " + userId;
|
||||
out += "\nsignatureOnly: " + signatureOnly;
|
||||
out += "\nkeyId: " + keyId;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,12 @@ import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.openintents.openpgp.IOpenPgpCallback;
|
||||
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
|
||||
import org.openintents.openpgp.IOpenPgpService;
|
||||
import org.openintents.openpgp.OpenPgpData;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.Id;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
@ -114,8 +117,8 @@ public class OpenPgpService extends RemoteService {
|
||||
* @param encryptionUserIds
|
||||
* @return
|
||||
*/
|
||||
private long[] getKeyIdsFromEmails(String[] encryptionUserIds, long ownKeyId,
|
||||
boolean allowUserInteraction) throws UserInteractionRequiredException {
|
||||
private long[] getKeyIdsFromEmails(String[] encryptionUserIds, boolean allowUserInteraction)
|
||||
throws UserInteractionRequiredException {
|
||||
// find key ids to given emails in database
|
||||
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[]
|
||||
long[] keyIdsArray = new long[keyIds.size()];
|
||||
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,
|
||||
boolean asciiArmor, boolean allowUserInteraction, IOpenPgpCallback callback,
|
||||
AppSettings appSettings, boolean sign) {
|
||||
private synchronized void getKeyIdsSafe(String[] userIds, boolean allowUserInteraction,
|
||||
IOpenPgpKeyIdsCallback callback, AppSettings appSettings) {
|
||||
try {
|
||||
// build InputData and write into OutputStream
|
||||
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);
|
||||
long[] keyIds = getKeyIdsFromEmails(userIds, allowUserInteraction);
|
||||
if (keyIds == null) {
|
||||
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) {
|
||||
String passphrase = getCachedPassphrase(appSettings.getKeyId(),
|
||||
allowUserInteraction);
|
||||
@ -253,12 +276,17 @@ public class OpenPgpService extends RemoteService {
|
||||
|
||||
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
|
||||
callback.onSuccess(outputBytes, null);
|
||||
callback.onSuccess(output, null);
|
||||
} catch (UserInteractionRequiredException e) {
|
||||
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
||||
} catch (NoUserIdsException e) {
|
||||
callbackOpenPgpError(callback, OpenPgpError.NO_USER_IDS, e.getMessage());
|
||||
} catch (WrongPassphraseException e) {
|
||||
callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage());
|
||||
} catch (Exception e) {
|
||||
@ -289,9 +317,10 @@ public class OpenPgpService extends RemoteService {
|
||||
outputStream.close();
|
||||
|
||||
byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray();
|
||||
OpenPgpData output = new OpenPgpData(new String(outputBytes));
|
||||
|
||||
// return over handler on client side
|
||||
callback.onSuccess(outputBytes, null);
|
||||
callback.onSuccess(output, null);
|
||||
} catch (UserInteractionRequiredException e) {
|
||||
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
||||
} catch (WrongPassphraseException e) {
|
||||
@ -406,8 +435,8 @@ public class OpenPgpService extends RemoteService {
|
||||
|
||||
OpenPgpSignatureResult sigResult = null;
|
||||
if (signature) {
|
||||
// long signatureKeyId = outputBundle
|
||||
// .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
||||
long signatureKeyId = outputBundle
|
||||
.getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
|
||||
String signatureUserId = outputBundle
|
||||
.getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
|
||||
boolean signatureSuccess = outputBundle
|
||||
@ -422,11 +451,13 @@ public class OpenPgpService extends RemoteService {
|
||||
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
|
||||
callback.onSuccess(outputBytes, sigResult);
|
||||
callback.onSuccess(output, sigResult);
|
||||
} catch (UserInteractionRequiredException e) {
|
||||
callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage());
|
||||
} 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() {
|
||||
|
||||
@Override
|
||||
public void encrypt(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, 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,
|
||||
public void encrypt(final OpenPgpData input, final OpenPgpData output, final long[] keyIds,
|
||||
final IOpenPgpCallback callback) throws RemoteException {
|
||||
final AppSettings settings = getAppSettings();
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
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
|
||||
public void decryptAndVerify(final byte[] inputBytes, final IOpenPgpCallback callback)
|
||||
throws RemoteException {
|
||||
public void signAndEncrypt(final OpenPgpData input, final OpenPgpData output,
|
||||
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();
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
decryptAndVerifySafe(inputBytes, true, callback, settings);
|
||||
decryptAndVerifySafe(getInput(input), true, callback, settings);
|
||||
}
|
||||
};
|
||||
|
||||
@ -518,13 +556,44 @@ public class OpenPgpService extends RemoteService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyAvailable(String[] userIds) throws RemoteException {
|
||||
// TODO
|
||||
return false;
|
||||
public void getKeyIds(final String[] userIds, final boolean allowUserInteraction,
|
||||
final IOpenPgpKeyIdsCallback callback) throws RemoteException {
|
||||
|
||||
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
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
|
@ -166,7 +166,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
|
||||
mListFragment = ImportKeysListFragment.newInstance(bytes, filename);
|
||||
|
||||
// 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()
|
||||
.replace(R.id.import_keys_list_container, mListFragment)
|
||||
.commitAllowingStateLoss();
|
||||
@ -189,6 +189,9 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
|
||||
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]);
|
||||
break;
|
||||
case 3:
|
||||
loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]);
|
||||
break;
|
||||
case 4:
|
||||
loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]);
|
||||
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