mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
Make asciiArmor a parameter, extend advanced app settings
This commit is contained in:
parent
c4bf7c5d11
commit
5dc693c64c
@ -78,7 +78,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:onClick="decryptOnClick"
|
android:onClick="decryptAndVerifyOnClick"
|
||||||
android:text="Decrypt" />
|
android:text="Decrypt" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ interface ICryptoService {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
|
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign
|
* Sign
|
||||||
@ -44,7 +44,7 @@ interface ICryptoService {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void sign(in byte[] inputBytes, in ICryptoCallback callback);
|
oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in ICryptoCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt and sign
|
* Encrypt and sign
|
||||||
@ -58,7 +58,7 @@ interface ICryptoService {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
|
oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypts and verifies given input bytes. If no signature is present this method
|
* Decrypts and verifies given input bytes. If no signature is present this method
|
||||||
@ -71,10 +71,4 @@ interface ICryptoService {
|
|||||||
*/
|
*/
|
||||||
oneway void decryptAndVerify(in byte[] inputBytes, in ICryptoCallback callback);
|
oneway void decryptAndVerify(in byte[] inputBytes, in ICryptoCallback callback);
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens setup using default parameters
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
oneway void setup(boolean asciiArmor, boolean newKeyring, String newKeyringUserId);
|
|
||||||
|
|
||||||
}
|
}
|
@ -74,7 +74,7 @@ public class CryptoProviderDemoActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(final byte[] outputBytes, CryptoSignatureResult signatureResult)
|
public void onSuccess(final byte[] outputBytes, CryptoSignatureResult signatureResult)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
Log.d(Constants.TAG, "onEncryptSignSuccess");
|
Log.d(Constants.TAG, "encryptCallback");
|
||||||
|
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
@ -92,12 +92,12 @@ public class CryptoProviderDemoActivity extends Activity {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
final ICryptoCallback.Stub decryptCallback = new ICryptoCallback.Stub() {
|
final ICryptoCallback.Stub decryptAndVerifyCallback = new ICryptoCallback.Stub() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(final byte[] outputBytes, final CryptoSignatureResult signatureResult)
|
public void onSuccess(final byte[] outputBytes, final CryptoSignatureResult signatureResult)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
Log.d(Constants.TAG, "onDecryptVerifySuccess");
|
Log.d(Constants.TAG, "decryptAndVerifyCallback");
|
||||||
|
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ public class CryptoProviderDemoActivity extends Activity {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().encrypt(inputBytes,
|
mCryptoServiceConnection.getService().encrypt(inputBytes,
|
||||||
mEncryptUserIds.getText().toString().split(","), encryptCallback);
|
mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ public class CryptoProviderDemoActivity extends Activity {
|
|||||||
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
byte[] inputBytes = mMessage.getText().toString().getBytes();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().sign(inputBytes, encryptCallback);
|
mCryptoServiceConnection.getService().sign(inputBytes, true, encryptCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
@ -157,17 +157,18 @@ public class CryptoProviderDemoActivity extends Activity {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().encryptAndSign(inputBytes,
|
mCryptoServiceConnection.getService().encryptAndSign(inputBytes,
|
||||||
mEncryptUserIds.getText().toString().split(","), encryptCallback);
|
mEncryptUserIds.getText().toString().split(","), true, encryptCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void decryptOnClick(View view) {
|
public void decryptAndVerifyOnClick(View view) {
|
||||||
byte[] inputBytes = mCiphertext.getText().toString().getBytes();
|
byte[] inputBytes = mCiphertext.getText().toString().getBytes();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCryptoServiceConnection.getService().decryptAndVerify(inputBytes, decryptCallback);
|
mCryptoServiceConnection.getService().decryptAndVerify(inputBytes,
|
||||||
|
decryptAndVerifyCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
Log.e(Constants.TAG, "CryptoProviderDemo", e);
|
||||||
}
|
}
|
||||||
|
@ -82,15 +82,41 @@
|
|||||||
android:id="@+id/api_app_settings_advanced"
|
android:id="@+id/api_app_settings_advanced"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="vertical"
|
||||||
android:visibility="invisible" >
|
android:visibility="invisible" >
|
||||||
|
|
||||||
<CheckBox
|
<TextView
|
||||||
android:id="@+id/api_app_ascii_armor"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:text="@string/label_encryptionAlgorithm"
|
||||||
android:text="@string/label_asciiArmour" />
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/api_app_settings_encryption_algorithm"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/label_hashAlgorithm"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/api_app_settings_hash_algorithm"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/label_messageCompression"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/api_app_settings_compression"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -34,7 +34,7 @@ interface ICryptoService {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
|
oneway void encrypt(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign
|
* Sign
|
||||||
@ -44,7 +44,7 @@ interface ICryptoService {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void sign(in byte[] inputBytes, in ICryptoCallback callback);
|
oneway void sign(in byte[] inputBytes, in boolean asciiArmor, in ICryptoCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt and sign
|
* Encrypt and sign
|
||||||
@ -58,7 +58,7 @@ interface ICryptoService {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* Callback where to return results
|
* Callback where to return results
|
||||||
*/
|
*/
|
||||||
oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in ICryptoCallback callback);
|
oneway void encryptAndSign(in byte[] inputBytes, in String[] encryptionUserIds, in boolean asciiArmor, in ICryptoCallback callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypts and verifies given input bytes. If no signature is present this method
|
* Decrypts and verifies given input bytes. If no signature is present this method
|
||||||
|
@ -21,6 +21,7 @@ import java.io.File;
|
|||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
|
|
||||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.PRNGFixes;
|
import org.sufficientlysecure.keychain.util.PRNGFixes;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
@ -30,15 +31,16 @@ public class KeychainApplication extends Application {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
// Define Java Security Provider to be Bouncy Castle
|
// Define Java Security Provider to be Bouncy Castle
|
||||||
Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
// apply RNG fixes
|
// apply RNG fixes
|
||||||
PRNGFixes.apply();
|
PRNGFixes.apply();
|
||||||
|
Log.d(Constants.TAG, "PRNG Fixes applied!");
|
||||||
|
|
||||||
// Create APG directory on sdcard if not existing
|
// Create APG directory on sdcard if not existing
|
||||||
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
|
@ -17,6 +17,30 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.helper;
|
package org.sufficientlysecure.keychain.helper;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.security.SignatureException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||||
@ -45,7 +69,6 @@ import org.spongycastle.openpgp.PGPPrivateKey;
|
|||||||
import org.spongycastle.openpgp.PGPPublicKey;
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRingCollection;
|
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPSignature;
|
import org.spongycastle.openpgp.PGPSignature;
|
||||||
@ -75,17 +98,17 @@ import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactory
|
|||||||
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
|
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.Id;
|
import org.sufficientlysecure.keychain.Id;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.util.HkpKeyServer;
|
import org.sufficientlysecure.keychain.util.HkpKeyServer;
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
|
import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
|
import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
|
||||||
import org.sufficientlysecure.keychain.util.Primes;
|
import org.sufficientlysecure.keychain.util.Primes;
|
||||||
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
|
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
|
||||||
import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
|
|
||||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
@ -93,31 +116,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.RandomAccessFile;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
|
||||||
import java.security.KeyPairGenerator;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.security.Security;
|
|
||||||
import java.security.SignatureException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO:
|
* TODO:
|
||||||
*
|
*
|
||||||
|
@ -56,7 +56,6 @@ public class KeychainContract {
|
|||||||
interface ApiAppsColumns {
|
interface ApiAppsColumns {
|
||||||
String PACKAGE_NAME = "package_name";
|
String PACKAGE_NAME = "package_name";
|
||||||
String KEY_ID = "key_id"; // not a database id
|
String KEY_ID = "key_id"; // not a database id
|
||||||
String ASCII_ARMOR = "ascii_armor";
|
|
||||||
String ENCRYPTION_ALGORITHM = "encryption_algorithm";
|
String ENCRYPTION_ALGORITHM = "encryption_algorithm";
|
||||||
String HASH_ALORITHM = "hash_algorithm";
|
String HASH_ALORITHM = "hash_algorithm";
|
||||||
String COMPRESSION = "compression";
|
String COMPRESSION = "compression";
|
||||||
|
@ -64,14 +64,11 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
|||||||
+ UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
|
+ UserIdsColumns.KEY_RING_ROW_ID + ") REFERENCES " + Tables.KEY_RINGS + "("
|
||||||
+ BaseColumns._ID + ") ON DELETE CASCADE)";
|
+ BaseColumns._ID + ") ON DELETE CASCADE)";
|
||||||
|
|
||||||
private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS "
|
private static final String CREATE_API_APPS = "CREATE TABLE IF NOT EXISTS " + Tables.API_APPS
|
||||||
+ Tables.API_APPS + " (" + BaseColumns._ID
|
+ " (" + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + ApiAppsColumns.PACKAGE_NAME
|
+ ApiAppsColumns.PACKAGE_NAME + " TEXT UNIQUE, " + ApiAppsColumns.KEY_ID + " INT64, "
|
||||||
+ " TEXT UNIQUE, " + ApiAppsColumns.KEY_ID + " INT64, "
|
+ ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, " + ApiAppsColumns.HASH_ALORITHM
|
||||||
+ ApiAppsColumns.ASCII_ARMOR + " INTEGER, "
|
+ " INTEGER, " + ApiAppsColumns.COMPRESSION + " INTEGER)";
|
||||||
+ ApiAppsColumns.ENCRYPTION_ALGORITHM + " INTEGER, "
|
|
||||||
+ ApiAppsColumns.HASH_ALORITHM + " INTEGER, "
|
|
||||||
+ ApiAppsColumns.COMPRESSION + " INTEGER)";
|
|
||||||
|
|
||||||
KeychainDatabase(Context context) {
|
KeychainDatabase(Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
@ -745,7 +745,6 @@ public class ProviderHelper {
|
|||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName());
|
values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName());
|
||||||
values.put(ApiApps.KEY_ID, appSettings.getKeyId());
|
values.put(ApiApps.KEY_ID, appSettings.getKeyId());
|
||||||
values.put(ApiApps.ASCII_ARMOR, appSettings.isAsciiArmor());
|
|
||||||
values.put(ApiApps.COMPRESSION, appSettings.getCompression());
|
values.put(ApiApps.COMPRESSION, appSettings.getCompression());
|
||||||
values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm());
|
values.put(ApiApps.ENCRYPTION_ALGORITHM, appSettings.getEncryptionAlgorithm());
|
||||||
values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm());
|
values.put(ApiApps.HASH_ALORITHM, appSettings.getHashAlgorithm());
|
||||||
@ -775,8 +774,6 @@ public class ProviderHelper {
|
|||||||
settings.setPackageName(cur.getString(cur
|
settings.setPackageName(cur.getString(cur
|
||||||
.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME)));
|
.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME)));
|
||||||
settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.ApiApps.KEY_ID)));
|
settings.setKeyId(cur.getLong(cur.getColumnIndex(KeychainContract.ApiApps.KEY_ID)));
|
||||||
settings.setAsciiArmor(cur.getInt(cur
|
|
||||||
.getColumnIndexOrThrow(KeychainContract.ApiApps.ASCII_ARMOR)) == 1);
|
|
||||||
settings.setCompression(cur.getInt(cur
|
settings.setCompression(cur.getInt(cur
|
||||||
.getColumnIndexOrThrow(KeychainContract.ApiApps.COMPRESSION)));
|
.getColumnIndexOrThrow(KeychainContract.ApiApps.COMPRESSION)));
|
||||||
settings.setHashAlgorithm(cur.getInt(cur
|
settings.setHashAlgorithm(cur.getInt(cur
|
||||||
|
@ -24,7 +24,6 @@ import org.sufficientlysecure.keychain.Id;
|
|||||||
public class AppSettings {
|
public class AppSettings {
|
||||||
private String packageName;
|
private String packageName;
|
||||||
private long keyId = Id.key.none;
|
private long keyId = Id.key.none;
|
||||||
private boolean asciiArmor;
|
|
||||||
private int encryptionAlgorithm;
|
private int encryptionAlgorithm;
|
||||||
private int hashAlgorithm;
|
private int hashAlgorithm;
|
||||||
private int compression;
|
private int compression;
|
||||||
@ -37,10 +36,9 @@ public class AppSettings {
|
|||||||
super();
|
super();
|
||||||
this.packageName = packageName;
|
this.packageName = packageName;
|
||||||
// defaults:
|
// defaults:
|
||||||
this.asciiArmor = true;
|
this.encryptionAlgorithm = PGPEncryptedData.AES_128;
|
||||||
this.encryptionAlgorithm = PGPEncryptedData.AES_128; // AES-128
|
this.hashAlgorithm = HashAlgorithmTags.SHA256;
|
||||||
this.hashAlgorithm = HashAlgorithmTags.SHA512; // SHA-512
|
this.compression = Id.choice.compression.zlib;
|
||||||
this.compression = Id.choice.compression.zlib; // zlib
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPackageName() {
|
public String getPackageName() {
|
||||||
@ -59,14 +57,6 @@ public class AppSettings {
|
|||||||
this.keyId = scretKeyId;
|
this.keyId = scretKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAsciiArmor() {
|
|
||||||
return asciiArmor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAsciiArmor(boolean asciiArmor) {
|
|
||||||
this.asciiArmor = asciiArmor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEncryptionAlgorithm() {
|
public int getEncryptionAlgorithm() {
|
||||||
return encryptionAlgorithm;
|
return encryptionAlgorithm;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.remote_api;
|
package org.sufficientlysecure.keychain.remote_api;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||||
|
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
@ -25,6 +29,7 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.helper.PgpHelper;
|
import org.sufficientlysecure.keychain.helper.PgpHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.ui.SelectSecretKeyActivity;
|
import org.sufficientlysecure.keychain.ui.SelectSecretKeyActivity;
|
||||||
|
import org.sufficientlysecure.keychain.util.KeyValueSpinnerAdapter;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@ -41,12 +46,12 @@ import android.view.View.OnClickListener;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.AlphaAnimation;
|
import android.view.animation.AlphaAnimation;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
public class AppSettingsFragment extends Fragment {
|
public class AppSettingsFragment extends Fragment {
|
||||||
@ -62,7 +67,13 @@ public class AppSettingsFragment extends Fragment {
|
|||||||
private TextView mKeyUserId;
|
private TextView mKeyUserId;
|
||||||
private TextView mKeyUserIdRest;
|
private TextView mKeyUserIdRest;
|
||||||
private Button mSelectKeyButton;
|
private Button mSelectKeyButton;
|
||||||
private CheckBox mAsciiArmorCheckBox;
|
private Spinner mEncryptionAlgorithm;
|
||||||
|
private Spinner mHashAlgorithm;
|
||||||
|
private Spinner mCompression;
|
||||||
|
|
||||||
|
KeyValueSpinnerAdapter encryptionAdapter;
|
||||||
|
KeyValueSpinnerAdapter hashAdapter;
|
||||||
|
KeyValueSpinnerAdapter compressionAdapter;
|
||||||
|
|
||||||
public AppSettings getAppSettings() {
|
public AppSettings getAppSettings() {
|
||||||
return appSettings;
|
return appSettings;
|
||||||
@ -72,7 +83,10 @@ public class AppSettingsFragment extends Fragment {
|
|||||||
this.appSettings = appSettings;
|
this.appSettings = appSettings;
|
||||||
setPackage(appSettings.getPackageName());
|
setPackage(appSettings.getPackageName());
|
||||||
updateSelectedKeyView(appSettings.getKeyId());
|
updateSelectedKeyView(appSettings.getKeyId());
|
||||||
mAsciiArmorCheckBox.setChecked(appSettings.isAsciiArmor());
|
mEncryptionAlgorithm.setSelection(encryptionAdapter.getPosition(appSettings
|
||||||
|
.getEncryptionAlgorithm()));
|
||||||
|
mHashAlgorithm.setSelection(hashAdapter.getPosition(appSettings.getHashAlgorithm()));
|
||||||
|
mCompression.setSelection(compressionAdapter.getPosition(appSettings.getCompression()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +109,80 @@ public class AppSettingsFragment extends Fragment {
|
|||||||
mKeyUserId = (TextView) view.findViewById(R.id.api_app_settings_user_id);
|
mKeyUserId = (TextView) view.findViewById(R.id.api_app_settings_user_id);
|
||||||
mKeyUserIdRest = (TextView) view.findViewById(R.id.api_app_settings_user_id_rest);
|
mKeyUserIdRest = (TextView) view.findViewById(R.id.api_app_settings_user_id_rest);
|
||||||
mSelectKeyButton = (Button) view.findViewById(R.id.api_app_settings_select_key_button);
|
mSelectKeyButton = (Button) view.findViewById(R.id.api_app_settings_select_key_button);
|
||||||
mAsciiArmorCheckBox = (CheckBox) view.findViewById(R.id.api_app_ascii_armor);
|
mEncryptionAlgorithm = (Spinner) view
|
||||||
|
.findViewById(R.id.api_app_settings_encryption_algorithm);
|
||||||
|
mHashAlgorithm = (Spinner) view.findViewById(R.id.api_app_settings_hash_algorithm);
|
||||||
|
mCompression = (Spinner) view.findViewById(R.id.api_app_settings_compression);
|
||||||
|
|
||||||
|
HashMap<Integer, String> encryptionMap = new HashMap<Integer, String>();
|
||||||
|
encryptionMap.put(PGPEncryptedData.AES_128, "AES-128");
|
||||||
|
encryptionMap.put(PGPEncryptedData.AES_192, "AES-192");
|
||||||
|
encryptionMap.put(PGPEncryptedData.AES_256, "AES-256");
|
||||||
|
encryptionMap.put(PGPEncryptedData.BLOWFISH, "Blowfish");
|
||||||
|
encryptionMap.put(PGPEncryptedData.TWOFISH, "Twofish");
|
||||||
|
encryptionMap.put(PGPEncryptedData.CAST5, "CAST5");
|
||||||
|
encryptionMap.put(PGPEncryptedData.DES, "DES");
|
||||||
|
encryptionMap.put(PGPEncryptedData.TRIPLE_DES, "Triple DES");
|
||||||
|
encryptionMap.put(PGPEncryptedData.IDEA, "IDEA");
|
||||||
|
|
||||||
|
encryptionAdapter = new KeyValueSpinnerAdapter(getActivity(), encryptionMap);
|
||||||
|
mEncryptionAlgorithm.setAdapter(encryptionAdapter);
|
||||||
|
mEncryptionAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
appSettings.setEncryptionAlgorithm((int) id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
|
||||||
|
hashMap.put(HashAlgorithmTags.MD5, "MD5");
|
||||||
|
hashMap.put(HashAlgorithmTags.RIPEMD160, "RIPEMD-160");
|
||||||
|
hashMap.put(HashAlgorithmTags.SHA1, "SHA-1");
|
||||||
|
hashMap.put(HashAlgorithmTags.SHA224, "SHA-224");
|
||||||
|
hashMap.put(HashAlgorithmTags.SHA256, "SHA-256");
|
||||||
|
hashMap.put(HashAlgorithmTags.SHA384, "SHA-384");
|
||||||
|
hashMap.put(HashAlgorithmTags.SHA512, "SHA-512");
|
||||||
|
|
||||||
|
hashAdapter = new KeyValueSpinnerAdapter(getActivity(), hashMap);
|
||||||
|
mHashAlgorithm.setAdapter(hashAdapter);
|
||||||
|
mHashAlgorithm.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
appSettings.setHashAlgorithm((int) id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
HashMap<Integer, String> compressionMap = new HashMap<Integer, String>();
|
||||||
|
compressionMap.put(Id.choice.compression.none, getString(R.string.choice_none) + " ("
|
||||||
|
+ getString(R.string.fast) + ")");
|
||||||
|
compressionMap.put(Id.choice.compression.zip, "ZIP (" + getString(R.string.fast) + ")");
|
||||||
|
compressionMap.put(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.fast) + ")");
|
||||||
|
compressionMap.put(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow)
|
||||||
|
+ ")");
|
||||||
|
|
||||||
|
compressionAdapter = new KeyValueSpinnerAdapter(getActivity(), compressionMap);
|
||||||
|
mCompression.setAdapter(compressionAdapter);
|
||||||
|
mCompression.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
appSettings.setCompression((int) id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mSelectKeyButton.setOnClickListener(new OnClickListener() {
|
mSelectKeyButton.setOnClickListener(new OnClickListener() {
|
||||||
|
|
||||||
@ -105,14 +192,6 @@ public class AppSettingsFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mAsciiArmorCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
||||||
appSettings.setAsciiArmor(isChecked);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final Animation visibleAnimation = new AlphaAnimation(0.0f, 1.0f);
|
final Animation visibleAnimation = new AlphaAnimation(0.0f, 1.0f);
|
||||||
visibleAnimation.setDuration(250);
|
visibleAnimation.setDuration(250);
|
||||||
final Animation invisibleAnimation = new AlphaAnimation(1.0f, 0.0f);
|
final Animation invisibleAnimation = new AlphaAnimation(1.0f, 0.0f);
|
||||||
|
@ -24,6 +24,7 @@ import java.io.OutputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
import org.openintents.crypto.CryptoError;
|
import org.openintents.crypto.CryptoError;
|
||||||
import org.openintents.crypto.CryptoSignatureResult;
|
import org.openintents.crypto.CryptoSignatureResult;
|
||||||
@ -233,7 +234,8 @@ public class CryptoService extends Service {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private synchronized void encryptAndSignSafe(byte[] inputBytes, String[] encryptionUserIds,
|
private synchronized void encryptAndSignSafe(byte[] inputBytes, String[] encryptionUserIds,
|
||||||
ICryptoCallback callback, AppSettings appSettings, boolean sign) throws RemoteException {
|
boolean asciiArmor, ICryptoCallback callback, AppSettings appSettings, boolean sign)
|
||||||
|
throws RemoteException {
|
||||||
try {
|
try {
|
||||||
// build InputData and write into OutputStream
|
// build InputData and write into OutputStream
|
||||||
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
||||||
@ -252,13 +254,13 @@ public class CryptoService extends Service {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PgpMain.encryptAndSign(mContext, null, inputData, outputStream,
|
PgpMain.encryptAndSign(mContext, null, inputData, outputStream, asciiArmor,
|
||||||
appSettings.isAsciiArmor(), appSettings.getCompression(), keyIds, null,
|
appSettings.getCompression(), keyIds, null,
|
||||||
appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
|
appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(),
|
||||||
appSettings.getHashAlgorithm(), true, passphrase);
|
appSettings.getHashAlgorithm(), true, passphrase);
|
||||||
} else {
|
} else {
|
||||||
PgpMain.encryptAndSign(mContext, null, inputData, outputStream,
|
PgpMain.encryptAndSign(mContext, null, inputData, outputStream, asciiArmor,
|
||||||
appSettings.isAsciiArmor(), appSettings.getCompression(), keyIds, null,
|
appSettings.getCompression(), keyIds, null,
|
||||||
appSettings.getEncryptionAlgorithm(), Id.key.none,
|
appSettings.getEncryptionAlgorithm(), Id.key.none,
|
||||||
appSettings.getHashAlgorithm(), true, null);
|
appSettings.getHashAlgorithm(), true, null);
|
||||||
}
|
}
|
||||||
@ -280,6 +282,7 @@ public class CryptoService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: asciiArmor?!
|
||||||
private void signSafe(byte[] inputBytes, ICryptoCallback callback, AppSettings appSettings)
|
private void signSafe(byte[] inputBytes, ICryptoCallback callback, AppSettings appSettings)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
try {
|
try {
|
||||||
@ -327,19 +330,50 @@ public class CryptoService extends Service {
|
|||||||
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
InputStream inputStream = new ByteArrayInputStream(inputBytes);
|
||||||
long inputLength = inputBytes.length;
|
long inputLength = inputBytes.length;
|
||||||
InputData inputData = new InputData(inputStream, inputLength);
|
InputData inputData = new InputData(inputStream, inputLength);
|
||||||
|
|
||||||
Log.d(Constants.TAG, "in: " + new String(inputBytes));
|
|
||||||
|
|
||||||
OutputStream outputStream = new ByteArrayOutputStream();
|
OutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
String message = new String(inputBytes);
|
||||||
|
Log.d(Constants.TAG, "in: " + message);
|
||||||
|
|
||||||
|
// checked if signed only
|
||||||
|
boolean signedOnly = false;
|
||||||
|
Matcher matcher = PgpMain.PGP_SIGNED_MESSAGE.matcher(message);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
signedOnly = true;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
|
// TODO: This allows to decrypt messages with ALL secret keys, not only the one for the
|
||||||
// app, Fix this?
|
// app, Fix this?
|
||||||
long secretKeyId = PgpMain.getDecryptionKeyId(mContext, inputStream);
|
// long secretKeyId = PgpMain.getDecryptionKeyId(mContext, inputStream);
|
||||||
if (secretKeyId == Id.key.none) {
|
// if (secretKeyId == Id.key.none) {
|
||||||
throw new PgpMain.PgpGeneralException(getString(R.string.error_noSecretKeyFound));
|
// throw new PgpMain.PgpGeneralException(getString(R.string.error_noSecretKeyFound));
|
||||||
}
|
// }
|
||||||
|
|
||||||
Log.d(Constants.TAG, "Got input:\n" + new String(inputBytes));
|
// TODO: duplicates functions from DecryptActivity!
|
||||||
|
boolean assumeSymmetricEncryption = false;
|
||||||
|
long secretKeyId;
|
||||||
|
try {
|
||||||
|
if (inputStream.markSupported()) {
|
||||||
|
inputStream.mark(200); // should probably set this to the max size of two pgpF
|
||||||
|
// objects, if it even needs to be anything other than 0.
|
||||||
|
}
|
||||||
|
secretKeyId = PgpMain.getDecryptionKeyId(this, inputStream);
|
||||||
|
if (secretKeyId == Id.key.none) {
|
||||||
|
throw new PgpMain.PgpGeneralException(
|
||||||
|
getString(R.string.error_noSecretKeyFound));
|
||||||
|
}
|
||||||
|
assumeSymmetricEncryption = false;
|
||||||
|
} catch (PgpMain.NoAsymmetricEncryptionException e) {
|
||||||
|
if (inputStream.markSupported()) {
|
||||||
|
inputStream.reset();
|
||||||
|
}
|
||||||
|
secretKeyId = Id.key.symmetric;
|
||||||
|
if (!PgpMain.hasSymmetricEncryption(this, inputStream)) {
|
||||||
|
throw new PgpMain.PgpGeneralException(
|
||||||
|
getString(R.string.error_noKnownEncryptionFound));
|
||||||
|
}
|
||||||
|
assumeSymmetricEncryption = true;
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
|
Log.d(Constants.TAG, "secretKeyId " + secretKeyId);
|
||||||
|
|
||||||
@ -350,17 +384,15 @@ public class CryptoService extends Service {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (signedOnly) {
|
Bundle outputBundle;
|
||||||
// resultData = PgpMain.verifyText(this, this, inputData, outStream,
|
if (signedOnly) {
|
||||||
// lookupUnknownKey);
|
// TODO: download missing keys from keyserver?
|
||||||
// } else {
|
outputBundle = PgpMain.verifyText(this, null, inputData, outputStream, false);
|
||||||
// resultData = PgpMain.decryptAndVerify(this, this, inputData, outStream,
|
} else {
|
||||||
// PassphraseCacheService.getCachedPassphrase(this, secretKeyId),
|
// TODO: assume symmetric: callback to enter symmetric pass
|
||||||
// assumeSymmetricEncryption);
|
outputBundle = PgpMain.decryptAndVerify(this, null, inputData, outputStream,
|
||||||
// }
|
passphrase, false);
|
||||||
|
}
|
||||||
Bundle outputBundle = PgpMain.decryptAndVerify(mContext, null, inputData, outputStream,
|
|
||||||
passphrase, false);
|
|
||||||
|
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
|
||||||
@ -377,8 +409,11 @@ public class CryptoService extends Service {
|
|||||||
boolean signatureUnknown = outputBundle
|
boolean signatureUnknown = outputBundle
|
||||||
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN);
|
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN);
|
||||||
|
|
||||||
CryptoSignatureResult sigResult = new CryptoSignatureResult(signatureUserId, signature,
|
CryptoSignatureResult sigResult = null;
|
||||||
signatureSuccess, signatureUnknown);
|
if (signature) {
|
||||||
|
sigResult = new CryptoSignatureResult(signatureUserId, signature, signatureSuccess,
|
||||||
|
signatureUnknown);
|
||||||
|
}
|
||||||
|
|
||||||
// return over handler on client side
|
// return over handler on client side
|
||||||
callback.onSuccess(outputBytes, sigResult);
|
callback.onSuccess(outputBytes, sigResult);
|
||||||
@ -397,7 +432,7 @@ public class CryptoService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds,
|
public void encrypt(final byte[] inputBytes, final String[] encryptionUserIds,
|
||||||
final ICryptoCallback callback) throws RemoteException {
|
final boolean asciiArmor, final ICryptoCallback callback) throws RemoteException {
|
||||||
|
|
||||||
final AppSettings settings = getAppSettings();
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
@ -406,7 +441,8 @@ public class CryptoService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
encryptAndSignSafe(inputBytes, encryptionUserIds, callback, settings, false);
|
encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, callback,
|
||||||
|
settings, false);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoService", e);
|
Log.e(Constants.TAG, "CryptoService", e);
|
||||||
}
|
}
|
||||||
@ -418,7 +454,7 @@ public class CryptoService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encryptAndSign(final byte[] inputBytes, final String[] encryptionUserIds,
|
public void encryptAndSign(final byte[] inputBytes, final String[] encryptionUserIds,
|
||||||
final ICryptoCallback callback) throws RemoteException {
|
final boolean asciiArmor, final ICryptoCallback callback) throws RemoteException {
|
||||||
|
|
||||||
final AppSettings settings = getAppSettings();
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
@ -427,7 +463,8 @@ public class CryptoService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
encryptAndSignSafe(inputBytes, encryptionUserIds, callback, settings, true);
|
encryptAndSignSafe(inputBytes, encryptionUserIds, asciiArmor, callback,
|
||||||
|
settings, true);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(Constants.TAG, "CryptoService", e);
|
Log.e(Constants.TAG, "CryptoService", e);
|
||||||
}
|
}
|
||||||
@ -438,7 +475,7 @@ public class CryptoService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sign(final byte[] inputBytes, final ICryptoCallback callback)
|
public void sign(final byte[] inputBytes, boolean asciiArmor, final ICryptoCallback callback)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
final AppSettings settings = getAppSettings();
|
final AppSettings settings = getAppSettings();
|
||||||
|
|
||||||
|
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
|
||||||
|
public class KeyValueSpinnerAdapter extends ArrayAdapter<String> {
|
||||||
|
private final HashMap<Integer, String> mData;
|
||||||
|
private final int[] mKeys;
|
||||||
|
private final String[] mValues;
|
||||||
|
|
||||||
|
static <K, V extends Comparable<? super V>> SortedSet<Map.Entry<K, V>> entriesSortedByValues(
|
||||||
|
Map<K, V> map) {
|
||||||
|
SortedSet<Map.Entry<K, V>> sortedEntries = new TreeSet<Map.Entry<K, V>>(
|
||||||
|
new Comparator<Map.Entry<K, V>>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
|
||||||
|
return e1.getValue().compareTo(e2.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sortedEntries.addAll(map.entrySet());
|
||||||
|
return sortedEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyValueSpinnerAdapter(Context context, HashMap<Integer, String> objects) {
|
||||||
|
// To make the drop down a simple text box
|
||||||
|
super(context, android.R.layout.simple_spinner_item);
|
||||||
|
mData = objects;
|
||||||
|
|
||||||
|
// To make the drop down view a radio button list
|
||||||
|
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
|
||||||
|
SortedSet<Map.Entry<Integer, String>> sorted = entriesSortedByValues(objects);
|
||||||
|
|
||||||
|
// Assign hash keys with a position so that we can present and retrieve them
|
||||||
|
int i = 0;
|
||||||
|
mKeys = new int[mData.size()];
|
||||||
|
mValues = new String[mData.size()];
|
||||||
|
for (Map.Entry<Integer, String> entry : sorted) {
|
||||||
|
mKeys[i] = entry.getKey();
|
||||||
|
mValues[i] = entry.getValue();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return mData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getItem(int position) {
|
||||||
|
// return the value based on the position. This is displayed in the list.
|
||||||
|
return mValues[position];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns item key
|
||||||
|
*/
|
||||||
|
public long getItemId(int position) {
|
||||||
|
// Return an id to represent the item.
|
||||||
|
|
||||||
|
return mKeys[position];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find position from key
|
||||||
|
*/
|
||||||
|
public int getPosition(long itemId) {
|
||||||
|
for (int i = 0; i < mKeys.length; i++) {
|
||||||
|
if ((int) itemId == mKeys[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user