New gradle folder structure for API Demo

This commit is contained in:
Dominik Schürmann
2014-01-27 14:44:20 +01:00
parent e360bb10f6
commit ca462a2d6c
36 changed files with 349 additions and 114 deletions

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.sufficientlysecure.keychain.demo"
android:versionCode="2"
android:versionName="1.1" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="OpenPGP Keychain API Demo" >
<activity
android:name=".BaseActivity"
android:label="OpenPGP Keychain API Demo" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".OpenPgpProviderActivity"
android:label="OpenPGP Provider"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".AidlDemoActivity2"
android:label="Aidl Demo (ACCESS_KEYS permission)"
android:windowSoftInputMode="stateHidden" />
</application>
</manifest>

View File

@@ -0,0 +1,45 @@
/*
* 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.OpenPgpData;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.OpenPgpError;
interface IOpenPgpCallback {
/**
* onSuccess returns on successful OpenPGP operations.
*
* @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 OpenPgpData output, in OpenPgpSignatureResult signatureResult);
/**
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
* was required execute an OpenPGP operation.
*
* @param error
* See OpenPgpError class for more information.
*/
oneway void onError(in OpenPgpError error);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,143 @@
/*
* 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.OpenPgpData;
import org.openintents.openpgp.IOpenPgpCallback;
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
/**
* All methods are oneway, which means they are asynchronous and non-blocking.
* Results are returned to the callback, which has to be implemented on client side.
*/
interface IOpenPgpService {
/**
* Sign
*
* After successful signing, callback's onSuccess will contain the resulting output.
*
* @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 OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
/**
* Encrypt
*
* After successful encryption, callback's onSuccess will contain the resulting output.
*
* @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 OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
/**
* Sign then encrypt
*
* After successful signing and encryption, callback's onSuccess will contain the resulting output.
*
* @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 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,
* and also signed-only input.
*
* After successful decryption/verification, callback's onSuccess will contain the resulting output.
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
*
* @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 OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
/**
* 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);
}

View File

@@ -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;

View File

@@ -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 OpenPgpError so AIDL can find it and knows that it implements the parcelable protocol.
parcelable OpenPgpError;

View File

@@ -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 OpenPgpSignatureResult so AIDL can find it and knows that it implements the parcelable protocol.
parcelable OpenPgpSignatureResult;

View File

@@ -0,0 +1,45 @@
/*
* 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.OpenPgpData;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.OpenPgpError;
interface IOpenPgpCallback {
/**
* onSuccess returns on successful OpenPGP operations.
*
* @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 OpenPgpData output, in OpenPgpSignatureResult signatureResult);
/**
* onError returns on errors or when allowUserInteraction was set to false, but user interaction
* was required execute an OpenPGP operation.
*
* @param error
* See OpenPgpError class for more information.
*/
oneway void onError(in OpenPgpError error);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,143 @@
/*
* 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.OpenPgpData;
import org.openintents.openpgp.IOpenPgpCallback;
import org.openintents.openpgp.IOpenPgpKeyIdsCallback;
/**
* All methods are oneway, which means they are asynchronous and non-blocking.
* Results are returned to the callback, which has to be implemented on client side.
*/
interface IOpenPgpService {
/**
* Sign
*
* After successful signing, callback's onSuccess will contain the resulting output.
*
* @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 OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
/**
* Encrypt
*
* After successful encryption, callback's onSuccess will contain the resulting output.
*
* @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 OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback);
/**
* Sign then encrypt
*
* After successful signing and encryption, callback's onSuccess will contain the resulting output.
*
* @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 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,
* and also signed-only input.
*
* After successful decryption/verification, callback's onSuccess will contain the resulting output.
* The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given.
*
* @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 OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback);
/**
* 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);
}

View File

@@ -0,0 +1,10 @@
package org.openintents.openpgp;
public class OpenPgpConstants {
public static final String TAG = "OpenPgp API";
public static final int REQUIRED_API_VERSION = 1;
public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService";
}

View File

@@ -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;

View File

@@ -0,0 +1,127 @@
/*
* 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.writeInt(type);
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.type = source.readInt();
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];
}
};
}

View File

@@ -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 OpenPgpError so AIDL can find it and knows that it implements the parcelable protocol.
parcelable OpenPgpError;

View File

@@ -0,0 +1,81 @@
/*
* 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.os.Parcel;
import android.os.Parcelable;
public class OpenPgpError implements Parcelable {
public static final int GENERIC_ERROR = 0;
public static final int NO_OR_WRONG_PASSPHRASE = 1;
public static final int NO_USER_IDS = 2;
public static final int USER_INTERACTION_REQUIRED = 3;
int errorId;
String message;
public OpenPgpError() {
}
public OpenPgpError(int errorId, String message) {
this.errorId = errorId;
this.message = message;
}
public OpenPgpError(OpenPgpError b) {
this.errorId = b.errorId;
this.message = b.message;
}
public int getErrorId() {
return errorId;
}
public void setErrorId(int errorId) {
this.errorId = errorId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(errorId);
dest.writeString(message);
}
public static final Creator<OpenPgpError> CREATOR = new Creator<OpenPgpError>() {
public OpenPgpError createFromParcel(final Parcel source) {
OpenPgpError error = new OpenPgpError();
error.errorId = source.readInt();
error.message = source.readString();
return error;
}
public OpenPgpError[] newArray(final int size) {
return new OpenPgpError[size];
}
};
}

View File

@@ -0,0 +1,52 @@
/*
* 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 java.util.List;
import java.util.regex.Pattern;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
public class OpenPgpHelper {
private Context context;
public static Pattern PGP_MESSAGE = Pattern.compile(
".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL);
public static Pattern PGP_SIGNED_MESSAGE = Pattern
.compile(
".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
Pattern.DOTALL);
public OpenPgpHelper(Context context) {
super();
this.context = context;
}
public boolean isAvailable() {
Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT);
List<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(intent, 0);
if (!resInfo.isEmpty()) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,203 @@
/*
* 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 java.util.ArrayList;
import java.util.List;
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.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.TextView;
public class OpenPgpListPreference extends DialogPreference {
ArrayList<OpenPgpProviderEntry> mProviderList = new ArrayList<OpenPgpProviderEntry>();
private String mSelectedPackage;
public OpenPgpListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
List<ResolveInfo> resInfo = context.getPackageManager().queryIntentServices(
new Intent(OpenPgpConstants.SERVICE_INTENT), PackageManager.GET_META_DATA);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
if (resolveInfo.serviceInfo == null)
continue;
String packageName = resolveInfo.serviceInfo.packageName;
String simpleName = String.valueOf(resolveInfo.serviceInfo.loadLabel(context
.getPackageManager()));
Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager());
// get api version
ServiceInfo si = resolveInfo.serviceInfo;
int apiVersion = si.metaData.getInt("api_version");
mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon,
apiVersion));
}
}
}
public OpenPgpListPreference(Context context) {
this(context, null);
}
/**
* Can be used to add "no selection"
*
* @param packageName
* @param simpleName
* @param icon
*/
public void addProvider(int position, String packageName, String simpleName, Drawable icon,
int apiVersion) {
mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon,
apiVersion));
}
@Override
protected void onPrepareDialogBuilder(Builder builder) {
// Init ArrayAdapter with OpenPGP Providers
ListAdapter adapter = new ArrayAdapter<OpenPgpProviderEntry>(getContext(),
android.R.layout.select_dialog_singlechoice, android.R.id.text1, mProviderList) {
public View getView(int position, View convertView, ViewGroup parent) {
// User super class to create the View
View v = super.getView(position, convertView, parent);
TextView tv = (TextView) v.findViewById(android.R.id.text1);
// Put the image on the TextView
tv.setCompoundDrawablesWithIntrinsicBounds(mProviderList.get(position).icon, null,
null, null);
// Add margin between image and text (support various screen densities)
int dp10 = (int) (10 * getContext().getResources().getDisplayMetrics().density + 0.5f);
tv.setCompoundDrawablePadding(dp10);
// disable if it has the wrong api_version
if (mProviderList.get(position).apiVersion == OpenPgpConstants.REQUIRED_API_VERSION) {
tv.setEnabled(true);
} else {
tv.setEnabled(false);
tv.setText(tv.getText() + " (API v" + mProviderList.get(position).apiVersion
+ ", needs v" + OpenPgpConstants.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;
/*
* Clicking on an item simulates the positive button click, and dismisses
* the dialog.
*/
OpenPgpListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
});
/*
* The typical interaction for list-based dialogs is to have click-on-an-item dismiss the
* dialog instead of the user having to press 'Ok'.
*/
builder.setPositiveButton(null, null);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult && (mSelectedPackage != null)) {
if (callChangeListener(mSelectedPackage)) {
setValue(mSelectedPackage);
}
}
}
private int getIndexOfProviderList(String packageName) {
for (OpenPgpProviderEntry app : mProviderList) {
if (app.packageName.equals(packageName)) {
return mProviderList.indexOf(app);
}
}
return -1;
}
public void setValue(String packageName) {
mSelectedPackage = packageName;
persistString(packageName);
}
public String getValue() {
return mSelectedPackage;
}
public String getEntry() {
return getEntryByValue(mSelectedPackage);
}
public String getEntryByValue(String packageName) {
for (OpenPgpProviderEntry app : mProviderList) {
if (app.packageName.equals(packageName)) {
return app.simpleName;
}
}
return null;
}
private static class OpenPgpProviderEntry {
private String packageName;
private String simpleName;
private Drawable icon;
private int apiVersion;
public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon,
int apiVersion) {
this.packageName = packageName;
this.simpleName = simpleName;
this.icon = icon;
this.apiVersion = apiVersion;
}
@Override
public String toString() {
return simpleName;
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.IOpenPgpService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
public class OpenPgpServiceConnection {
private Context mApplicationContext;
private IOpenPgpService mService;
private boolean mBound;
private String mCryptoProviderPackageName;
public OpenPgpServiceConnection(Context context, String cryptoProviderPackageName) {
this.mApplicationContext = context.getApplicationContext();
this.mCryptoProviderPackageName = cryptoProviderPackageName;
}
public IOpenPgpService getService() {
return mService;
}
public boolean isBound() {
return mBound;
}
private ServiceConnection mCryptoServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IOpenPgpService.Stub.asInterface(service);
Log.d(OpenPgpConstants.TAG, "connected to service");
mBound = true;
}
public void onServiceDisconnected(ComponentName name) {
mService = null;
Log.d(OpenPgpConstants.TAG, "disconnected from service");
mBound = false;
}
};
/**
* If not already bound, bind!
*
* @return
*/
public boolean bindToService() {
if (mService == null && !mBound) { // if not already connected
try {
Log.d(OpenPgpConstants.TAG, "not bound yet");
Intent serviceIntent = new Intent();
serviceIntent.setAction(IOpenPgpService.class.getName());
serviceIntent.setPackage(mCryptoProviderPackageName);
mApplicationContext.bindService(serviceIntent, mCryptoServiceConnection,
Context.BIND_AUTO_CREATE);
return true;
} catch (Exception e) {
Log.d(OpenPgpConstants.TAG, "Exception on binding", e);
return false;
}
} else {
Log.d(OpenPgpConstants.TAG, "already bound");
return true;
}
}
public void unbindFromService() {
mApplicationContext.unbindService(mCryptoServiceConnection);
}
}

View File

@@ -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 OpenPgpSignatureResult so AIDL can find it and knows that it implements the parcelable protocol.
parcelable OpenPgpSignatureResult;

View File

@@ -0,0 +1,110 @@
/*
* 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.os.Parcel;
import android.os.Parcelable;
public class OpenPgpSignatureResult implements Parcelable {
// generic error on signature verification
public static final int SIGNATURE_ERROR = 0;
// successfully verified signature, with trusted public key
public static final int SIGNATURE_SUCCESS_TRUSTED = 1;
// 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 status;
boolean signatureOnly;
String userId;
long keyId;
public int getStatus() {
return status;
}
public boolean isSignatureOnly() {
return signatureOnly;
}
public String getUserId() {
return userId;
}
public long getKeyId() {
return keyId;
}
public OpenPgpSignatureResult() {
}
public OpenPgpSignatureResult(int signatureStatus, String signatureUserId,
boolean signatureOnly, long keyId) {
this.status = signatureStatus;
this.signatureOnly = signatureOnly;
this.userId = signatureUserId;
this.keyId = keyId;
}
public OpenPgpSignatureResult(OpenPgpSignatureResult b) {
this.status = b.status;
this.userId = b.userId;
this.signatureOnly = b.signatureOnly;
this.keyId = b.keyId;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(status);
dest.writeByte((byte) (signatureOnly ? 1 : 0));
dest.writeString(userId);
dest.writeLong(keyId);
}
public static final Creator<OpenPgpSignatureResult> CREATOR = new Creator<OpenPgpSignatureResult>() {
public OpenPgpSignatureResult createFromParcel(final Parcel source) {
OpenPgpSignatureResult vr = new OpenPgpSignatureResult();
vr.status = source.readInt();
vr.signatureOnly = source.readByte() == 1;
vr.userId = source.readString();
vr.keyId = source.readLong();
return vr;
}
public OpenPgpSignatureResult[] newArray(final int size) {
return new OpenPgpSignatureResult[size];
}
};
@Override
public String toString() {
String out = new String();
out += "\nstatus: " + status;
out += "\nuserId: " + userId;
out += "\nsignatureOnly: " + signatureOnly;
out += "\nkeyId: " + keyId;
return out;
}
}

View File

@@ -0,0 +1,168 @@
///*
// * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//package org.sufficientlysecure.keychain.demo;
//
//import java.util.ArrayList;
//import java.util.List;
//
//import org.sufficientlysecure.keychain.demo.R;
//import org.sufficientlysecure.keychain.integration.KeychainData;
//import org.sufficientlysecure.keychain.integration.KeychainIntentHelper;
//import org.sufficientlysecure.keychain.service.IKeychainKeyService;
//import org.sufficientlysecure.keychain.service.handler.IKeychainGetKeyringsHandler;
//
//import android.annotation.SuppressLint;
//import android.app.Activity;
//import android.app.AlertDialog;
//import android.content.ComponentName;
//import android.content.Context;
//import android.content.Intent;
//import android.content.ServiceConnection;
//import android.os.Bundle;
//import android.os.IBinder;
//import android.os.RemoteException;
//import android.util.Base64;
//import android.view.View;
//import android.widget.TextView;
//
//public class AidlDemoActivity2 extends Activity {
// Activity mActivity;
//
// TextView mKeyringsTextView;
//
// KeychainIntentHelper mKeychainIntentHelper;
// KeychainData mKeychainData;
//
// byte[] keysBytes;
// ArrayList<String> keysStrings;
//
// private IKeychainKeyService service = null;
// private ServiceConnection svcConn = new ServiceConnection() {
// public void onServiceConnected(ComponentName className, IBinder binder) {
// service = IKeychainKeyService.Stub.asInterface(binder);
// }
//
// public void onServiceDisconnected(ComponentName className) {
// service = null;
// }
// };
//
// @Override
// public void onCreate(Bundle icicle) {
// super.onCreate(icicle);
// setContentView(R.layout.aidl_demo2);
//
// mActivity = this;
//
// mKeyringsTextView = (TextView) findViewById(R.id.aidl_demo_keyrings);
//
// mKeychainIntentHelper = new KeychainIntentHelper(mActivity);
// mKeychainData = new KeychainData();
//
// bindService(new Intent(IKeychainKeyService.class.getName()), svcConn,
// Context.BIND_AUTO_CREATE);
// }
//
// public void getKeyringsStringsOnClick(View view) {
// try {
// service.getPublicKeyRings(mKeychainData.getPublicKeys(), true, getKeyringsHandler);
// } catch (RemoteException e) {
// exceptionImplementation(-1, e.toString());
// }
// }
//
// public void getKeyringsBytesOnClick(View view) {
// try {
// service.getPublicKeyRings(mKeychainData.getPublicKeys(), false, getKeyringsHandler);
// } catch (RemoteException e) {
// exceptionImplementation(-1, e.toString());
// }
// }
//
// @SuppressLint("NewApi")
// private void updateView() {
// if (keysBytes != null) {
// mKeyringsTextView.setText(Base64.encodeToString(keysBytes, Base64.DEFAULT));
// } else if (keysStrings != null) {
// mKeyringsTextView.setText("");
// for (String output : keysStrings) {
// mKeyringsTextView.append(output);
// }
// }
// }
//
// @Override
// public void onDestroy() {
// super.onDestroy();
//
// unbindService(svcConn);
// }
//
// private void exceptionImplementation(int exceptionId, String error) {
// AlertDialog.Builder builder = new AlertDialog.Builder(this);
// builder.setTitle("Exception!").setMessage(error).setPositiveButton("OK", null).show();
// }
//
// private final IKeychainGetKeyringsHandler.Stub getKeyringsHandler = new IKeychainGetKeyringsHandler.Stub() {
//
// @Override
// public void onException(final int exceptionId, final String message) throws RemoteException {
// runOnUiThread(new Runnable() {
// public void run() {
// exceptionImplementation(exceptionId, message);
// }
// });
// }
//
// @Override
// public void onSuccess(final byte[] outputBytes, final List<String> outputStrings)
// throws RemoteException {
// runOnUiThread(new Runnable() {
// public void run() {
// if (outputBytes != null) {
// keysBytes = outputBytes;
// keysStrings = null;
// } else if (outputStrings != null) {
// keysBytes = null;
// keysStrings = (ArrayList<String>) outputStrings;
// }
// updateView();
// }
// });
//
// }
//
// };
//
// public void selectEncryptionKeysOnClick(View view) {
// mKeychainIntentHelper.selectPublicKeys("user@example.com");
// }
//
// @Override
// protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// // this updates the mKeychainData object to the result of the methods
// boolean result = mKeychainIntentHelper.onActivityResult(requestCode, resultCode, data,
// mKeychainData);
// if (result) {
// updateView();
// }
//
// // continue with other activity results
// super.onActivityResult(requestCode, resultCode, data);
// }
//
//}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sufficientlysecure.keychain.demo;
import org.sufficientlysecure.keychain.demo.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.widget.Toast;
public class BaseActivity extends PreferenceActivity {
private Activity mActivity;
private Preference mIntentDemo;
private Preference mContentProviderDemo;
private Preference mCryptoProvider;
private Preference mAidlDemo;
private Preference mAidlDemo2;
/**
* Called when the activity is first created.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = this;
// load preferences from xml
addPreferencesFromResource(R.xml.base_preference);
// find preferences
mIntentDemo = (Preference) findPreference("intent_demo");
mContentProviderDemo = (Preference) findPreference("content_provider_demo");
mCryptoProvider = (Preference) findPreference("openpgp_provider_demo");
mAidlDemo = (Preference) findPreference("aidl_demo");
mAidlDemo2 = (Preference) findPreference("aidl_demo2");
mIntentDemo.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
// startActivity(new Intent(mActivity, IntentDemoActivity.class));
Toast.makeText(BaseActivity.this, "Not implemented!", Toast.LENGTH_LONG).show();
return false;
}
});
mCryptoProvider.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(mActivity, OpenPgpProviderActivity.class));
return false;
}
});
// mAidlDemo2.setOnPreferenceClickListener(new OnPreferenceClickListener() {
// @Override
// public boolean onPreferenceClick(Preference preference) {
// startActivity(new Intent(mActivity, AidlDemoActivity2.class));
//
// return false;
// }
// });
}
}

View File

@@ -0,0 +1,25 @@
/*
* 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.sufficientlysecure.keychain.demo;
public final class Constants {
public static final boolean DEBUG = BuildConfig.DEBUG;
public static final String TAG = "Keychain";
}

View File

@@ -0,0 +1,352 @@
/*
* 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.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;
import org.openintents.openpgp.IOpenPgpCallback;
import org.openintents.openpgp.IOpenPgpService;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class OpenPgpProviderActivity extends Activity {
Activity mActivity;
EditText mMessage;
EditText mCiphertext;
EditText mEncryptUserIds;
private OpenPgpServiceConnection mCryptoServiceConnection;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.crypto_provider_demo);
mActivity = this;
mMessage = (EditText) findViewById(R.id.crypto_provider_demo_message);
mCiphertext = (EditText) findViewById(R.id.crypto_provider_demo_ciphertext);
mEncryptUserIds = (EditText) findViewById(R.id.crypto_provider_demo_encrypt_user_id);
selectCryptoProvider();
}
/**
* 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 OpenPgpData output, OpenPgpSignatureResult signatureResult)
throws RemoteException {
Log.d(Constants.TAG, "encryptCallback");
runOnUiThread(new Runnable() {
@Override
public void run() {
mCiphertext.setText(output.getString());
}
});
}
@Override
public void onError(OpenPgpError error) throws RemoteException {
handleError(error);
}
};
final IOpenPgpCallback.Stub decryptAndVerifyCallback = new IOpenPgpCallback.Stub() {
@Override
public void onSuccess(final OpenPgpData output, final OpenPgpSignatureResult signatureResult)
throws RemoteException {
Log.d(Constants.TAG, "decryptAndVerifyCallback");
runOnUiThread(new Runnable() {
@Override
public void run() {
mMessage.setText(output.getString());
if (signatureResult != null) {
Toast.makeText(OpenPgpProviderActivity.this,
"signature result:\n" + signatureResult.toString(),
Toast.LENGTH_LONG).show();
}
}
});
}
@Override
public void onError(OpenPgpError error) throws RemoteException {
handleError(error);
}
};
private void handleError(final OpenPgpError error) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(mActivity,
"onError id:" + error.getErrorId() + "\n\n" + error.getMessage(),
Toast.LENGTH_LONG).show();
Log.e(Constants.TAG, "onError getErrorId:" + error.getErrorId());
Log.e(Constants.TAG, "onError getMessage:" + error.getMessage());
}
});
}
public void encryptOnClick(View view) {
try {
mCryptoServiceConnection.getService().getKeyIds(
mEncryptUserIds.getText().toString().split(","), true, getKeysEncryptCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
}
public void signOnClick(View view) {
String inputStr = mMessage.getText().toString();
OpenPgpData input = new OpenPgpData(inputStr);
try {
mCryptoServiceConnection.getService().sign(input,
new OpenPgpData(OpenPgpData.TYPE_STRING), encryptCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
}
public void signAndEncryptOnClick(View view) {
try {
mCryptoServiceConnection.getService().getKeyIds(
mEncryptUserIds.getText().toString().split(","), true,
getKeysSignAndEncryptCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
}
public void decryptAndVerifyOnClick(View view) {
String inputStr = mCiphertext.getText().toString();
OpenPgpData input = new OpenPgpData(inputStr);
try {
mCryptoServiceConnection.getService().decryptAndVerify(input,
new OpenPgpData(OpenPgpData.TYPE_STRING), decryptAndVerifyCallback);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoProviderDemo", e);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mCryptoServiceConnection != null) {
mCryptoServiceConnection.unbindFromService();
}
}
private static class OpenPgpProviderElement {
private String packageName;
private String simpleName;
private Drawable icon;
public OpenPgpProviderElement(String packageName, String simpleName, Drawable icon) {
this.packageName = packageName;
this.simpleName = simpleName;
this.icon = icon;
}
@Override
public String toString() {
return simpleName;
}
}
private void selectCryptoProvider() {
Intent intent = new Intent(IOpenPgpService.class.getName());
final ArrayList<OpenPgpProviderElement> providerList = new ArrayList<OpenPgpProviderElement>();
List<ResolveInfo> resInfo = getPackageManager().queryIntentServices(intent, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
if (resolveInfo.serviceInfo == null)
continue;
String packageName = resolveInfo.serviceInfo.packageName;
String simpleName = String.valueOf(resolveInfo.serviceInfo
.loadLabel(getPackageManager()));
Drawable icon = resolveInfo.serviceInfo.loadIcon(getPackageManager());
providerList.add(new OpenPgpProviderElement(packageName, simpleName, icon));
}
}
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Select OpenPGP Provider!");
alert.setCancelable(false);
if (!providerList.isEmpty()) {
// add "disable OpenPGP provider"
providerList.add(0, new OpenPgpProviderElement(null, "Disable OpenPGP Provider",
getResources().getDrawable(android.R.drawable.ic_menu_close_clear_cancel)));
// Init ArrayAdapter with OpenPGP Providers
ListAdapter adapter = new ArrayAdapter<OpenPgpProviderElement>(this,
android.R.layout.select_dialog_item, android.R.id.text1, providerList) {
public View getView(int position, View convertView, ViewGroup parent) {
// User super class to create the View
View v = super.getView(position, convertView, parent);
TextView tv = (TextView) v.findViewById(android.R.id.text1);
// Put the image on the TextView
tv.setCompoundDrawablesWithIntrinsicBounds(providerList.get(position).icon,
null, null, null);
// Add margin between image and text (support various screen densities)
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
tv.setCompoundDrawablePadding(dp5);
return v;
}
};
alert.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int position) {
String packageName = providerList.get(position).packageName;
if (packageName == null) {
dialog.cancel();
finish();
}
// bind to service
mCryptoServiceConnection = new OpenPgpServiceConnection(
OpenPgpProviderActivity.this, packageName);
mCryptoServiceConnection.bindToService();
dialog.dismiss();
}
});
} else {
alert.setMessage("No OpenPGP Provider installed!");
}
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
finish();
}
});
AlertDialog ad = alert.create();
ad.show();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="@+id/aidl_demo_select_encryption_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="selectEncryptionKeysOnClick"
android:text="Select encryption key(s)" />
<EditText
android:id="@+id/aidl_demo_keyrings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="keyrings output"
android:textAppearance="@android:style/TextAppearance.Small" />
<Button
android:id="@+id/aidl_demo_get_keyrings_strings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="getKeyringsStringsOnClick"
android:text="getKeyrings as Strings" />
<Button
android:id="@+id/aidl_demo_get_keyrings_bytes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="getKeyringsBytesOnClick"
android:text="getKeyringsBytes" />
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Encrypt UserIds (split with &apos;,&apos;)"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/crypto_provider_demo_encrypt_user_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="dominik@dominikschuermann.de"
android:textAppearance="@android:style/TextAppearance.Small" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Message"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/crypto_provider_demo_message"
android:layout_width="match_parent"
android:layout_height="100dip"
android:scrollHorizontally="true"
android:scrollbars="vertical"
android:text="message"
android:textAppearance="@android:style/TextAppearance.Small" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ciphertext"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/crypto_provider_demo_ciphertext"
android:layout_width="match_parent"
android:layout_height="100dip"
android:text="ciphertext"
android:textAppearance="@android:style/TextAppearance.Small" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="@+id/crypto_provider_demo_encrypt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="encryptOnClick"
android:text="Encrypt" />
<Button
android:id="@+id/crypto_provider_demo_sign"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="signOnClick"
android:text="Sign" />
<Button
android:id="@+id/crypto_provider_demo_encrypt_and_sign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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>

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/Button02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="encryptOnClick"
android:text="Encrypt" />
<Button
android:id="@+id/intent_demo_create_new_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="createNewKeyOnClick"
android:text="Create new key" />
<Button
android:id="@+id/intent_demo_select_secret_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="selectSecretKeyOnClick"
android:text="Select secret key" />
<Button
android:id="@+id/intent_demo_select_encryption_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="selectEncryptionKeysOnClick"
android:text="Select encryption key(s)" />
<EditText
android:id="@+id/intent_demo_message"
android:layout_width="match_parent"
android:layout_height="150dip"
android:text="message"
android:textAppearance="@android:style/TextAppearance.Small" />
<EditText
android:id="@+id/intent_demo_ciphertext"
android:layout_width="match_parent"
android:layout_height="150dip"
android:text="ciphertext"
android:textAppearance="@android:style/TextAppearance.Small" />
<Button
android:id="@+id/intent_demo_encrypt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="encryptOnClick"
android:text="Encrypt" />
<Button
android:id="@+id/intent_demo_encrypt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="encryptAndReturnOnClick"
android:text="Encrypt and return result" />
<Button
android:id="@+id/intent_demo_decrypt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="decryptOnClick"
android:text="Decrypt" />
<Button
android:id="@+id/intent_demo_decrypt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="decryptAndReturnOnClick"
android:text="Decrypt and return result" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="APG Data:" />
<TextView
android:id="@+id/intent_demo_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minLines="10" />
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Intent" >
<Preference
android:key="intent_demo"
android:title="Intent Demo" />
</PreferenceCategory>
<!-- <PreferenceCategory android:title="AIDL" > -->
<!-- <Preference -->
<!-- android:key="aidl_demo2" -->
<!-- android:title="AIDL Demo (ACCESS_KEYS permission)" /> -->
<!-- </PreferenceCategory> -->
<PreferenceCategory android:title="OpenPGP Provider" >
<org.openintents.openpgp.OpenPgpListPreference
android:key="openpgp_provider_list"
android:title="Select OpenPGP Provider!" />
<Preference
android:key="openpgp_provider_demo"
android:title="OpenPGP Provider" />
</PreferenceCategory>
</PreferenceScreen>