Merge pull request #413 from uberspot/master

More code style fixes
This commit is contained in:
Dominik Schürmann
2014-03-13 21:49:58 +01:00
65 changed files with 993 additions and 980 deletions

View File

@@ -16,10 +16,10 @@
package org.sufficientlysecure.keychain; package org.sufficientlysecure.keychain;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import android.os.Environment; import android.os.Environment;
import org.spongycastle.jce.provider.BouncyCastleProvider;
public final class Constants { public final class Constants {
public static final boolean DEBUG = BuildConfig.DEBUG; public static final boolean DEBUG = BuildConfig.DEBUG;
@@ -40,14 +40,14 @@ public final class Constants {
public static final String INTENT_PREFIX = PACKAGE_NAME + ".action."; public static final String INTENT_PREFIX = PACKAGE_NAME + ".action.";
public static final class path { public static final class Path {
public static final String APP_DIR = Environment.getExternalStorageDirectory() public static final String APP_DIR = Environment.getExternalStorageDirectory()
+ "/OpenPGP-Keychain"; + "/OpenPGP-Keychain";
public static final String APP_DIR_FILE_SEC = APP_DIR + "/secexport.asc"; public static final String APP_DIR_FILE_SEC = APP_DIR + "/secexport.asc";
public static final String APP_DIR_FILE_PUB = APP_DIR + "/pubexport.asc"; public static final String APP_DIR_FILE_PUB = APP_DIR + "/pubexport.asc";
} }
public static final class pref { public static final class Pref {
public static final String DEFAULT_ENCRYPTION_ALGORITHM = "defaultEncryptionAlgorithm"; public static final String DEFAULT_ENCRYPTION_ALGORITHM = "defaultEncryptionAlgorithm";
public static final String DEFAULT_HASH_ALGORITHM = "defaultHashAlgorithm"; public static final String DEFAULT_HASH_ALGORITHM = "defaultHashAlgorithm";
public static final String DEFAULT_ASCII_ARMOUR = "defaultAsciiArmour"; public static final String DEFAULT_ASCII_ARMOUR = "defaultAsciiArmour";
@@ -59,7 +59,7 @@ public final class Constants {
public static final String KEY_SERVERS = "keyServers"; public static final String KEY_SERVERS = "keyServers";
} }
public static final class defaults { public static final class Defaults {
public static final String KEY_SERVERS = "pool.sks-keyservers.net, subkeys.pgp.net, pgp.mit.edu"; public static final String KEY_SERVERS = "pool.sks-keyservers.net, subkeys.pgp.net, pgp.mit.edu";
} }

View File

@@ -64,7 +64,7 @@ public class KeychainApplication extends Application {
// 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)) {
File dir = new File(Constants.path.APP_DIR); File dir = new File(Constants.Path.APP_DIR);
if (!dir.exists() && !dir.mkdirs()) { if (!dir.exists() && !dir.mkdirs()) {
// ignore this for now, it's not crucial // ignore this for now, it's not crucial
// that the directory doesn't exist at this point // that the directory doesn't exist at this point

View File

@@ -49,17 +49,17 @@ public class Preferences {
} }
public String getLanguage() { public String getLanguage() {
return mSharedPreferences.getString(Constants.pref.LANGUAGE, ""); return mSharedPreferences.getString(Constants.Pref.LANGUAGE, "");
} }
public void setLanguage(String value) { public void setLanguage(String value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(Constants.pref.LANGUAGE, value); editor.putString(Constants.Pref.LANGUAGE, value);
editor.commit(); editor.commit();
} }
public long getPassPhraseCacheTtl() { public long getPassPhraseCacheTtl() {
int ttl = mSharedPreferences.getInt(Constants.pref.PASS_PHRASE_CACHE_TTL, 180); int ttl = mSharedPreferences.getInt(Constants.Pref.PASS_PHRASE_CACHE_TTL, 180);
// fix the value if it was set to "never" in previous versions, which currently is not // fix the value if it was set to "never" in previous versions, which currently is not
// supported // supported
if (ttl == 0) { if (ttl == 0) {
@@ -70,77 +70,77 @@ public class Preferences {
public void setPassPhraseCacheTtl(int value) { public void setPassPhraseCacheTtl(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.PASS_PHRASE_CACHE_TTL, value); editor.putInt(Constants.Pref.PASS_PHRASE_CACHE_TTL, value);
editor.commit(); editor.commit();
} }
public int getDefaultEncryptionAlgorithm() { public int getDefaultEncryptionAlgorithm() {
return mSharedPreferences.getInt(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM, return mSharedPreferences.getInt(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM,
PGPEncryptedData.AES_256); PGPEncryptedData.AES_256);
} }
public void setDefaultEncryptionAlgorithm(int value) { public void setDefaultEncryptionAlgorithm(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM, value); editor.putInt(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM, value);
editor.commit(); editor.commit();
} }
public int getDefaultHashAlgorithm() { public int getDefaultHashAlgorithm() {
return mSharedPreferences.getInt(Constants.pref.DEFAULT_HASH_ALGORITHM, return mSharedPreferences.getInt(Constants.Pref.DEFAULT_HASH_ALGORITHM,
HashAlgorithmTags.SHA512); HashAlgorithmTags.SHA512);
} }
public void setDefaultHashAlgorithm(int value) { public void setDefaultHashAlgorithm(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.DEFAULT_HASH_ALGORITHM, value); editor.putInt(Constants.Pref.DEFAULT_HASH_ALGORITHM, value);
editor.commit(); editor.commit();
} }
public int getDefaultMessageCompression() { public int getDefaultMessageCompression() {
return mSharedPreferences.getInt(Constants.pref.DEFAULT_MESSAGE_COMPRESSION, return mSharedPreferences.getInt(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION,
Id.choice.compression.zlib); Id.choice.compression.zlib);
} }
public void setDefaultMessageCompression(int value) { public void setDefaultMessageCompression(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.DEFAULT_MESSAGE_COMPRESSION, value); editor.putInt(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION, value);
editor.commit(); editor.commit();
} }
public int getDefaultFileCompression() { public int getDefaultFileCompression() {
return mSharedPreferences.getInt(Constants.pref.DEFAULT_FILE_COMPRESSION, return mSharedPreferences.getInt(Constants.Pref.DEFAULT_FILE_COMPRESSION,
Id.choice.compression.none); Id.choice.compression.none);
} }
public void setDefaultFileCompression(int value) { public void setDefaultFileCompression(int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(Constants.pref.DEFAULT_FILE_COMPRESSION, value); editor.putInt(Constants.Pref.DEFAULT_FILE_COMPRESSION, value);
editor.commit(); editor.commit();
} }
public boolean getDefaultAsciiArmour() { public boolean getDefaultAsciiArmour() {
return mSharedPreferences.getBoolean(Constants.pref.DEFAULT_ASCII_ARMOUR, false); return mSharedPreferences.getBoolean(Constants.Pref.DEFAULT_ASCII_ARMOUR, false);
} }
public void setDefaultAsciiArmour(boolean value) { public void setDefaultAsciiArmour(boolean value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.pref.DEFAULT_ASCII_ARMOUR, value); editor.putBoolean(Constants.Pref.DEFAULT_ASCII_ARMOUR, value);
editor.commit(); editor.commit();
} }
public boolean getForceV3Signatures() { public boolean getForceV3Signatures() {
return mSharedPreferences.getBoolean(Constants.pref.FORCE_V3_SIGNATURES, false); return mSharedPreferences.getBoolean(Constants.Pref.FORCE_V3_SIGNATURES, false);
} }
public void setForceV3Signatures(boolean value) { public void setForceV3Signatures(boolean value) {
SharedPreferences.Editor editor = mSharedPreferences.edit(); SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(Constants.pref.FORCE_V3_SIGNATURES, value); editor.putBoolean(Constants.Pref.FORCE_V3_SIGNATURES, value);
editor.commit(); editor.commit();
} }
public String[] getKeyServers() { public String[] getKeyServers() {
String rawData = mSharedPreferences.getString(Constants.pref.KEY_SERVERS, String rawData = mSharedPreferences.getString(Constants.Pref.KEY_SERVERS,
Constants.defaults.KEY_SERVERS); Constants.Defaults.KEY_SERVERS);
Vector<String> servers = new Vector<String>(); Vector<String> servers = new Vector<String>();
String chunks[] = rawData.split(","); String chunks[] = rawData.split(",");
for (String c : chunks) { for (String c : chunks) {
@@ -165,7 +165,7 @@ public class Preferences {
} }
rawData += tmp; rawData += tmp;
} }
editor.putString(Constants.pref.KEY_SERVERS, rawData); editor.putString(Constants.Pref.KEY_SERVERS, rawData);
editor.commit(); editor.commit();
} }
} }

View File

@@ -17,11 +17,6 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory; import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
@@ -29,12 +24,17 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
public class PgpConversionHelper { public class PgpConversionHelper {
/** /**
* Convert from byte[] to PGPKeyRing * Convert from byte[] to PGPKeyRing
* *
* @param keysBytes * @param keysBytes
* @return * @return
*/ */
@@ -54,7 +54,7 @@ public class PgpConversionHelper {
/** /**
* Convert from byte[] to ArrayList<PGPSecretKey> * Convert from byte[] to ArrayList<PGPSecretKey>
* *
* @param keysBytes * @param keysBytes
* @return * @return
*/ */
@@ -73,9 +73,9 @@ public class PgpConversionHelper {
/** /**
* Convert from byte[] to PGPSecretKey * Convert from byte[] to PGPSecretKey
* * <p/>
* Singles keys are encoded as keyRings with one single key in it by Bouncy Castle * Singles keys are encoded as keyRings with one single key in it by Bouncy Castle
* *
* @param keyBytes * @param keyBytes
* @return * @return
*/ */
@@ -88,13 +88,13 @@ public class PgpConversionHelper {
Log.e(Constants.TAG, "Error while converting to PGPSecretKey!", e); Log.e(Constants.TAG, "Error while converting to PGPSecretKey!", e);
} }
PGPSecretKey secKey = null; PGPSecretKey secKey = null;
if(obj instanceof PGPSecretKey) { if (obj instanceof PGPSecretKey) {
if ((secKey = (PGPSecretKey)obj ) == null) { if ((secKey = (PGPSecretKey) obj) == null) {
Log.e(Constants.TAG, "No keys given!"); Log.e(Constants.TAG, "No keys given!");
} }
} else if(obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings } else if (obj instanceof PGPSecretKeyRing) { //master keys are sent as keyrings
PGPSecretKeyRing keyRing = null; PGPSecretKeyRing keyRing = null;
if ((keyRing = (PGPSecretKeyRing)obj) == null) { if ((keyRing = (PGPSecretKeyRing) obj) == null) {
Log.e(Constants.TAG, "No keys given!"); Log.e(Constants.TAG, "No keys given!");
} }
secKey = keyRing.getSecretKey(); secKey = keyRing.getSecretKey();
@@ -105,7 +105,7 @@ public class PgpConversionHelper {
/** /**
* Convert from ArrayList<PGPSecretKey> to byte[] * Convert from ArrayList<PGPSecretKey> to byte[]
* *
* @param keys * @param keys
* @return * @return
*/ */
@@ -124,7 +124,7 @@ public class PgpConversionHelper {
/** /**
* Convert from PGPSecretKey to byte[] * Convert from PGPSecretKey to byte[]
* *
* @param key * @param key
* @return * @return
*/ */
@@ -140,7 +140,7 @@ public class PgpConversionHelper {
/** /**
* Convert from PGPSecretKeyRing to byte[] * Convert from PGPSecretKeyRing to byte[]
* *
* @param keyRing * @param keyRing
* @return * @return
*/ */

View File

@@ -18,38 +18,16 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import android.content.Context; import android.content.Context;
import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.bcpg.ArmoredInputStream;
import org.spongycastle.bcpg.SignatureSubpacketTags; import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.openpgp.PGPCompressedData; import org.spongycastle.openpgp.*;
import org.spongycastle.openpgp.PGPEncryptedData;
import org.spongycastle.openpgp.PGPEncryptedDataList;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPLiteralData;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPOnePassSignature;
import org.spongycastle.openpgp.PGPOnePassSignatureList;
import org.spongycastle.openpgp.PGPPBEEncryptedData;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureList;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; import org.spongycastle.openpgp.operator.jcajce.*;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
@@ -59,12 +37,7 @@ import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
import java.io.BufferedInputStream; import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.Iterator; import java.util.Iterator;
@@ -72,57 +45,57 @@ import java.util.Iterator;
* This class uses a Builder pattern! * This class uses a Builder pattern!
*/ */
public class PgpDecryptVerify { public class PgpDecryptVerify {
private Context context; private Context mContext;
private InputData data; private InputData mData;
private OutputStream outStream; private OutputStream mOutStream;
private ProgressDialogUpdater progressDialogUpdater; private ProgressDialogUpdater mProgressDialogUpdater;
private boolean assumeSymmetric; private boolean mAssumeSymmetric;
private String passphrase; private String mPassphrase;
private long enforcedKeyId; private long mEnforcedKeyId;
private PgpDecryptVerify(Builder builder) { private PgpDecryptVerify(Builder builder) {
// private Constructor can only be called from Builder // private Constructor can only be called from Builder
this.context = builder.context; this.mContext = builder.mContext;
this.data = builder.data; this.mData = builder.mData;
this.outStream = builder.outStream; this.mOutStream = builder.mOutStream;
this.progressDialogUpdater = builder.progressDialogUpdater; this.mProgressDialogUpdater = builder.mProgressDialogUpdater;
this.assumeSymmetric = builder.assumeSymmetric; this.mAssumeSymmetric = builder.mAssumeSymmetric;
this.passphrase = builder.passphrase; this.mPassphrase = builder.mPassphrase;
this.enforcedKeyId = builder.enforcedKeyId; this.mEnforcedKeyId = builder.mEnforcedKeyId;
} }
public static class Builder { public static class Builder {
// mandatory parameter // mandatory parameter
private Context context; private Context mContext;
private InputData data; private InputData mData;
private OutputStream outStream; private OutputStream mOutStream;
// optional // optional
private ProgressDialogUpdater progressDialogUpdater = null; private ProgressDialogUpdater mProgressDialogUpdater = null;
private boolean assumeSymmetric = false; private boolean mAssumeSymmetric = false;
private String passphrase = ""; private String mPassphrase = "";
private long enforcedKeyId = 0; private long mEnforcedKeyId = 0;
public Builder(Context context, InputData data, OutputStream outStream) { public Builder(Context context, InputData data, OutputStream outStream) {
this.context = context; this.mContext = context;
this.data = data; this.mData = data;
this.outStream = outStream; this.mOutStream = outStream;
} }
public Builder progressDialogUpdater(ProgressDialogUpdater progressDialogUpdater) { public Builder progressDialogUpdater(ProgressDialogUpdater progressDialogUpdater) {
this.progressDialogUpdater = progressDialogUpdater; this.mProgressDialogUpdater = progressDialogUpdater;
return this; return this;
} }
public Builder assumeSymmetric(boolean assumeSymmetric) { public Builder assumeSymmetric(boolean assumeSymmetric) {
this.assumeSymmetric = assumeSymmetric; this.mAssumeSymmetric = assumeSymmetric;
return this; return this;
} }
public Builder passphrase(String passphrase) { public Builder passphrase(String passphrase) {
this.passphrase = passphrase; this.mPassphrase = passphrase;
return this; return this;
} }
@@ -134,7 +107,7 @@ public class PgpDecryptVerify {
* @return * @return
*/ */
public Builder enforcedKeyId(long enforcedKeyId) { public Builder enforcedKeyId(long enforcedKeyId) {
this.enforcedKeyId = enforcedKeyId; this.mEnforcedKeyId = enforcedKeyId;
return this; return this;
} }
@@ -144,14 +117,14 @@ public class PgpDecryptVerify {
} }
public void updateProgress(int message, int current, int total) { public void updateProgress(int message, int current, int total) {
if (progressDialogUpdater != null) { if (mProgressDialogUpdater != null) {
progressDialogUpdater.setProgress(message, current, total); mProgressDialogUpdater.setProgress(message, current, total);
} }
} }
public void updateProgress(int current, int total) { public void updateProgress(int current, int total) {
if (progressDialogUpdater != null) { if (mProgressDialogUpdater != null) {
progressDialogUpdater.setProgress(current, total); mProgressDialogUpdater.setProgress(current, total);
} }
} }
@@ -196,7 +169,7 @@ public class PgpDecryptVerify {
public PgpDecryptVerifyResult execute() public PgpDecryptVerifyResult execute()
throws IOException, PgpGeneralException, PGPException, SignatureException { throws IOException, PgpGeneralException, PGPException, SignatureException {
// automatically works with ascii armor input and binary // automatically works with ascii armor input and binary
InputStream in = PGPUtil.getDecoderStream(data.getInputStream()); InputStream in = PGPUtil.getDecoderStream(mData.getInputStream());
if (in instanceof ArmoredInputStream) { if (in instanceof ArmoredInputStream) {
ArmoredInputStream aIn = (ArmoredInputStream) in; ArmoredInputStream aIn = (ArmoredInputStream) in;
// it is ascii armored // it is ascii armored
@@ -240,7 +213,7 @@ public class PgpDecryptVerify {
} }
if (enc == null) { if (enc == null) {
throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); throw new PgpGeneralException(mContext.getString(R.string.error_invalid_data));
} }
InputStream clear; InputStream clear;
@@ -250,7 +223,7 @@ public class PgpDecryptVerify {
// TODO: currently we always only look at the first known key or symmetric encryption, // TODO: currently we always only look at the first known key or symmetric encryption,
// there might be more... // there might be more...
if (assumeSymmetric) { if (mAssumeSymmetric) {
PGPPBEEncryptedData pbe = null; PGPPBEEncryptedData pbe = null;
Iterator<?> it = enc.getEncryptedDataObjects(); Iterator<?> it = enc.getEncryptedDataObjects();
// find secret key // find secret key
@@ -264,7 +237,7 @@ public class PgpDecryptVerify {
if (pbe == null) { if (pbe == null) {
throw new PgpGeneralException( throw new PgpGeneralException(
context.getString(R.string.error_no_symmetric_encryption_packet)); mContext.getString(R.string.error_no_symmetric_encryption_packet));
} }
updateProgress(R.string.progress_preparing_streams, currentProgress, 100); updateProgress(R.string.progress_preparing_streams, currentProgress, 100);
@@ -273,7 +246,7 @@ public class PgpDecryptVerify {
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build();
PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder(
digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
passphrase.toCharArray()); mPassphrase.toCharArray());
clear = pbe.getDataStream(decryptorFactory); clear = pbe.getDataStream(decryptorFactory);
@@ -290,33 +263,35 @@ public class PgpDecryptVerify {
Object obj = it.next(); Object obj = it.next();
if (obj instanceof PGPPublicKeyEncryptedData) { if (obj instanceof PGPPublicKeyEncryptedData) {
PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID()); secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID());
if (secretKey != null) { if (secretKey != null) {
// secret key exists in database // secret key exists in database
// allow only a specific key for decryption? // allow only a specific key for decryption?
if (enforcedKeyId != 0) { if (mEnforcedKeyId != 0) {
// TODO: improve this code! get master key directly! // TODO: improve this code! get master key directly!
PGPSecretKeyRing secretKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, encData.getKeyID()); PGPSecretKeyRing secretKeyRing =
ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, encData.getKeyID());
long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID(); long masterKeyId = PgpKeyHelper.getMasterKey(secretKeyRing).getKeyID();
Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID()); Log.d(Constants.TAG, "encData.getKeyID():" + encData.getKeyID());
Log.d(Constants.TAG, "enforcedKeyId: " + enforcedKeyId); Log.d(Constants.TAG, "enforcedKeyId: " + mEnforcedKeyId);
Log.d(Constants.TAG, "masterKeyId: " + masterKeyId); Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);
if (enforcedKeyId != masterKeyId) { if (mEnforcedKeyId != masterKeyId) {
throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found)); throw new PgpGeneralException(
mContext.getString(R.string.error_no_secret_key_found));
} }
} }
pbe = encData; pbe = encData;
// if no passphrase was explicitly set try to get it from the cache service // if no passphrase was explicitly set try to get it from the cache service
if (passphrase == null) { if (mPassphrase == null) {
// returns "" if key has no passphrase // returns "" if key has no passphrase
passphrase = PassphraseCacheService.getCachedPassphrase(context, encData.getKeyID()); mPassphrase = PassphraseCacheService.getCachedPassphrase(mContext, encData.getKeyID());
// if passphrase was not cached, return here indicating that a passphrase is missing! // if passphrase was not cached, return here indicating that a passphrase is missing!
if (passphrase == null) { if (mPassphrase == null) {
returnData.setKeyPassphraseNeeded(true); returnData.setKeyPassphraseNeeded(true);
return returnData; return returnData;
} }
@@ -330,7 +305,7 @@ public class PgpDecryptVerify {
} }
if (secretKey == null) { if (secretKey == null) {
throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found)); throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found));
} }
currentProgress += 5; currentProgress += 5;
@@ -339,14 +314,14 @@ public class PgpDecryptVerify {
try { try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
passphrase.toCharArray()); mPassphrase.toCharArray());
privateKey = secretKey.extractPrivateKey(keyDecryptor); privateKey = secretKey.extractPrivateKey(keyDecryptor);
} catch (PGPException e) { } catch (PGPException e) {
throw new PGPException(context.getString(R.string.error_wrong_passphrase)); throw new PGPException(mContext.getString(R.string.error_wrong_passphrase));
} }
if (privateKey == null) { if (privateKey == null) {
throw new PgpGeneralException( throw new PgpGeneralException(
context.getString(R.string.error_could_not_extract_private_key)); mContext.getString(R.string.error_could_not_extract_private_key));
} }
currentProgress += 5; currentProgress += 5;
updateProgress(R.string.progress_preparing_streams, currentProgress, 100); updateProgress(R.string.progress_preparing_streams, currentProgress, 100);
@@ -386,7 +361,7 @@ public class PgpDecryptVerify {
for (int i = 0; i < sigList.size(); ++i) { for (int i = 0; i < sigList.size(); ++i) {
signature = sigList.get(i); signature = sigList.get(i);
signatureKey = ProviderHelper signatureKey = ProviderHelper
.getPGPPublicKeyByKeyId(context, signature.getKeyID()); .getPGPPublicKeyByKeyId(mContext, signature.getKeyID());
if (signatureKeyId == 0) { if (signatureKeyId == 0) {
signatureKeyId = signature.getKeyID(); signatureKeyId = signature.getKeyID();
} }
@@ -397,7 +372,7 @@ public class PgpDecryptVerify {
signatureKeyId = signature.getKeyID(); signatureKeyId = signature.getKeyID();
String userId = null; String userId = null;
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(
context, signatureKeyId); mContext, signatureKeyId);
if (signKeyRing != null) { if (signKeyRing != null) {
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
} }
@@ -444,9 +419,9 @@ public class PgpDecryptVerify {
int n; int n;
// TODO: progress calculation is broken here! Try to rework it based on commented code! // TODO: progress calculation is broken here! Try to rework it based on commented code!
// int progress = 0; // int progress = 0;
long startPos = data.getStreamPosition(); long startPos = mData.getStreamPosition();
while ((n = dataIn.read(buffer)) > 0) { while ((n = dataIn.read(buffer)) > 0) {
outStream.write(buffer, 0, n); mOutStream.write(buffer, 0, n);
// progress += n; // progress += n;
if (signature != null) { if (signature != null) {
try { try {
@@ -460,11 +435,11 @@ public class PgpDecryptVerify {
// unknown size, but try to at least have a moving, slowing down progress bar // unknown size, but try to at least have a moving, slowing down progress bar
// currentProgress = startProgress + (endProgress - startProgress) * progress // currentProgress = startProgress + (endProgress - startProgress) * progress
// / (progress + 100000); // / (progress + 100000);
if (data.getSize() - startPos == 0) { if (mData.getSize() - startPos == 0) {
currentProgress = endProgress; currentProgress = endProgress;
} else { } else {
currentProgress = (int) (startProgress + (endProgress - startProgress) currentProgress = (int) (startProgress + (endProgress - startProgress)
* (data.getStreamPosition() - startPos) / (data.getSize() - startPos)); * (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos));
} }
updateProgress(currentProgress, 100); updateProgress(currentProgress, 100);
} }
@@ -480,7 +455,7 @@ public class PgpDecryptVerify {
signatureResult.setSignatureOnly(false); signatureResult.setSignatureOnly(false);
//Now check binding signatures //Now check binding signatures
boolean validKeyBinding = verifyKeyBinding(context, messageSignature, signatureKey); boolean validKeyBinding = verifyKeyBinding(mContext, messageSignature, signatureKey);
boolean validSignature = signature.verify(messageSignature); boolean validSignature = signature.verify(messageSignature);
// TODO: implement CERTIFIED! // TODO: implement CERTIFIED!
@@ -499,7 +474,7 @@ public class PgpDecryptVerify {
} else { } else {
// failed // failed
Log.d(Constants.TAG, "Integrity verification: failed!"); Log.d(Constants.TAG, "Integrity verification: failed!");
throw new PgpGeneralException(context.getString(R.string.error_integrity_check_failed)); throw new PgpGeneralException(mContext.getString(R.string.error_integrity_check_failed));
} }
} else { } else {
// no integrity check // no integrity check
@@ -555,21 +530,21 @@ public class PgpDecryptVerify {
out.close(); out.close();
byte[] clearText = out.toByteArray(); byte[] clearText = out.toByteArray();
outStream.write(clearText); mOutStream.write(clearText);
updateProgress(R.string.progress_processing_signature, 60, 100); updateProgress(R.string.progress_processing_signature, 60, 100);
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
if (sigList == null) { if (sigList == null) {
throw new PgpGeneralException(context.getString(R.string.error_corrupt_data)); throw new PgpGeneralException(mContext.getString(R.string.error_corrupt_data));
} }
PGPSignature signature = null; PGPSignature signature = null;
long signatureKeyId = 0; long signatureKeyId = 0;
PGPPublicKey signatureKey = null; PGPPublicKey signatureKey = null;
for (int i = 0; i < sigList.size(); ++i) { for (int i = 0; i < sigList.size(); ++i) {
signature = sigList.get(i); signature = sigList.get(i);
signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(context, signature.getKeyID()); signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(mContext, signature.getKeyID());
if (signatureKeyId == 0) { if (signatureKeyId == 0) {
signatureKeyId = signature.getKeyID(); signatureKeyId = signature.getKeyID();
} }
@@ -579,7 +554,7 @@ public class PgpDecryptVerify {
} else { } else {
signatureKeyId = signature.getKeyID(); signatureKeyId = signature.getKeyID();
String userId = null; String userId = null;
PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext,
signatureKeyId); signatureKeyId);
if (signKeyRing != null) { if (signKeyRing != null) {
userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing));
@@ -623,7 +598,7 @@ public class PgpDecryptVerify {
} }
//Now check binding signatures //Now check binding signatures
boolean validKeyBinding = verifyKeyBinding(context, signature, signatureKey); boolean validKeyBinding = verifyKeyBinding(mContext, signature, signatureKey);
boolean validSignature = signature.verify(); boolean validSignature = signature.verify();
if (validSignature & validKeyBinding) { if (validSignature & validKeyBinding) {
@@ -684,24 +659,27 @@ public class PgpDecryptVerify {
continue; continue;
} }
if (validTempSubkeyBinding) if (validTempSubkeyBinding) {
validSubkeyBinding = true; validSubkeyBinding = true;
}
if (validTempSubkeyBinding) { if (validTempSubkeyBinding) {
validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getUnhashedSubPackets(), validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getUnhashedSubPackets(),
masterPublicKey, signingPublicKey); masterPublicKey, signingPublicKey);
if (validPrimaryKeyBinding) if (validPrimaryKeyBinding) {
break; break;
}
validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getHashedSubPackets(), validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getHashedSubPackets(),
masterPublicKey, signingPublicKey); masterPublicKey, signingPublicKey);
if (validPrimaryKeyBinding) if (validPrimaryKeyBinding) {
break; break;
}
} }
} }
} }
return (validSubkeyBinding & validPrimaryKeyBinding); return (validSubkeyBinding & validPrimaryKeyBinding);
} }
private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector Pkts, private static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts,
PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) {
boolean validPrimaryKeyBinding = false; boolean validPrimaryKeyBinding = false;
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
@@ -709,9 +687,9 @@ public class PgpDecryptVerify {
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureList eSigList; PGPSignatureList eSigList;
if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { if (pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) {
try { try {
eSigList = Pkts.getEmbeddedSignatures(); eSigList = pkts.getEmbeddedSignatures();
} catch (IOException e) { } catch (IOException e) {
return false; return false;
} catch (PGPException e) { } catch (PGPException e) {
@@ -723,8 +701,9 @@ public class PgpDecryptVerify {
try { try {
emSig.init(contentVerifierBuilderProvider, signingPublicKey); emSig.init(contentVerifierBuilderProvider, signingPublicKey);
validPrimaryKeyBinding = emSig.verifyCertification(masterPublicKey, signingPublicKey); validPrimaryKeyBinding = emSig.verifyCertification(masterPublicKey, signingPublicKey);
if (validPrimaryKeyBinding) if (validPrimaryKeyBinding) {
break; break;
}
} catch (PGPException e) { } catch (PGPException e) {
continue; continue;
} catch (SignatureException e) { } catch (SignatureException e) {

View File

@@ -19,36 +19,35 @@ package org.sufficientlysecure.keychain.pgp;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.OpenPgpSignatureResult;
public class PgpDecryptVerifyResult implements Parcelable { public class PgpDecryptVerifyResult implements Parcelable {
boolean symmetricPassphraseNeeded; boolean mSymmetricPassphraseNeeded;
boolean keyPassphraseNeeded; boolean mKeyPassphraseNeeded;
OpenPgpSignatureResult signatureResult; OpenPgpSignatureResult mSignatureResult;
public boolean isSymmetricPassphraseNeeded() { public boolean isSymmetricPassphraseNeeded() {
return symmetricPassphraseNeeded; return mSymmetricPassphraseNeeded;
} }
public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) { public void setSymmetricPassphraseNeeded(boolean symmetricPassphraseNeeded) {
this.symmetricPassphraseNeeded = symmetricPassphraseNeeded; this.mSymmetricPassphraseNeeded = symmetricPassphraseNeeded;
} }
public boolean isKeyPassphraseNeeded() { public boolean isKeyPassphraseNeeded() {
return keyPassphraseNeeded; return mKeyPassphraseNeeded;
} }
public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) { public void setKeyPassphraseNeeded(boolean keyPassphraseNeeded) {
this.keyPassphraseNeeded = keyPassphraseNeeded; this.mKeyPassphraseNeeded = keyPassphraseNeeded;
} }
public OpenPgpSignatureResult getSignatureResult() { public OpenPgpSignatureResult getSignatureResult() {
return signatureResult; return mSignatureResult;
} }
public void setSignatureResult(OpenPgpSignatureResult signatureResult) { public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
this.signatureResult = signatureResult; this.mSignatureResult = signatureResult;
} }
public PgpDecryptVerifyResult() { public PgpDecryptVerifyResult() {
@@ -56,9 +55,9 @@ public class PgpDecryptVerifyResult implements Parcelable {
} }
public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) { public PgpDecryptVerifyResult(PgpDecryptVerifyResult b) {
this.symmetricPassphraseNeeded = b.symmetricPassphraseNeeded; this.mSymmetricPassphraseNeeded = b.mSymmetricPassphraseNeeded;
this.keyPassphraseNeeded = b.keyPassphraseNeeded; this.mKeyPassphraseNeeded = b.mKeyPassphraseNeeded;
this.signatureResult = b.signatureResult; this.mSignatureResult = b.mSignatureResult;
} }
@@ -67,17 +66,17 @@ public class PgpDecryptVerifyResult implements Parcelable {
} }
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (symmetricPassphraseNeeded ? 1 : 0)); dest.writeByte((byte) (mSymmetricPassphraseNeeded ? 1 : 0));
dest.writeByte((byte) (keyPassphraseNeeded ? 1 : 0)); dest.writeByte((byte) (mKeyPassphraseNeeded ? 1 : 0));
dest.writeParcelable(signatureResult, 0); dest.writeParcelable(mSignatureResult, 0);
} }
public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() { public static final Creator<PgpDecryptVerifyResult> CREATOR = new Creator<PgpDecryptVerifyResult>() {
public PgpDecryptVerifyResult createFromParcel(final Parcel source) { public PgpDecryptVerifyResult createFromParcel(final Parcel source) {
PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult(); PgpDecryptVerifyResult vr = new PgpDecryptVerifyResult();
vr.symmetricPassphraseNeeded = source.readByte() == 1; vr.mSymmetricPassphraseNeeded = source.readByte() == 1;
vr.keyPassphraseNeeded = source.readByte() == 1; vr.mKeyPassphraseNeeded = source.readByte() == 1;
vr.signatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader()); vr.mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
return vr; return vr;
} }

View File

@@ -17,22 +17,10 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import java.io.File; import android.content.Context;
import java.io.FileNotFoundException; import android.content.pm.PackageInfo;
import java.io.IOException; import android.content.pm.PackageManager.NameNotFoundException;
import java.io.InputStream; import org.spongycastle.openpgp.*;
import java.io.RandomAccessFile;
import java.security.SecureRandom;
import java.util.Iterator;
import java.util.regex.Pattern;
import org.spongycastle.openpgp.PGPEncryptedDataList;
import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPUtil;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
@@ -42,21 +30,25 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
import android.content.Context; import java.io.File;
import android.content.pm.PackageInfo; import java.io.IOException;
import android.content.pm.PackageManager.NameNotFoundException; import java.io.InputStream;
import java.io.RandomAccessFile;
import java.security.SecureRandom;
import java.util.Iterator;
import java.util.regex.Pattern;
public class PgpHelper { public class PgpHelper {
public static Pattern PGP_MESSAGE = Pattern.compile( public static final Pattern PGP_MESSAGE = Pattern.compile(
".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL);
public static Pattern PGP_SIGNED_MESSAGE = Pattern public static final Pattern PGP_SIGNED_MESSAGE = Pattern
.compile( .compile(
".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
Pattern.DOTALL); Pattern.DOTALL);
public static Pattern PGP_PUBLIC_KEY = Pattern.compile( public static final Pattern PGP_PUBLIC_KEY = Pattern.compile(
".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*", ".*?(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?-----END PGP PUBLIC KEY BLOCK-----).*",
Pattern.DOTALL); Pattern.DOTALL);
@@ -140,7 +132,7 @@ public class PgpHelper {
/** /**
* Generate a random filename * Generate a random filename
* *
* @param length * @param length
* @return * @return
*/ */
@@ -170,7 +162,7 @@ public class PgpHelper {
/** /**
* Go once through stream to get length of stream. The length is later used to display progress * Go once through stream to get length of stream. The length is later used to display progress
* when encrypting/decrypting * when encrypting/decrypting
* *
* @param in * @param in
* @return * @return
* @throws IOException * @throws IOException
@@ -187,9 +179,9 @@ public class PgpHelper {
/** /**
* Deletes file securely by overwriting it with random data before deleting it. * Deletes file securely by overwriting it with random data before deleting it.
* * <p/>
* TODO: Does this really help on flash storage? * TODO: Does this really help on flash storage?
* *
* @param context * @param context
* @param progress * @param progress
* @param file * @param file
@@ -206,8 +198,9 @@ public class PgpHelper {
int pos = 0; int pos = 0;
String msg = context.getString(R.string.progress_deleting_securely, file.getName()); String msg = context.getString(R.string.progress_deleting_securely, file.getName());
while (pos < length) { while (pos < length) {
if (progress != null) if (progress != null) {
progress.setProgress(msg, (int) (100 * pos / length), 100); progress.setProgress(msg, (int) (100 * pos / length), 100);
}
random.nextBytes(data); random.nextBytes(data);
raf.write(data); raf.write(data);
pos += data.length; pos += data.length;

View File

@@ -17,20 +17,11 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import java.io.ByteArrayOutputStream; import android.content.Context;
import java.io.FileNotFoundException; import android.os.Bundle;
import java.io.IOException; import android.os.Environment;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.*;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
@@ -39,16 +30,14 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
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.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
import org.sufficientlysecure.keychain.util.HkpKeyServer; import org.sufficientlysecure.keychain.util.*;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException; import org.sufficientlysecure.keychain.util.KeyServer.AddKeyException;
import org.sufficientlysecure.keychain.util.KeychainServiceListener;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
import android.content.Context; import java.io.ByteArrayOutputStream;
import android.os.Bundle; import java.io.IOException;
import android.os.Environment; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class PgpImportExport { public class PgpImportExport {
@@ -63,7 +52,7 @@ public class PgpImportExport {
this.mProgress = progress; this.mProgress = progress;
} }
public PgpImportExport(Context context, ProgressDialogUpdater progress, KeychainServiceListener keychainListener){ public PgpImportExport(Context context, ProgressDialogUpdater progress, KeychainServiceListener keychainListener) {
super(); super();
this.mContext = context; this.mContext = context;
this.mProgress = progress; this.mProgress = progress;
@@ -107,8 +96,8 @@ public class PgpImportExport {
return false; return false;
} finally { } finally {
try { try {
if (aos != null) aos.close(); if (aos != null) { aos.close(); }
if (bos != null) bos.close(); if (bos != null) { bos.close(); }
} catch (IOException e) { } catch (IOException e) {
} }
} }
@@ -199,7 +188,7 @@ public class PgpImportExport {
if (secretKeyRing != null) { if (secretKeyRing != null) {
secretKeyRing.encode(arOutStream); secretKeyRing.encode(arOutStream);
} }
if(mKeychainServiceListener.hasServiceStopped()){ if (mKeychainServiceListener.hasServiceStopped()) {
arOutStream.close(); arOutStream.close();
return null; return null;
} }
@@ -212,7 +201,7 @@ public class PgpImportExport {
publicKeyRing.encode(arOutStream); publicKeyRing.encode(arOutStream);
} }
if(mKeychainServiceListener.hasServiceStopped()){ if (mKeychainServiceListener.hasServiceStopped()) {
arOutStream.close(); arOutStream.close();
return null; return null;
} }

View File

@@ -17,21 +17,9 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import java.util.Calendar; import android.content.Context;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.*;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.util.encoders.Hex; import org.spongycastle.util.encoders.Hex;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
@@ -39,7 +27,9 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import android.content.Context; import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PgpKeyHelper { public class PgpKeyHelper {

View File

@@ -17,48 +17,20 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import java.io.IOException; import android.content.Context;
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.SignatureException;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.jce.provider.BouncyCastleProvider; import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.jce.spec.ElGamalParameterSpec; import org.spongycastle.jce.spec.ElGamalParameterSpec;
import org.spongycastle.openpgp.PGPEncryptedData; import org.spongycastle.openpgp.*;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPKeyPair;
import org.spongycastle.openpgp.PGPKeyRingGenerator;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor; import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor;
import org.spongycastle.openpgp.operator.PGPContentSignerBuilder; import org.spongycastle.openpgp.operator.PGPContentSignerBuilder;
import org.spongycastle.openpgp.operator.PGPDigestCalculator; import org.spongycastle.openpgp.operator.PGPDigestCalculator;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.spongycastle.openpgp.operator.jcajce.*;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
@@ -68,21 +40,27 @@ import org.sufficientlysecure.keychain.util.Log;
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 android.content.Context; import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class PgpKeyOperation { public class PgpKeyOperation {
private Context mContext; private Context mContext;
private ProgressDialogUpdater mProgress; private ProgressDialogUpdater mProgress;
private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] { private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192,
SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5, SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5,
SymmetricKeyAlgorithmTags.TRIPLE_DES }; SymmetricKeyAlgorithmTags.TRIPLE_DES};
private static final int[] PREFERRED_HASH_ALGORITHMS = new int[] { HashAlgorithmTags.SHA1, private static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{HashAlgorithmTags.SHA1,
HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160 }; HashAlgorithmTags.SHA256, HashAlgorithmTags.RIPEMD160};
private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[] { private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{
CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2,
CompressionAlgorithmTags.ZIP }; CompressionAlgorithmTags.ZIP};
public PgpKeyOperation(Context context, ProgressDialogUpdater progress) { public PgpKeyOperation(Context context, ProgressDialogUpdater progress) {
super(); super();
@@ -104,7 +82,7 @@ public class PgpKeyOperation {
/** /**
* Creates new secret key. * Creates new secret key.
* *
* @param algorithmChoice * @param algorithmChoice
* @param keySize * @param keySize
* @param passphrase * @param passphrase
@@ -119,8 +97,9 @@ public class PgpKeyOperation {
// TODO: key flags? // TODO: key flags?
public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase, public PGPSecretKey createKey(int algorithmChoice, int keySize, String passphrase,
boolean isMasterKey) throws NoSuchAlgorithmException, PGPException, NoSuchProviderException, boolean isMasterKey)
PgpGeneralException, InvalidAlgorithmParameterException { throws NoSuchAlgorithmException, PGPException, NoSuchProviderException,
PgpGeneralException, InvalidAlgorithmParameterException {
if (keySize < 512) { if (keySize < 512) {
throw new PgpGeneralException(mContext.getString(R.string.error_key_size_minimum512bit)); throw new PgpGeneralException(mContext.getString(R.string.error_key_size_minimum512bit));
@@ -134,41 +113,41 @@ public class PgpKeyOperation {
KeyPairGenerator keyGen = null; KeyPairGenerator keyGen = null;
switch (algorithmChoice) { switch (algorithmChoice) {
case Id.choice.algorithm.dsa: { case Id.choice.algorithm.dsa: {
keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
keyGen.initialize(keySize, new SecureRandom()); keyGen.initialize(keySize, new SecureRandom());
algorithm = PGPPublicKey.DSA; algorithm = PGPPublicKey.DSA;
break; break;
}
case Id.choice.algorithm.elgamal: {
if (isMasterKey) {
throw new PgpGeneralException(
mContext.getString(R.string.error_master_key_must_not_be_el_gamal));
} }
keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
BigInteger p = Primes.getBestPrime(keySize);
BigInteger g = new BigInteger("2");
ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); case Id.choice.algorithm.elgamal: {
if (isMasterKey) {
throw new PgpGeneralException(
mContext.getString(R.string.error_master_key_must_not_be_el_gamal));
}
keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
BigInteger p = Primes.getBestPrime(keySize);
BigInteger g = new BigInteger("2");
keyGen.initialize(elParams); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
algorithm = PGPPublicKey.ELGAMAL_ENCRYPT;
break;
}
case Id.choice.algorithm.rsa: { keyGen.initialize(elParams);
keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); algorithm = PGPPublicKey.ELGAMAL_ENCRYPT;
keyGen.initialize(keySize, new SecureRandom()); break;
}
algorithm = PGPPublicKey.RSA_GENERAL; case Id.choice.algorithm.rsa: {
break; keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
} keyGen.initialize(keySize, new SecureRandom());
default: { algorithm = PGPPublicKey.RSA_GENERAL;
throw new PgpGeneralException( break;
mContext.getString(R.string.error_unknown_algorithm_choice)); }
}
default: {
throw new PgpGeneralException(
mContext.getString(R.string.error_unknown_algorithm_choice));
}
} }
// build new key pair // build new key pair
@@ -184,13 +163,13 @@ public class PgpKeyOperation {
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
PGPSecretKey secKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(), PGPSecretKey secKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
sha1Calc, isMasterKey, keyEncryptor); sha1Calc, isMasterKey, keyEncryptor);
return secKey; return secKey;
} }
public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase, public void changeSecretKeyPassphrase(PGPSecretKeyRing keyRing, String oldPassPhrase,
String newPassPhrase) throws IOException, PGPException, String newPassPhrase) throws IOException, PGPException,
NoSuchProviderException { NoSuchProviderException {
updateProgress(R.string.progress_building_key, 0, 100); updateProgress(R.string.progress_building_key, 0, 100);
@@ -218,9 +197,9 @@ public class PgpKeyOperation {
} }
public void buildSecretKey(ArrayList<String> userIds, ArrayList<PGPSecretKey> keys, public void buildSecretKey(ArrayList<String> userIds, ArrayList<PGPSecretKey> keys,
ArrayList<Integer> keysUsages, ArrayList<GregorianCalendar> keysExpiryDates, ArrayList<Integer> keysUsages, ArrayList<GregorianCalendar> keysExpiryDates,
long masterKeyId, String oldPassPhrase, long masterKeyId, String oldPassPhrase,
String newPassPhrase) throws PgpGeneralException, NoSuchProviderException, String newPassPhrase) throws PgpGeneralException, NoSuchProviderException,
PGPException, NoSuchAlgorithmException, SignatureException, IOException { PGPException, NoSuchAlgorithmException, SignatureException, IOException {
Log.d(Constants.TAG, "userIds: " + userIds.toString()); Log.d(Constants.TAG, "userIds: " + userIds.toString());
@@ -237,8 +216,10 @@ public class PgpKeyOperation {
updateProgress(R.string.progress_preparing_master_key, 10, 100); updateProgress(R.string.progress_preparing_master_key, 10, 100);
int usageId = keysUsages.get(0); int usageId = keysUsages.get(0);
boolean canSign = (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt); boolean canSign =
boolean canEncrypt = (usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt); (usageId == Id.choice.usage.sign_only || usageId == Id.choice.usage.sign_and_encrypt);
boolean canEncrypt =
(usageId == Id.choice.usage.encrypt_only || usageId == Id.choice.usage.sign_and_encrypt);
String mainUserId = userIds.get(0); String mainUserId = userIds.get(0);
@@ -303,13 +284,16 @@ public class PgpKeyOperation {
GregorianCalendar expiryDate = keysExpiryDates.get(0); GregorianCalendar expiryDate = keysExpiryDates.get(0);
//note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
//here we purposefully ignore partial days in each date - long type has no fractional part! //here we purposefully ignore partial days in each date - long type has no fractional part!
long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); long numDays =
if (numDays <= 0) (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000);
if (numDays <= 0) {
throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation));
}
hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
} else { } else {
hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, //do this explicitly, although since we're rebuilding,
//this happens anyway hashedPacketsGen.setKeyExpirationTime(false, 0);
//this happens anyway
} }
updateProgress(R.string.progress_building_master_key, 30, 100); updateProgress(R.string.progress_building_master_key, 30, 100);
@@ -382,13 +366,17 @@ public class PgpKeyOperation {
GregorianCalendar expiryDate = keysExpiryDates.get(i); GregorianCalendar expiryDate = keysExpiryDates.get(i);
//note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c //note that the below, (a/c) - (b/c) is *not* the same as (a - b) /c
//here we purposefully ignore partial days in each date - long type has no fractional part! //here we purposefully ignore partial days in each date - long type has no fractional part!
long numDays = (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000); long numDays =
if (numDays <= 0) (expiryDate.getTimeInMillis() / 86400000) - (creationDate.getTimeInMillis() / 86400000);
throw new PgpGeneralException(mContext.getString(R.string.error_expiry_must_come_after_creation)); if (numDays <= 0) {
throw new PgpGeneralException
(mContext.getString(R.string.error_expiry_must_come_after_creation));
}
hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400); hashedPacketsGen.setKeyExpirationTime(false, numDays * 86400);
} else { } else {
hashedPacketsGen.setKeyExpirationTime(false, 0); //do this explicitly, although since we're rebuilding, //do this explicitly, although since we're rebuilding,
//this happens anyway hashedPacketsGen.setKeyExpirationTime(false, 0);
//this happens anyway
} }
keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate()); keyGen.addSubKey(subKeyPair, hashedPacketsGen.generate(), unhashedPacketsGen.generate());

View File

@@ -18,28 +18,11 @@
package org.sufficientlysecure.keychain.pgp; package org.sufficientlysecure.keychain.pgp;
import android.content.Context; import android.content.Context;
import org.spongycastle.bcpg.ArmoredOutputStream; import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.BCPGOutputStream; import org.spongycastle.bcpg.BCPGOutputStream;
import org.spongycastle.openpgp.PGPCompressedDataGenerator; import org.spongycastle.openpgp.*;
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPLiteralData;
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.spongycastle.openpgp.PGPV3SignatureGenerator;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.spongycastle.openpgp.operator.jcajce.*;
import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
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.R;
@@ -49,11 +32,7 @@ import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; import org.sufficientlysecure.keychain.util.ProgressDialogUpdater;
import java.io.BufferedReader; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.SignatureException; import java.security.SignatureException;
@@ -63,110 +42,110 @@ import java.util.Date;
* This class uses a Builder pattern! * This class uses a Builder pattern!
*/ */
public class PgpSignEncrypt { public class PgpSignEncrypt {
private Context context; private Context mContext;
private InputData data; private InputData mData;
private OutputStream outStream; private OutputStream mOutStream;
private ProgressDialogUpdater progress; private ProgressDialogUpdater mProgress;
private boolean enableAsciiArmorOutput; private boolean mEnableAsciiArmorOutput;
private int compressionId; private int mCompressionId;
private long[] encryptionKeyIds; private long[] mEncryptionKeyIds;
private String encryptionPassphrase; private String mEncryptionPassphrase;
private int symmetricEncryptionAlgorithm; private int mSymmetricEncryptionAlgorithm;
private long signatureKeyId; private long mSignatureKeyId;
private int signatureHashAlgorithm; private int mSignatureHashAlgorithm;
private boolean signatureForceV3; private boolean mSignatureForceV3;
private String signaturePassphrase; private String mSignaturePassphrase;
private PgpSignEncrypt(Builder builder) { private PgpSignEncrypt(Builder builder) {
// private Constructor can only be called from Builder // private Constructor can only be called from Builder
this.context = builder.context; this.mContext = builder.mContext;
this.data = builder.data; this.mData = builder.mData;
this.outStream = builder.outStream; this.mOutStream = builder.mOutStream;
this.progress = builder.progress; this.mProgress = builder.mProgress;
this.enableAsciiArmorOutput = builder.enableAsciiArmorOutput; this.mEnableAsciiArmorOutput = builder.mEnableAsciiArmorOutput;
this.compressionId = builder.compressionId; this.mCompressionId = builder.mCompressionId;
this.encryptionKeyIds = builder.encryptionKeyIds; this.mEncryptionKeyIds = builder.mEncryptionKeyIds;
this.encryptionPassphrase = builder.encryptionPassphrase; this.mEncryptionPassphrase = builder.mEncryptionPassphrase;
this.symmetricEncryptionAlgorithm = builder.symmetricEncryptionAlgorithm; this.mSymmetricEncryptionAlgorithm = builder.mSymmetricEncryptionAlgorithm;
this.signatureKeyId = builder.signatureKeyId; this.mSignatureKeyId = builder.mSignatureKeyId;
this.signatureHashAlgorithm = builder.signatureHashAlgorithm; this.mSignatureHashAlgorithm = builder.mSignatureHashAlgorithm;
this.signatureForceV3 = builder.signatureForceV3; this.mSignatureForceV3 = builder.mSignatureForceV3;
this.signaturePassphrase = builder.signaturePassphrase; this.mSignaturePassphrase = builder.mSignaturePassphrase;
} }
public static class Builder { public static class Builder {
// mandatory parameter // mandatory parameter
private Context context; private Context mContext;
private InputData data; private InputData mData;
private OutputStream outStream; private OutputStream mOutStream;
// optional // optional
private ProgressDialogUpdater progress = null; private ProgressDialogUpdater mProgress = null;
private boolean enableAsciiArmorOutput = false; private boolean mEnableAsciiArmorOutput = false;
private int compressionId = Id.choice.compression.none; private int mCompressionId = Id.choice.compression.none;
private long[] encryptionKeyIds = new long[0]; private long[] mEncryptionKeyIds = new long[0];
private String encryptionPassphrase = null; private String mEncryptionPassphrase = null;
private int symmetricEncryptionAlgorithm = 0; private int mSymmetricEncryptionAlgorithm = 0;
private long signatureKeyId = Id.key.none; private long mSignatureKeyId = Id.key.none;
private int signatureHashAlgorithm = 0; private int mSignatureHashAlgorithm = 0;
private boolean signatureForceV3 = false; private boolean mSignatureForceV3 = false;
private String signaturePassphrase = null; private String mSignaturePassphrase = null;
public Builder(Context context, InputData data, OutputStream outStream) { public Builder(Context context, InputData data, OutputStream outStream) {
this.context = context; this.mContext = context;
this.data = data; this.mData = data;
this.outStream = outStream; this.mOutStream = outStream;
} }
public Builder progress(ProgressDialogUpdater progress) { public Builder progress(ProgressDialogUpdater progress) {
this.progress = progress; this.mProgress = progress;
return this; return this;
} }
public Builder enableAsciiArmorOutput(boolean enableAsciiArmorOutput) { public Builder enableAsciiArmorOutput(boolean enableAsciiArmorOutput) {
this.enableAsciiArmorOutput = enableAsciiArmorOutput; this.mEnableAsciiArmorOutput = enableAsciiArmorOutput;
return this; return this;
} }
public Builder compressionId(int compressionId) { public Builder compressionId(int compressionId) {
this.compressionId = compressionId; this.mCompressionId = compressionId;
return this; return this;
} }
public Builder encryptionKeyIds(long[] encryptionKeyIds) { public Builder encryptionKeyIds(long[] encryptionKeyIds) {
this.encryptionKeyIds = encryptionKeyIds; this.mEncryptionKeyIds = encryptionKeyIds;
return this; return this;
} }
public Builder encryptionPassphrase(String encryptionPassphrase) { public Builder encryptionPassphrase(String encryptionPassphrase) {
this.encryptionPassphrase = encryptionPassphrase; this.mEncryptionPassphrase = encryptionPassphrase;
return this; return this;
} }
public Builder symmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) { public Builder symmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) {
this.symmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; this.mSymmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm;
return this; return this;
} }
public Builder signatureKeyId(long signatureKeyId) { public Builder signatureKeyId(long signatureKeyId) {
this.signatureKeyId = signatureKeyId; this.mSignatureKeyId = signatureKeyId;
return this; return this;
} }
public Builder signatureHashAlgorithm(int signatureHashAlgorithm) { public Builder signatureHashAlgorithm(int signatureHashAlgorithm) {
this.signatureHashAlgorithm = signatureHashAlgorithm; this.mSignatureHashAlgorithm = signatureHashAlgorithm;
return this; return this;
} }
public Builder signatureForceV3(boolean signatureForceV3) { public Builder signatureForceV3(boolean signatureForceV3) {
this.signatureForceV3 = signatureForceV3; this.mSignatureForceV3 = signatureForceV3;
return this; return this;
} }
public Builder signaturePassphrase(String signaturePassphrase) { public Builder signaturePassphrase(String signaturePassphrase) {
this.signaturePassphrase = signaturePassphrase; this.mSignaturePassphrase = signaturePassphrase;
return this; return this;
} }
@@ -176,14 +155,14 @@ public class PgpSignEncrypt {
} }
public void updateProgress(int message, int current, int total) { public void updateProgress(int message, int current, int total) {
if (progress != null) { if (mProgress != null) {
progress.setProgress(message, current, total); mProgress.setProgress(message, current, total);
} }
} }
public void updateProgress(int current, int total) { public void updateProgress(int current, int total) {
if (progress != null) { if (mProgress != null) {
progress.setProgress(current, total); mProgress.setProgress(current, total);
} }
} }
@@ -201,17 +180,17 @@ public class PgpSignEncrypt {
throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, throws IOException, PgpGeneralException, PGPException, NoSuchProviderException,
NoSuchAlgorithmException, SignatureException { NoSuchAlgorithmException, SignatureException {
boolean enableSignature = signatureKeyId != Id.key.none; boolean enableSignature = mSignatureKeyId != Id.key.none;
boolean enableEncryption = (encryptionKeyIds.length != 0 || encryptionPassphrase != null); boolean enableEncryption = (mEncryptionKeyIds.length != 0 || mEncryptionPassphrase != null);
boolean enableCompression = (enableEncryption && compressionId != Id.choice.compression.none); boolean enableCompression = (enableEncryption && mCompressionId != Id.choice.compression.none);
Log.d(Constants.TAG, "enableSignature:" + enableSignature Log.d(Constants.TAG, "enableSignature:" + enableSignature
+ "\nenableEncryption:" + enableEncryption + "\nenableEncryption:" + enableEncryption
+ "\nenableCompression:" + enableCompression + "\nenableCompression:" + enableCompression
+ "\nenableAsciiArmorOutput:" + enableAsciiArmorOutput); + "\nenableAsciiArmorOutput:" + mEnableAsciiArmorOutput);
int signatureType; int signatureType;
if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { if (mEnableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) {
// for sign-only ascii text // for sign-only ascii text
signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT;
} else { } else {
@@ -220,12 +199,12 @@ public class PgpSignEncrypt {
ArmoredOutputStream armorOut = null; ArmoredOutputStream armorOut = null;
OutputStream out; OutputStream out;
if (enableAsciiArmorOutput) { if (mEnableAsciiArmorOutput) {
armorOut = new ArmoredOutputStream(outStream); armorOut = new ArmoredOutputStream(mOutStream);
armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext));
out = armorOut; out = armorOut;
} else { } else {
out = outStream; out = mOutStream;
} }
/* Get keys for signature generation for later usage */ /* Get keys for signature generation for later usage */
@@ -233,25 +212,25 @@ public class PgpSignEncrypt {
PGPSecretKeyRing signingKeyRing = null; PGPSecretKeyRing signingKeyRing = null;
PGPPrivateKey signaturePrivateKey = null; PGPPrivateKey signaturePrivateKey = null;
if (enableSignature) { if (enableSignature) {
signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId);
signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
if (signingKey == null) { if (signingKey == null) {
throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
} }
if (signaturePassphrase == null) { if (mSignaturePassphrase == null) {
throw new PgpGeneralException( throw new PgpGeneralException(
context.getString(R.string.error_no_signature_passphrase)); mContext.getString(R.string.error_no_signature_passphrase));
} }
updateProgress(R.string.progress_extracting_signature_key, 0, 100); updateProgress(R.string.progress_extracting_signature_key, 0, 100);
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) { if (signaturePrivateKey == null) {
throw new PgpGeneralException( throw new PgpGeneralException(
context.getString(R.string.error_could_not_extract_private_key)); mContext.getString(R.string.error_could_not_extract_private_key));
} }
} }
updateProgress(R.string.progress_preparing_streams, 5, 100); updateProgress(R.string.progress_preparing_streams, 5, 100);
@@ -261,23 +240,23 @@ public class PgpSignEncrypt {
if (enableEncryption) { if (enableEncryption) {
// has Integrity packet enabled! // has Integrity packet enabled!
JcePGPDataEncryptorBuilder encryptorBuilder = JcePGPDataEncryptorBuilder encryptorBuilder =
new JcePGPDataEncryptorBuilder(symmetricEncryptionAlgorithm) new JcePGPDataEncryptorBuilder(mSymmetricEncryptionAlgorithm)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME)
.setWithIntegrityPacket(true); .setWithIntegrityPacket(true);
cPk = new PGPEncryptedDataGenerator(encryptorBuilder); cPk = new PGPEncryptedDataGenerator(encryptorBuilder);
if (encryptionKeyIds.length == 0) { if (mEncryptionKeyIds.length == 0) {
// Symmetric encryption // Symmetric encryption
Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption");
JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
new JcePBEKeyEncryptionMethodGenerator(encryptionPassphrase.toCharArray()); new JcePBEKeyEncryptionMethodGenerator(mEncryptionPassphrase.toCharArray());
cPk.addMethod(symmetricEncryptionGenerator); cPk.addMethod(symmetricEncryptionGenerator);
} else { } else {
// Asymmetric encryption // Asymmetric encryption
for (long id : encryptionKeyIds) { for (long id : mEncryptionKeyIds) {
PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(context, id); PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(mContext, id);
if (key != null) { if (key != null) {
JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator =
new JcePublicKeyKeyEncryptionMethodGenerator(key); new JcePublicKeyKeyEncryptionMethodGenerator(key);
@@ -295,10 +274,10 @@ public class PgpSignEncrypt {
// content signer based on signing key algorithm and chosen hash algorithm // content signer based on signing key algorithm and chosen hash algorithm
JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
signingKey.getPublicKey().getAlgorithm(), signatureHashAlgorithm) signingKey.getPublicKey().getAlgorithm(), mSignatureHashAlgorithm)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
if (signatureForceV3) { if (mSignatureForceV3) {
signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder);
signatureV3Generator.init(signatureType, signaturePrivateKey); signatureV3Generator.init(signatureType, signaturePrivateKey);
} else { } else {
@@ -322,14 +301,14 @@ public class PgpSignEncrypt {
encryptionOut = cPk.open(out, new byte[1 << 16]); encryptionOut = cPk.open(out, new byte[1 << 16]);
if (enableCompression) { if (enableCompression) {
compressGen = new PGPCompressedDataGenerator(compressionId); compressGen = new PGPCompressedDataGenerator(mCompressionId);
bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
} else { } else {
bcpgOut = new BCPGOutputStream(encryptionOut); bcpgOut = new BCPGOutputStream(encryptionOut);
} }
if (enableSignature) { if (enableSignature) {
if (signatureForceV3) { if (mSignatureForceV3) {
signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut);
} else { } else {
signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
@@ -345,13 +324,13 @@ public class PgpSignEncrypt {
long progress = 0; long progress = 0;
int n; int n;
byte[] buffer = new byte[1 << 16]; byte[] buffer = new byte[1 << 16];
InputStream in = data.getInputStream(); InputStream in = mData.getInputStream();
while ((n = in.read(buffer)) > 0) { while ((n = in.read(buffer)) > 0) {
pOut.write(buffer, 0, n); pOut.write(buffer, 0, n);
// update signature buffer if signature is requested // update signature buffer if signature is requested
if (enableSignature) { if (enableSignature) {
if (signatureForceV3) { if (mSignatureForceV3) {
signatureV3Generator.update(buffer, 0, n); signatureV3Generator.update(buffer, 0, n);
} else { } else {
signatureGenerator.update(buffer, 0, n); signatureGenerator.update(buffer, 0, n);
@@ -359,26 +338,26 @@ public class PgpSignEncrypt {
} }
progress += n; progress += n;
if (data.getSize() != 0) { if (mData.getSize() != 0) {
updateProgress((int) (20 + (95 - 20) * progress / data.getSize()), 100); updateProgress((int) (20 + (95 - 20) * progress / mData.getSize()), 100);
} }
} }
literalGen.close(); literalGen.close();
} else if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { } else if (mEnableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) {
/* sign-only of ascii text */ /* sign-only of ascii text */
updateProgress(R.string.progress_signing, 40, 100); updateProgress(R.string.progress_signing, 40, 100);
// write directly on armor output stream // write directly on armor output stream
armorOut.beginClearText(signatureHashAlgorithm); armorOut.beginClearText(mSignatureHashAlgorithm);
InputStream in = data.getInputStream(); InputStream in = mData.getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
final byte[] newline = "\r\n".getBytes("UTF-8"); final byte[] newline = "\r\n".getBytes("UTF-8");
if (signatureForceV3) { if (mSignatureForceV3) {
processLine(reader.readLine(), armorOut, signatureV3Generator); processLine(reader.readLine(), armorOut, signatureV3Generator);
} else { } else {
processLine(reader.readLine(), armorOut, signatureGenerator); processLine(reader.readLine(), armorOut, signatureGenerator);
@@ -395,7 +374,7 @@ public class PgpSignEncrypt {
armorOut.write(newline); armorOut.write(newline);
// update signature buffer with input line // update signature buffer with input line
if (signatureForceV3) { if (mSignatureForceV3) {
signatureV3Generator.update(newline); signatureV3Generator.update(newline);
processLine(line, armorOut, signatureV3Generator); processLine(line, armorOut, signatureV3Generator);
} else { } else {
@@ -415,7 +394,7 @@ public class PgpSignEncrypt {
if (enableSignature) { if (enableSignature) {
updateProgress(R.string.progress_generating_signature, 95, 100); updateProgress(R.string.progress_generating_signature, 95, 100);
if (signatureForceV3) { if (mSignatureForceV3) {
signatureV3Generator.generate().encode(pOut); signatureV3Generator.generate().encode(pOut);
} else { } else {
signatureGenerator.generate().encode(pOut); signatureGenerator.generate().encode(pOut);
@@ -432,12 +411,12 @@ public class PgpSignEncrypt {
encryptionOut.close(); encryptionOut.close();
} }
if (enableAsciiArmorOutput) { if (mEnableAsciiArmorOutput) {
armorOut.close(); armorOut.close();
} }
out.close(); out.close();
outStream.close(); mOutStream.close();
updateProgress(R.string.progress_done, 100, 100); updateProgress(R.string.progress_done, 100, 100);
} }
@@ -449,35 +428,36 @@ public class PgpSignEncrypt {
SignatureException { SignatureException {
OutputStream out; OutputStream out;
if (enableAsciiArmorOutput) { if (mEnableAsciiArmorOutput) {
// Ascii Armor (Radix-64) // Ascii Armor (Radix-64)
ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream); ArmoredOutputStream armorOut = new ArmoredOutputStream(mOutStream);
armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext));
out = armorOut; out = armorOut;
} else { } else {
out = outStream; out = mOutStream;
} }
if (signatureKeyId == 0) { if (mSignatureKeyId == 0) {
throw new PgpGeneralException(context.getString(R.string.error_no_signature_key)); throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_key));
} }
PGPSecretKeyRing signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); PGPSecretKeyRing signingKeyRing =
PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, mSignatureKeyId);
PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, mSignatureKeyId);
if (signingKey == null) { if (signingKey == null) {
throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed));
} }
if (signaturePassphrase == null) { if (mSignaturePassphrase == null) {
throw new PgpGeneralException(context.getString(R.string.error_no_signature_passphrase)); throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_passphrase));
} }
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(mSignaturePassphrase.toCharArray());
PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) { if (signaturePrivateKey == null) {
throw new PgpGeneralException( throw new PgpGeneralException(
context.getString(R.string.error_could_not_extract_private_key)); mContext.getString(R.string.error_could_not_extract_private_key));
} }
updateProgress(R.string.progress_preparing_streams, 0, 100); updateProgress(R.string.progress_preparing_streams, 0, 100);
@@ -490,12 +470,12 @@ public class PgpSignEncrypt {
// content signer based on signing key algorithm and chosen hash algorithm // content signer based on signing key algorithm and chosen hash algorithm
JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey
.getPublicKey().getAlgorithm(), signatureHashAlgorithm) .getPublicKey().getAlgorithm(), mSignatureHashAlgorithm)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator signatureGenerator = null; PGPSignatureGenerator signatureGenerator = null;
PGPV3SignatureGenerator signatureV3Generator = null; PGPV3SignatureGenerator signatureV3Generator = null;
if (signatureForceV3) { if (mSignatureForceV3) {
signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder);
signatureV3Generator.init(type, signaturePrivateKey); signatureV3Generator.init(type, signaturePrivateKey);
} else { } else {
@@ -510,7 +490,7 @@ public class PgpSignEncrypt {
updateProgress(R.string.progress_signing, 40, 100); updateProgress(R.string.progress_signing, 40, 100);
InputStream inStream = data.getInputStream(); InputStream inStream = mData.getInputStream();
// if (binary) { // if (binary) {
// byte[] buffer = new byte[1 << 16]; // byte[] buffer = new byte[1 << 16];
// int n = 0; // int n = 0;
@@ -527,7 +507,7 @@ public class PgpSignEncrypt {
String line; String line;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
if (signatureForceV3) { if (mSignatureForceV3) {
processLine(line, null, signatureV3Generator); processLine(line, null, signatureV3Generator);
signatureV3Generator.update(newline); signatureV3Generator.update(newline);
} else { } else {
@@ -538,13 +518,13 @@ public class PgpSignEncrypt {
// } // }
BCPGOutputStream bOut = new BCPGOutputStream(out); BCPGOutputStream bOut = new BCPGOutputStream(out);
if (signatureForceV3) { if (mSignatureForceV3) {
signatureV3Generator.generate().encode(bOut); signatureV3Generator.generate().encode(bOut);
} else { } else {
signatureGenerator.generate().encode(bOut); signatureGenerator.generate().encode(bOut);
} }
out.close(); out.close();
outStream.close(); mOutStream.close();
updateProgress(R.string.progress_done, 100, 100); updateProgress(R.string.progress_done, 100, 100);
} }

View File

@@ -1,33 +1,24 @@
/*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
*
* 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.pgp; package org.sufficientlysecure.keychain.pgp;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.spongycastle.asn1.DERObjectIdentifier; import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.x509.AuthorityKeyIdentifier; import org.spongycastle.asn1.x509.*;
import org.spongycastle.asn1.x509.BasicConstraints;
import org.spongycastle.asn1.x509.GeneralName;
import org.spongycastle.asn1.x509.GeneralNames;
import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
import org.spongycastle.asn1.x509.X509Extensions;
import org.spongycastle.asn1.x509.X509Name;
import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKey;
@@ -38,30 +29,38 @@ import org.spongycastle.x509.extension.SubjectKeyIdentifierStructure;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;
public class PgpToX509 { public class PgpToX509 {
public final static String DN_COMMON_PART_O = "OpenPGP to X.509 Bridge"; public static final String DN_COMMON_PART_O = "OpenPGP to X.509 Bridge";
public final static String DN_COMMON_PART_OU = "OpenPGP Keychain cert"; public static final String DN_COMMON_PART_OU = "OpenPGP Keychain cert";
/** /**
* Creates a self-signed certificate from a public and private key. The (critical) key-usage * Creates a self-signed certificate from a public and private key. The (critical) key-usage
* extension is set up with: digital signature, non-repudiation, key-encipherment, key-agreement * extension is set up with: digital signature, non-repudiation, key-encipherment, key-agreement
* and certificate-signing. The (non-critical) Netscape extension is set up with: SSL client and * and certificate-signing. The (non-critical) Netscape extension is set up with: SSL client and
* S/MIME. A URI subjectAltName may also be set up. * S/MIME. A URI subjectAltName may also be set up.
* *
* @param pubKey * @param pubKey public key
* public key * @param privKey private key
* @param privKey * @param subject subject (and issuer) DN for this certificate, RFC 2253 format preferred.
* private key * @param startDate date from which the certificate will be valid (defaults to current date and time
* @param subject * if null)
* subject (and issuer) DN for this certificate, RFC 2253 format preferred. * @param endDate date until which the certificate will be valid (defaults to current date and time
* @param startDate * if null) *
* date from which the certificate will be valid (defaults to current date and time * @param subjAltNameURI URI to be placed in subjectAltName
* if null)
* @param endDate
* date until which the certificate will be valid (defaults to current date and time
* if null) *
* @param subjAltNameURI
* URI to be placed in subjectAltName
* @return self-signed certificate * @return self-signed certificate
* @throws InvalidKeyException * @throws InvalidKeyException
* @throws SignatureException * @throws SignatureException
@@ -70,11 +69,10 @@ public class PgpToX509 {
* @throws NoSuchProviderException * @throws NoSuchProviderException
* @throws CertificateException * @throws CertificateException
* @throws Exception * @throws Exception
*
* @author Bruno Harbulot * @author Bruno Harbulot
*/ */
public static X509Certificate createSelfSignedCert(PublicKey pubKey, PrivateKey privKey, public static X509Certificate createSelfSignedCert(PublicKey pubKey, PrivateKey privKey,
X509Name subject, Date startDate, Date endDate, String subjAltNameURI) X509Name subject, Date startDate, Date endDate, String subjAltNameURI)
throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException,
SignatureException, CertificateException, NoSuchProviderException { SignatureException, CertificateException, NoSuchProviderException {
@@ -171,15 +169,12 @@ public class PgpToX509 {
/** /**
* Creates a self-signed certificate from a PGP Secret Key. * Creates a self-signed certificate from a PGP Secret Key.
* *
* @param pgpSecKey * @param pgpSecKey PGP Secret Key (from which one can extract the public and private keys and other
* PGP Secret Key (from which one can extract the public and private keys and other * attributes).
* attributes). * @param pgpPrivKey PGP Private Key corresponding to the Secret Key (password callbacks should be done
* @param pgpPrivKey * before calling this method)
* PGP Private Key corresponding to the Secret Key (password callbacks should be done * @param subjAltNameURI optional URI to embed in the subject alternative-name
* before calling this method)
* @param subjAltNameURI
* optional URI to embed in the subject alternative-name
* @return self-signed certificate * @return self-signed certificate
* @throws PGPException * @throws PGPException
* @throws NoSuchProviderException * @throws NoSuchProviderException
@@ -187,11 +182,10 @@ public class PgpToX509 {
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* @throws SignatureException * @throws SignatureException
* @throws CertificateException * @throws CertificateException
*
* @author Bruno Harbulot * @author Bruno Harbulot
*/ */
public static X509Certificate createSelfSignedCert(PGPSecretKey pgpSecKey, public static X509Certificate createSelfSignedCert(PGPSecretKey pgpSecKey,
PGPPrivateKey pgpPrivKey, String subjAltNameURI) throws PGPException, PGPPrivateKey pgpPrivKey, String subjAltNameURI) throws PGPException,
NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException,
SignatureException, CertificateException { SignatureException, CertificateException {
// get public key from secret key // get public key from secret key
@@ -213,7 +207,7 @@ public class PgpToX509 {
x509NameValues.add(DN_COMMON_PART_OU); x509NameValues.add(DN_COMMON_PART_OU);
for (@SuppressWarnings("unchecked") for (@SuppressWarnings("unchecked")
Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserIDs(); it.hasNext();) { Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserIDs(); it.hasNext(); ) {
Object attrib = it.next(); Object attrib = it.next();
x509NameOids.add(X509Name.CN); x509NameOids.add(X509Name.CN);
x509NameValues.add("CryptoCall"); x509NameValues.add("CryptoCall");
@@ -225,7 +219,7 @@ public class PgpToX509 {
*/ */
Log.d(Constants.TAG, "User attributes: "); Log.d(Constants.TAG, "User attributes: ");
for (@SuppressWarnings("unchecked") for (@SuppressWarnings("unchecked")
Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserAttributes(); it.hasNext();) { Iterator<Object> it = (Iterator<Object>) pgpSecKey.getUserAttributes(); it.hasNext(); ) {
Object attrib = it.next(); Object attrib = it.next();
Log.d(Constants.TAG, " - " + attrib + " -- " + attrib.getClass()); Log.d(Constants.TAG, " - " + attrib + " -- " + attrib.getClass());
} }
@@ -261,9 +255,8 @@ public class PgpToX509 {
* This is a password callback handler that will fill in a password automatically. Useful to * This is a password callback handler that will fill in a password automatically. Useful to
* configure passwords in advance, but should be used with caution depending on how much you * configure passwords in advance, but should be used with caution depending on how much you
* allow passwords to be stored within your application. * allow passwords to be stored within your application.
* *
* @author Bruno Harbulot. * @author Bruno Harbulot.
*
*/ */
public final static class PredefinedPasswordCallbackHandler implements CallbackHandler { public final static class PredefinedPasswordCallbackHandler implements CallbackHandler {

View File

@@ -1,3 +1,20 @@
/*
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
*
* 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.pgp.exception; package org.sufficientlysecure.keychain.pgp.exception;
public class NoAsymmetricEncryptionException extends Exception { public class NoAsymmetricEncryptionException extends Exception {
@@ -6,4 +23,4 @@ public class NoAsymmetricEncryptionException extends Exception {
public NoAsymmetricEncryptionException() { public NoAsymmetricEncryptionException() {
super(); super();
} }
} }

View File

@@ -1,3 +1,20 @@
/*
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
*
* 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.pgp.exception; package org.sufficientlysecure.keychain.pgp.exception;
public class PgpGeneralException extends Exception { public class PgpGeneralException extends Exception {
@@ -6,4 +23,4 @@ public class PgpGeneralException extends Exception {
public PgpGeneralException(String message) { public PgpGeneralException(String message) {
super(message); super(message);
} }
} }

View File

@@ -40,7 +40,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
public class KeychainServiceBlobProvider extends ContentProvider { public class KeychainServiceBlobProvider extends ContentProvider {
private static final String STORE_PATH = Constants.path.APP_DIR + "/ApgBlobs"; private static final String STORE_PATH = Constants.Path.APP_DIR + "/ApgBlobs";
private KeychainServiceBlobDatabase mBlobDatabase = null; private KeychainServiceBlobDatabase mBlobDatabase = null;

View File

@@ -351,7 +351,7 @@ public class DecryptActivity extends DrawerActivity {
} }
} else { } else {
Log.e(Constants.TAG, Log.e(Constants.TAG,
"Direct binary data without actual file in filesystem is not supported. Please use the Remote Service API!"); "Direct binary data without actual file in filesystem is not supported. Please use the Remote Service API!");
Toast.makeText(this, R.string.error_only_files_are_supported, Toast.LENGTH_LONG) Toast.makeText(this, R.string.error_only_files_are_supported, Toast.LENGTH_LONG)
.show(); .show();
// end activity // end activity
@@ -370,7 +370,7 @@ public class DecryptActivity extends DrawerActivity {
if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) { if (filename.endsWith(".asc") || filename.endsWith(".gpg") || filename.endsWith(".pgp")) {
filename = filename.substring(0, filename.length() - 4); filename = filename.substring(0, filename.length() - 4);
} }
mOutputFilename = Constants.path.APP_DIR + "/" + filename; mOutputFilename = Constants.Path.APP_DIR + "/" + filename;
} }
private void updateSource() { private void updateSource() {
@@ -519,7 +519,9 @@ public class DecryptActivity extends DrawerActivity {
AppMsg.STYLE_ALERT).show(); AppMsg.STYLE_ALERT).show();
} finally { } finally {
try { try {
if (inStream != null) inStream.close(); if (inStream != null) {
inStream.close();
}
} catch (Exception e) { } catch (Exception e) {
} }
} }

View File

@@ -221,15 +221,15 @@ public class DrawerActivity extends ActionBarActivity {
} }
private class NavigationDrawerAdapter extends ArrayAdapter<NavItem> { private class NavigationDrawerAdapter extends ArrayAdapter<NavItem> {
Context context; Context mContext;
int layoutResourceId; int mLayoutResourceId;
NavItem data[] = null; NavItem mData[] = null;
public NavigationDrawerAdapter(Context context, int layoutResourceId, NavItem[] data) { public NavigationDrawerAdapter(Context context, int layoutResourceId, NavItem[] data) {
super(context, layoutResourceId, data); super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId; this.mLayoutResourceId = layoutResourceId;
this.context = context; this.mContext = context;
this.data = data; this.mData = data;
} }
@Override @Override
@@ -238,21 +238,21 @@ public class DrawerActivity extends ActionBarActivity {
NavItemHolder holder = null; NavItemHolder holder = null;
if (row == null) { if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater(); LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false); row = inflater.inflate(mLayoutResourceId, parent, false);
holder = new NavItemHolder(); holder = new NavItemHolder();
holder.img = (FontAwesomeText) row.findViewById(R.id.drawer_item_icon); holder.mImg = (FontAwesomeText) row.findViewById(R.id.drawer_item_icon);
holder.txtTitle = (TextView) row.findViewById(R.id.drawer_item_text); holder.mTxtTitle = (TextView) row.findViewById(R.id.drawer_item_text);
row.setTag(holder); row.setTag(holder);
} else { } else {
holder = (NavItemHolder) row.getTag(); holder = (NavItemHolder) row.getTag();
} }
NavItem item = data[position]; NavItem item = mData[position];
holder.txtTitle.setText(item.title); holder.mTxtTitle.setText(item.title);
holder.img.setIcon(item.icon); holder.mImg.setIcon(item.icon);
return row; return row;
} }
@@ -260,8 +260,8 @@ public class DrawerActivity extends ActionBarActivity {
} }
static class NavItemHolder { static class NavItemHolder {
FontAwesomeText img; FontAwesomeText mImg;
TextView txtTitle; TextView mTxtTitle;
} }
} }

View File

@@ -98,7 +98,7 @@ public class EditKeyActivity extends ActionBarActivity {
Vector<String> mUserIds; Vector<String> mUserIds;
Vector<PGPSecretKey> mKeys; Vector<PGPSecretKey> mKeys;
Vector<Integer> mKeysUsages; Vector<Integer> mKeysUsages;
boolean masterCanSign = true; boolean mMasterCanSign = true;
ExportHelper mExportHelper; ExportHelper mExportHelper;
@@ -264,8 +264,8 @@ public class EditKeyActivity extends ActionBarActivity {
// get master key id using row id // get master key id using row id
long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
masterCanSign = ProviderHelper.getMasterKeyCanSign(this, mDataUri); mMasterCanSign = ProviderHelper.getMasterKeyCanSign(this, mDataUri);
finallyEdit(masterKeyId, masterCanSign); finallyEdit(masterKeyId, mMasterCanSign);
} }
} }
@@ -323,7 +323,7 @@ public class EditKeyActivity extends ActionBarActivity {
return true; return true;
case R.id.menu_key_edit_export_file: case R.id.menu_key_edit_export_file:
long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())}; long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.path.APP_DIR_FILE_SEC); mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC);
return true; return true;
case R.id.menu_key_edit_delete: { case R.id.menu_key_edit_delete: {
// Message is received after key is deleted // Message is received after key is deleted
@@ -432,12 +432,12 @@ public class EditKeyActivity extends ActionBarActivity {
LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container); LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container);
mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
mUserIdsView.setType(Id.type.user_id); mUserIdsView.setType(Id.type.user_id);
mUserIdsView.setCanEdit(masterCanSign); mUserIdsView.setCanEdit(mMasterCanSign);
mUserIdsView.setUserIds(mUserIds); mUserIdsView.setUserIds(mUserIds);
container.addView(mUserIdsView); container.addView(mUserIdsView);
mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false);
mKeysView.setType(Id.type.key); mKeysView.setType(Id.type.key);
mKeysView.setCanEdit(masterCanSign); mKeysView.setCanEdit(mMasterCanSign);
mKeysView.setKeys(mKeys, mKeysUsages); mKeysView.setKeys(mKeys, mKeysUsages);
container.addView(mKeysView); container.addView(mKeysView);
@@ -493,12 +493,13 @@ public class EditKeyActivity extends ActionBarActivity {
} }
String passphrase = null; String passphrase = null;
if (mIsPassPhraseSet) if (mIsPassPhraseSet) {
passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId); passphrase = PassphraseCacheService.getCachedPassphrase(this, masterKeyId);
else } else {
passphrase = ""; passphrase = "";
}
if (passphrase == null) { if (passphrase == null) {
showPassphraseDialog(masterKeyId, masterCanSign); showPassphraseDialog(masterKeyId, mMasterCanSign);
} else { } else {
mCurrentPassphrase = passphrase; mCurrentPassphrase = passphrase;
finallySaveClicked(); finallySaveClicked();
@@ -531,7 +532,7 @@ public class EditKeyActivity extends ActionBarActivity {
data.putSerializable(KeychainIntentService.SAVE_KEYRING_KEYS_EXPIRY_DATES, data.putSerializable(KeychainIntentService.SAVE_KEYRING_KEYS_EXPIRY_DATES,
getKeysExpiryDates(mKeysView)); getKeysExpiryDates(mKeysView));
data.putLong(KeychainIntentService.SAVE_KEYRING_MASTER_KEY_ID, getMasterKeyId()); data.putLong(KeychainIntentService.SAVE_KEYRING_MASTER_KEY_ID, getMasterKeyId());
data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, masterCanSign); data.putBoolean(KeychainIntentService.SAVE_KEYRING_CAN_SIGN, mMasterCanSign);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@@ -848,7 +848,7 @@ public class EncryptActivity extends DrawerActivity {
new Choice(Id.choice.compression.zlib, "ZLIB (" new Choice(Id.choice.compression.zlib, "ZLIB ("
+ getString(R.string.compression_fast) + ")"), + getString(R.string.compression_fast) + ")"),
new Choice(Id.choice.compression.bzip2, "BZIP2 (" new Choice(Id.choice.compression.bzip2, "BZIP2 ("
+ getString(R.string.compression_very_slow) + ")"),}; + getString(R.string.compression_very_slow) + ")"), };
ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(this, ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(this,
android.R.layout.simple_spinner_item, choices); android.R.layout.simple_spinner_item, choices);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

View File

@@ -76,4 +76,4 @@ public class HelpActivity extends ActionBarActivity {
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)), mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
HelpAboutFragment.class, null, (selectedTab == 4)); HelpAboutFragment.class, null, (selectedTab == 4));
} }
} }

View File

@@ -167,7 +167,8 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
query = "0x" + fingerprint; query = "0x" + fingerprint;
} }
} else { } else {
Log.e(Constants.TAG, "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or 'fingerprint' extra!"); Log.e(Constants.TAG,
"IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or 'fingerprint' extra!");
return; return;
} }
@@ -336,7 +337,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
// } else { // } else {
// status.putString( // status.putString(
// EXTRA_ERROR, // EXTRA_ERROR,
// "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key."); // "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key.");
// } // }
// } // }
// } catch (QueryException e) { // } catch (QueryException e) {
@@ -398,7 +399,8 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO) AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
.show(); .show();
if (bad > 0) { if (bad > 0) {
BadImportKeyDialogFragment badImportKeyDialogFragment = BadImportKeyDialogFragment.newInstance(bad); BadImportKeyDialogFragment badImportKeyDialogFragment =
BadImportKeyDialogFragment.newInstance(bad);
badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog"); badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog");
} }
} }

View File

@@ -58,8 +58,9 @@ public class ImportKeysClipboardFragment extends Fragment {
public void onClick(View v) { public void onClick(View v) {
CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity()); CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
String sendText = ""; String sendText = "";
if (clipboardText != null) if (clipboardText != null) {
sendText = clipboardText.toString(); sendText = clipboardText.toString();
}
mImportActivity.loadCallback(sendText.getBytes(), null, null, null); mImportActivity.loadCallback(sendText.getBytes(), null, null, null);
} }
}); });

View File

@@ -60,7 +60,7 @@ public class ImportKeysFileFragment extends Fragment {
// open .asc or .gpg files // open .asc or .gpg files
// setting it to text/plain prevents Cynaogenmod's file manager from selecting asc // setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
// or gpg types! // or gpg types!
FileHelper.openFile(ImportKeysFileFragment.this, Constants.path.APP_DIR + "/", FileHelper.openFile(ImportKeysFileFragment.this, Constants.Path.APP_DIR + "/",
"*/*", Id.request.filename); "*/*", Id.request.filename);
} }
}); });

View File

@@ -178,7 +178,8 @@ public class ImportKeysListFragment extends ListFragment implements
} }
@Override @Override
public Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> onCreateLoader(int id, Bundle args) { public Loader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>>
onCreateLoader(int id, Bundle args) {
switch (id) { switch (id) {
case LOADER_ID_BYTES: { case LOADER_ID_BYTES: {
InputData inputData = getInputData(mKeyBytes, mDataUri); InputData inputData = getInputData(mKeyBytes, mDataUri);

View File

@@ -94,7 +94,8 @@ public class ImportKeysServerFragment extends Fragment {
search(query, keyServer); search(query, keyServer);
// close keyboard after pressing search // close keyboard after pressing search
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm =
(InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mQueryEditText.getWindowToken(), 0); imm.hideSoftInputFromWindow(mQueryEditText.getWindowToken(), 0);
} }
}); });
@@ -108,7 +109,6 @@ public class ImportKeysServerFragment extends Fragment {
search(query, keyServer); search(query, keyServer);
// Don't return true to let the keyboard close itself after pressing search // Don't return true to let the keyboard close itself after pressing search
// http://stackoverflow.com/questions/2342620/how-to-hide-keyboard-after-typing-in-edittext-in-android
return false; return false;
} }
return false; return false;

View File

@@ -59,7 +59,7 @@ public class KeyListActivity extends DrawerActivity {
return true; return true;
case R.id.menu_key_list_export: case R.id.menu_key_list_export:
// TODO fix this for unified keylist // TODO fix this for unified keylist
mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB); mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB);
return true; return true;
case R.id.menu_key_list_create: case R.id.menu_key_list_create:
@@ -71,9 +71,9 @@ public class KeyListActivity extends DrawerActivity {
return true; return true;
case R.id.menu_key_list_secret_export: case R.id.menu_key_list_secret_export:
mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.path.APP_DIR_FILE_SEC); mExportHelper.showExportKeysDialog(null, Id.type.secret_key, Constants.Path.APP_DIR_FILE_SEC);
return true;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }

View File

@@ -36,8 +36,8 @@ import android.text.TextUtils;
import android.view.*; import android.view.*;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.*; import android.widget.*;
import android.widget.AbsListView.MultiChoiceModeListener;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
@@ -63,7 +63,8 @@ import java.util.HashMap;
* Public key list with sticky list headers. It does _not_ extend ListFragment because it uses * Public key list with sticky list headers. It does _not_ extend ListFragment because it uses
* StickyListHeaders library which does not extend upon ListView. * StickyListHeaders library which does not extend upon ListView.
*/ */
public class KeyListFragment extends Fragment implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener, public class KeyListFragment extends Fragment
implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener,
LoaderManager.LoaderCallbacks<Cursor> { LoaderManager.LoaderCallbacks<Cursor> {
private KeyListAdapter mAdapter; private KeyListAdapter mAdapter;
@@ -185,7 +186,10 @@ public class KeyListFragment extends Fragment implements SearchView.OnQueryTextL
// todo: public/secret needs to be handled differently here // todo: public/secret needs to be handled differently here
ids = mStickyList.getWrappedList().getCheckedItemIds(); ids = mStickyList.getWrappedList().getCheckedItemIds();
ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB); mExportHelper
.showExportKeysDialog(ids,
Id.type.public_key,
Constants.Path.APP_DIR_FILE_PUB);
break; break;
} }
case R.id.menu_key_list_multi_select_all: { case R.id.menu_key_list_multi_select_all: {
@@ -310,7 +314,10 @@ public class KeyListFragment extends Fragment implements SearchView.OnQueryTextL
} else { } else {
viewIntent = new Intent(getActivity(), ViewKeyActivityJB.class); viewIntent = new Intent(getActivity(), ViewKeyActivityJB.class);
} }
viewIntent.setData(KeychainContract.KeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long.toString(mAdapter.getMasterKeyId(position)))); viewIntent.setData(
KeychainContract
.KeyRings.buildPublicKeyRingsByMasterKeyIdUri(
Long.toString(mAdapter.getMasterKeyId(position))));
startActivity(viewIntent); startActivity(viewIntent);
} }
@@ -347,8 +354,12 @@ public class KeyListFragment extends Fragment implements SearchView.OnQueryTextL
for (String userId : notDeleted) { for (String userId : notDeleted) {
notDeletedMsg += userId + "\n"; notDeletedMsg += userId + "\n";
} }
Toast.makeText(getActivity(), getString(R.string.error_can_not_delete_contacts, notDeletedMsg) Toast.makeText(getActivity(),
+ getResources().getQuantityString(R.plurals.error_can_not_delete_info, notDeleted.size()), getString(R.string.error_can_not_delete_contacts, notDeletedMsg)
+ getResources()
.getQuantityString(
R.plurals.error_can_not_delete_info,
notDeleted.size()),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
mode.finish(); mode.finish();
@@ -507,7 +518,9 @@ public class KeyListFragment extends Fragment implements SearchView.OnQueryTextL
button.setOnClickListener(new OnClickListener() { button.setOnClickListener(new OnClickListener() {
public void onClick(View view) { public void onClick(View view) {
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
editIntent.setData(KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(id))); editIntent.setData(
KeychainContract.KeyRings
.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(id)));
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
startActivityForResult(editIntent, 0); startActivityForResult(editIntent, 0);
} }
@@ -582,7 +595,8 @@ public class KeyListFragment extends Fragment implements SearchView.OnQueryTextL
String userId = mCursor.getString(KeyListFragment.INDEX_USER_ID); String userId = mCursor.getString(KeyListFragment.INDEX_USER_ID);
String headerText = convertView.getResources().getString(R.string.user_id_no_name); String headerText = convertView.getResources().getString(R.string.user_id_no_name);
if (userId != null && userId.length() > 0) { if (userId != null && userId.length() > 0) {
headerText = "" + mCursor.getString(KeyListFragment.INDEX_USER_ID).subSequence(0, 1).charAt(0); headerText = "" +
mCursor.getString(KeyListFragment.INDEX_USER_ID).subSequence(0, 1).charAt(0);
} }
holder.mText.setText(headerText); holder.mText.setText(headerText);
holder.mCount.setVisibility(View.GONE); holder.mCount.setVisibility(View.GONE);
@@ -605,9 +619,9 @@ public class KeyListFragment extends Fragment implements SearchView.OnQueryTextL
} }
// early breakout: all secret keys are assigned id 0 // early breakout: all secret keys are assigned id 0
if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) {
return 1L; return 1L;
}
// otherwise, return the first character of the name as ID // otherwise, return the first character of the name as ID
String userId = mCursor.getString(KeyListFragment.INDEX_USER_ID); String userId = mCursor.getString(KeyListFragment.INDEX_USER_ID);
if (userId != null && userId.length() > 0) { if (userId != null && userId.length() > 0) {

View File

@@ -34,8 +34,8 @@ import java.util.List;
@SuppressLint("NewApi") @SuppressLint("NewApi")
public class PreferencesActivity extends PreferenceActivity { public class PreferencesActivity extends PreferenceActivity {
public final static String ACTION_PREFS_GEN = "org.sufficientlysecure.keychain.ui.PREFS_GEN"; public static final String ACTION_PREFS_GEN = "org.sufficientlysecure.keychain.ui.PREFS_GEN";
public final static String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV"; public static final String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
private PreferenceScreen mKeyServerPreference = null; private PreferenceScreen mKeyServerPreference = null;
private static Preferences mPreferences; private static Preferences mPreferences;
@@ -56,9 +56,9 @@ public class PreferencesActivity extends PreferenceActivity {
addPreferencesFromResource(R.xml.gen_preferences); addPreferencesFromResource(R.xml.gen_preferences);
initializePassPassPhraceCacheTtl( initializePassPassPhraceCacheTtl(
(IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL)); (IntegerListPreference) findPreference(Constants.Pref.PASS_PHRASE_CACHE_TTL));
mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS); mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
String servers[] = mPreferences.getKeyServers(); String servers[] = mPreferences.getKeyServers();
mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers, mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
servers.length, servers.length)); servers.length, servers.length));
@@ -78,35 +78,37 @@ public class PreferencesActivity extends PreferenceActivity {
addPreferencesFromResource(R.xml.adv_preferences); addPreferencesFromResource(R.xml.adv_preferences);
initializeEncryptionAlgorithm( initializeEncryptionAlgorithm(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM)); (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
int[] valueIds = new int[]{Id.choice.compression.none, Id.choice.compression.zip, int[] valueIds = new int[]{Id.choice.compression.none, Id.choice.compression.zip,
Id.choice.compression.zlib, Id.choice.compression.bzip2,}; Id.choice.compression.zlib, Id.choice.compression.bzip2, };
String[] entries = new String[]{ String[] entries = new String[]{
getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")", getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
"ZIP (" + getString(R.string.compression_fast) + ")", "ZIP (" + getString(R.string.compression_fast) + ")",
"ZLIB (" + getString(R.string.compression_fast) + ")", "ZLIB (" + getString(R.string.compression_fast) + ")",
"BZIP2 (" + getString(R.string.compression_very_slow) + ")",}; "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
String[] values = new String[valueIds.length]; String[] values = new String[valueIds.length];
for (int i = 0; i < values.length; ++i) { for (int i = 0; i < values.length; ++i) {
values[i] = "" + valueIds[i]; values[i] = "" + valueIds[i];
} }
initializeHashAlgorithm( initializeHashAlgorithm(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM), (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM),
valueIds, entries, values); valueIds, entries, values);
initializeMessageCompression( initializeMessageCompression(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION), (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
valueIds, entries, values); valueIds, entries, values);
initializeFileCompression( initializeFileCompression(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION), (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
entries, values); entries, values);
initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR)); initializeAsciiArmour(
(CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOUR));
initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES)); initializeForceV3Signatures(
(CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES));
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
// Load the legacy preferences headers // Load the legacy preferences headers
@@ -158,9 +160,9 @@ public class PreferencesActivity extends PreferenceActivity {
addPreferencesFromResource(R.xml.gen_preferences); addPreferencesFromResource(R.xml.gen_preferences);
initializePassPassPhraceCacheTtl( initializePassPassPhraceCacheTtl(
(IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL)); (IntegerListPreference) findPreference(Constants.Pref.PASS_PHRASE_CACHE_TTL));
mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS); mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
String servers[] = mPreferences.getKeyServers(); String servers[] = mPreferences.getKeyServers();
mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers, mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
servers.length, servers.length)); servers.length, servers.length));
@@ -213,35 +215,37 @@ public class PreferencesActivity extends PreferenceActivity {
addPreferencesFromResource(R.xml.adv_preferences); addPreferencesFromResource(R.xml.adv_preferences);
initializeEncryptionAlgorithm( initializeEncryptionAlgorithm(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM)); (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_ENCRYPTION_ALGORITHM));
int[] valueIds = new int[]{Id.choice.compression.none, Id.choice.compression.zip, int[] valueIds = new int[]{Id.choice.compression.none, Id.choice.compression.zip,
Id.choice.compression.zlib, Id.choice.compression.bzip2,}; Id.choice.compression.zlib, Id.choice.compression.bzip2, };
String[] entries = new String[]{ String[] entries = new String[]{
getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")", getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
"ZIP (" + getString(R.string.compression_fast) + ")", "ZIP (" + getString(R.string.compression_fast) + ")",
"ZLIB (" + getString(R.string.compression_fast) + ")", "ZLIB (" + getString(R.string.compression_fast) + ")",
"BZIP2 (" + getString(R.string.compression_very_slow) + ")",}; "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
String[] values = new String[valueIds.length]; String[] values = new String[valueIds.length];
for (int i = 0; i < values.length; ++i) { for (int i = 0; i < values.length; ++i) {
values[i] = "" + valueIds[i]; values[i] = "" + valueIds[i];
} }
initializeHashAlgorithm( initializeHashAlgorithm(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM), (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_HASH_ALGORITHM),
valueIds, entries, values); valueIds, entries, values);
initializeMessageCompression( initializeMessageCompression(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION), (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_MESSAGE_COMPRESSION),
valueIds, entries, values); valueIds, entries, values);
initializeFileCompression( initializeFileCompression(
(IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION), (IntegerListPreference) findPreference(Constants.Pref.DEFAULT_FILE_COMPRESSION),
entries, values); entries, values);
initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR)); initializeAsciiArmour(
(CheckBoxPreference) findPreference(Constants.Pref.DEFAULT_ASCII_ARMOUR));
initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES)); initializeForceV3Signatures(
(CheckBoxPreference) findPreference(Constants.Pref.FORCE_V3_SIGNATURES));
} }
} }
@@ -269,9 +273,9 @@ public class PreferencesActivity extends PreferenceActivity {
int valueIds[] = {PGPEncryptedData.AES_128, PGPEncryptedData.AES_192, int valueIds[] = {PGPEncryptedData.AES_128, PGPEncryptedData.AES_192,
PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH, PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH,
PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES, PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES,
PGPEncryptedData.IDEA,}; PGPEncryptedData.IDEA, };
String entries[] = {"AES-128", "AES-192", "AES-256", "Blowfish", "Twofish", "CAST5", String entries[] = {"AES-128", "AES-192", "AES-256", "Blowfish", "Twofish", "CAST5",
"DES", "Triple DES", "IDEA",}; "DES", "Triple DES", "IDEA", };
String values[] = new String[valueIds.length]; String values[] = new String[valueIds.length];
for (int i = 0; i < values.length; ++i) { for (int i = 0; i < values.length; ++i) {
values[i] = "" + valueIds[i]; values[i] = "" + valueIds[i];
@@ -296,9 +300,9 @@ public class PreferencesActivity extends PreferenceActivity {
(final IntegerListPreference mHashAlgorithm, int[] valueIds, String[] entries, String[] values) { (final IntegerListPreference mHashAlgorithm, int[] valueIds, String[] entries, String[] values) {
valueIds = new int[]{HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160, valueIds = new int[]{HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160,
HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512,}; HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, };
entries = new String[]{"MD5", "RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384", entries = new String[]{"MD5", "RIPEMD-160", "SHA-1", "SHA-224", "SHA-256", "SHA-384",
"SHA-512",}; "SHA-512", };
values = new String[valueIds.length]; values = new String[valueIds.length];
for (int i = 0; i < values.length; ++i) { for (int i = 0; i < values.length; ++i) {
values[i] = "" + valueIds[i]; values[i] = "" + valueIds[i];
@@ -317,8 +321,9 @@ public class PreferencesActivity extends PreferenceActivity {
}); });
} }
private static void initializeMessageCompression private static void initializeMessageCompression(
(final IntegerListPreference mMessageCompression, int[] valueIds, String[] entries, String[] values) { final IntegerListPreference mMessageCompression,
int[] valueIds, String[] entries, String[] values) {
mMessageCompression.setEntries(entries); mMessageCompression.setEntries(entries);
mMessageCompression.setEntryValues(values); mMessageCompression.setEntryValues(values);
mMessageCompression.setValue("" + mPreferences.getDefaultMessageCompression()); mMessageCompression.setValue("" + mPreferences.getDefaultMessageCompression());
@@ -373,4 +378,4 @@ public class PreferencesActivity extends PreferenceActivity {
} }
}); });
} }
} }

View File

@@ -38,7 +38,7 @@ public class SelectPublicKeyActivity extends ActionBarActivity {
SelectPublicKeyFragment mSelectFragment; SelectPublicKeyFragment mSelectFragment;
long selectedMasterKeyIds[]; long mSelectedMasterKeyIds[];
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -79,7 +79,7 @@ public class SelectPublicKeyActivity extends ActionBarActivity {
} }
// Create an instance of the fragment // Create an instance of the fragment
mSelectFragment = SelectPublicKeyFragment.newInstance(selectedMasterKeyIds); mSelectFragment = SelectPublicKeyFragment.newInstance(mSelectedMasterKeyIds);
// Add the fragment to the 'fragment_container' FrameLayout // Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction() getSupportFragmentManager().beginTransaction()
@@ -124,7 +124,7 @@ public class SelectPublicKeyActivity extends ActionBarActivity {
// } // }
// preselected master keys // preselected master keys
selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS); mSelectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
} }
private void cancelClicked() { private void cancelClicked() {

View File

@@ -132,7 +132,8 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
mSearchView = new EditText(context); mSearchView = new EditText(context);
mSearchView.setId(SEARCH_ID); mSearchView.setId(SEARCH_ID);
mSearchView.setHint(R.string.menu_search); mSearchView.setHint(R.string.menu_search);
mSearchView.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_action_search), null, null, null); mSearchView.setCompoundDrawablesWithIntrinsicBounds(
getResources().getDrawable(R.drawable.ic_action_search), null, null, null);
linearLayout.addView(mSearchView, new FrameLayout.LayoutParams( linearLayout.addView(mSearchView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
@@ -270,7 +271,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements T
+ Keys.CAN_ENCRYPT + " = '1' AND valid_keys." + Keys.CREATION + " <= '" + Keys.CAN_ENCRYPT + " = '1' AND valid_keys." + Keys.CREATION + " <= '"
+ now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys."
+ Keys.EXPIRY + " >= '" + now + "')) AS " + Keys.EXPIRY + " >= '" + now + "')) AS "
+ SelectKeyCursorAdapter.PROJECTION_ROW_VALID,}; + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
String inMasterKeyList = null; String inMasterKeyList = null;
if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) { if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) {

View File

@@ -141,7 +141,7 @@ public class SelectSecretKeyFragment extends ListFragment implements
+ Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_SIGN + Keys.IS_REVOKED + " = '0' AND valid_keys." + Keys.CAN_SIGN
+ " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND " + " = '1' AND valid_keys." + Keys.CREATION + " <= '" + now + "' AND "
+ "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys." + Keys.EXPIRY
+ " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID,}; + " >= '" + now + "')) AS " + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
String orderBy = UserIds.USER_ID + " ASC"; String orderBy = UserIds.USER_ID + " ASC";

View File

@@ -101,7 +101,10 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
mKeyUserIdRest.setVisibility(View.GONE); mKeyUserIdRest.setVisibility(View.GONE);
} }
} else { } else {
mKeyMasterKeyIdHex.setText(getActivity().getResources().getString(R.string.no_keys_added_or_updated) + " for master id: " + secretKeyId); mKeyMasterKeyIdHex.setText(
getActivity().getResources()
.getString(R.string.no_keys_added_or_updated)
+ " for master id: " + secretKeyId);
mKeyUserId.setVisibility(View.GONE); mKeyUserId.setVisibility(View.GONE);
mKeyUserIdRest.setVisibility(View.GONE); mKeyUserIdRest.setVisibility(View.GONE);
} }

View File

@@ -125,7 +125,7 @@ public class ViewKeyActivity extends ActionBarActivity {
return true; return true;
case R.id.menu_key_view_export_file: case R.id.menu_key_view_export_file:
long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())}; long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB); mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.Path.APP_DIR_FILE_PUB);
return true; return true;
case R.id.menu_key_view_share_default_fingerprint: case R.id.menu_key_view_share_default_fingerprint:
shareKey(mDataUri, true); shareKey(mDataUri, true);
@@ -241,7 +241,8 @@ public class ViewKeyActivity extends ActionBarActivity {
// we delete only this key, so MESSAGE_NOT_DELETED will solely contain this key // we delete only this key, so MESSAGE_NOT_DELETED will solely contain this key
Toast.makeText(ViewKeyActivity.this, Toast.makeText(ViewKeyActivity.this,
getString(R.string.error_can_not_delete_contact) getString(R.string.error_can_not_delete_contact)
+ getResources().getQuantityString(R.plurals.error_can_not_delete_info, 1), + getResources()
.getQuantityString(R.plurals.error_can_not_delete_info, 1),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
} else { } else {
setResult(RESULT_CANCELED); setResult(RESULT_CANCELED);

View File

@@ -87,4 +87,4 @@ public class ViewKeyCertsFragment extends Fragment {
startActivity(signIntent); startActivity(signIntent);
} }
} }

View File

@@ -136,7 +136,10 @@ public class ViewKeyMainFragment extends Fragment implements
mActionEdit.setOnClickListener(new View.OnClickListener() { mActionEdit.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) { public void onClick(View view) {
Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); Intent editIntent = new Intent(getActivity(), EditKeyActivity.class);
editIntent.setData(KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId))); editIntent.setData(
KeychainContract
.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(
Long.toString(masterKeyId)));
editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY);
startActivityForResult(editIntent, 0); startActivityForResult(editIntent, 0);
} }
@@ -169,21 +172,28 @@ public class ViewKeyMainFragment extends Fragment implements
getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this); getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
} }
static final String[] KEYRING_PROJECTION = new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID, static final String[] KEYRING_PROJECTION =
new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.UserIds.USER_ID}; KeychainContract.UserIds.USER_ID};
static final int KEYRING_INDEX_ID = 0; static final int KEYRING_INDEX_ID = 0;
static final int KEYRING_INDEX_MASTER_KEY_ID = 1; static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
static final int KEYRING_INDEX_USER_ID = 2; static final int KEYRING_INDEX_USER_ID = 2;
static final String[] USER_IDS_PROJECTION = new String[]{KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID, static final String[] USER_IDS_PROJECTION =
KeychainContract.UserIds.RANK,}; new String[]{KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID,
KeychainContract.UserIds.RANK, };
// not the main user id // not the main user id
static final String USER_IDS_SELECTION = KeychainContract.UserIds.RANK + " > 0 "; static final String USER_IDS_SELECTION = KeychainContract.UserIds.RANK + " > 0 ";
static final String USER_IDS_SORT_ORDER = KeychainContract.UserIds.USER_ID + " COLLATE LOCALIZED ASC"; static final String USER_IDS_SORT_ORDER =
KeychainContract.UserIds.USER_ID + " COLLATE LOCALIZED ASC";
static final String[] KEYS_PROJECTION = new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID, static final String[] KEYS_PROJECTION =
KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN, new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
KeychainContract.Keys.CAN_ENCRYPT, KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT}; KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM,
KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY,
KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT,
KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY,
KeychainContract.Keys.FINGERPRINT};
static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC"; static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC";
static final int KEYS_INDEX_ID = 0; static final int KEYS_INDEX_ID = 0;
static final int KEYS_INDEX_KEY_ID = 1; static final int KEYS_INDEX_KEY_ID = 1;
@@ -266,7 +276,8 @@ public class ViewKeyMainFragment extends Fragment implements
} else { } else {
Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000); Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
mCreation.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format( mCreation.setText(
DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
creationDate)); creationDate));
} }
@@ -276,7 +287,8 @@ public class ViewKeyMainFragment extends Fragment implements
} else { } else {
Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000); Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
mExpiry.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format( mExpiry.setText(
DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
expiryDate)); expiryDate));
} }
@@ -397,5 +409,4 @@ public class ViewKeyMainFragment extends Fragment implements
startActivity(signIntent); startActivity(signIntent);
} }
}
}

View File

@@ -27,20 +27,20 @@ package org.sufficientlysecure.keychain.ui.adapter;
*/ */
public class AsyncTaskResultWrapper<T> { public class AsyncTaskResultWrapper<T> {
private final T result; private final T mResult;
private final Exception error; private final Exception mError;
public AsyncTaskResultWrapper(T result, Exception error) { public AsyncTaskResultWrapper(T result, Exception error) {
this.result = result; this.mResult = result;
this.error = error; this.mError = error;
} }
public T getResult() { public T getResult() {
return result; return mResult;
} }
public Exception getError() { public Exception getError() {
return error; return mError;
} }
} }

View File

@@ -40,15 +40,15 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
protected LayoutInflater mInflater; protected LayoutInflater mInflater;
protected Activity mActivity; protected Activity mActivity;
protected List<ImportKeysListEntry> data; protected List<ImportKeysListEntry> mData;
static class ViewHolder { static class ViewHolder {
private TextView mainUserId; private TextView mMainUserId;
private TextView mainUserIdRest; private TextView mMainUserIdRest;
private TextView keyId; private TextView mKeyId;
private TextView fingerprint; private TextView mFingerprint;
private TextView algorithm; private TextView mAlgorithm;
private TextView status; private TextView mStatus;
} }
@@ -62,7 +62,7 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
public void setData(List<ImportKeysListEntry> data) { public void setData(List<ImportKeysListEntry> data) {
clear(); clear();
if (data != null) { if (data != null) {
this.data = data; this.mData = data;
// add data to extended ArrayAdapter // add data to extended ArrayAdapter
if (Build.VERSION.SDK_INT >= 11) { if (Build.VERSION.SDK_INT >= 11) {
@@ -76,14 +76,15 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
} }
public List<ImportKeysListEntry> getData() { public List<ImportKeysListEntry> getData() {
return data; return mData;
} }
public ArrayList<ImportKeysListEntry> getSelectedData() { public ArrayList<ImportKeysListEntry> getSelectedData() {
ArrayList<ImportKeysListEntry> selectedData = new ArrayList<ImportKeysListEntry>(); ArrayList<ImportKeysListEntry> selectedData = new ArrayList<ImportKeysListEntry>();
for (ImportKeysListEntry entry : data) { for (ImportKeysListEntry entry : mData) {
if (entry.isSelected()) if (entry.isSelected()) {
selectedData.add(entry); selectedData.add(entry);
}
} }
return selectedData; return selectedData;
} }
@@ -94,17 +95,17 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
} }
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
ImportKeysListEntry entry = data.get(position); ImportKeysListEntry entry = mData.get(position);
ViewHolder holder; ViewHolder holder;
if (convertView == null) { if (convertView == null) {
holder = new ViewHolder(); holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.import_keys_list_entry, null); convertView = mInflater.inflate(R.layout.import_keys_list_entry, null);
holder.mainUserId = (TextView) convertView.findViewById(R.id.mainUserId); holder.mMainUserId = (TextView) convertView.findViewById(R.id.mainUserId);
holder.mainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest); holder.mMainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest);
holder.keyId = (TextView) convertView.findViewById(R.id.keyId); holder.mKeyId = (TextView) convertView.findViewById(R.id.keyId);
holder.fingerprint = (TextView) convertView.findViewById(R.id.fingerprint); holder.mFingerprint = (TextView) convertView.findViewById(R.id.fingerprint);
holder.algorithm = (TextView) convertView.findViewById(R.id.algorithm); holder.mAlgorithm = (TextView) convertView.findViewById(R.id.algorithm);
holder.status = (TextView) convertView.findViewById(R.id.status); holder.mStatus = (TextView) convertView.findViewById(R.id.status);
convertView.setTag(holder); convertView.setTag(holder);
} else { } else {
holder = (ViewHolder) convertView.getTag(); holder = (ViewHolder) convertView.getTag();
@@ -118,36 +119,36 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
// show red user id if it is a secret key // show red user id if it is a secret key
if (entry.secretKey) { if (entry.secretKey) {
userIdSplit[0] = mActivity.getString(R.string.secret_key) + " " + userIdSplit[0]; userIdSplit[0] = mActivity.getString(R.string.secret_key) + " " + userIdSplit[0];
holder.mainUserId.setTextColor(Color.RED); holder.mMainUserId.setTextColor(Color.RED);
} }
holder.mainUserId.setText(userIdSplit[0]); holder.mMainUserId.setText(userIdSplit[0]);
} else { } else {
holder.mainUserId.setText(R.string.user_id_no_name); holder.mMainUserId.setText(R.string.user_id_no_name);
} }
// email // email
if (userIdSplit[1] != null) { if (userIdSplit[1] != null) {
holder.mainUserIdRest.setText(userIdSplit[1]); holder.mMainUserIdRest.setText(userIdSplit[1]);
holder.mainUserIdRest.setVisibility(View.VISIBLE); holder.mMainUserIdRest.setVisibility(View.VISIBLE);
} else { } else {
holder.mainUserIdRest.setVisibility(View.GONE); holder.mMainUserIdRest.setVisibility(View.GONE);
} }
holder.keyId.setText(entry.hexKeyId); holder.mKeyId.setText(entry.hexKeyId);
if (entry.fingerPrint != null) { if (entry.fingerPrint != null) {
holder.fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint); holder.mFingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
holder.fingerprint.setVisibility(View.VISIBLE); holder.mFingerprint.setVisibility(View.VISIBLE);
} else { } else {
holder.fingerprint.setVisibility(View.GONE); holder.mFingerprint.setVisibility(View.GONE);
} }
holder.algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm); holder.mAlgorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
if (entry.revoked) { if (entry.revoked) {
holder.status.setText(R.string.revoked); holder.mStatus.setText(R.string.revoked);
} else { } else {
holder.status.setVisibility(View.GONE); holder.mStatus.setVisibility(View.GONE);
} }
LinearLayout ll = (LinearLayout) convertView.findViewById(R.id.list); LinearLayout ll = (LinearLayout) convertView.findViewById(R.id.list);

View File

@@ -45,9 +45,9 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
public String algorithm; public String algorithm;
public boolean secretKey; public boolean secretKey;
private boolean selected; private boolean mSelected;
private byte[] bytes = new byte[]{}; private byte[] mBytes = new byte[]{};
public ImportKeysListEntry(ImportKeysListEntry b) { public ImportKeysListEntry(ImportKeysListEntry b) {
this.userIds = b.userIds; this.userIds = b.userIds;
@@ -59,8 +59,8 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
this.bitStrength = b.bitStrength; this.bitStrength = b.bitStrength;
this.algorithm = b.algorithm; this.algorithm = b.algorithm;
this.secretKey = b.secretKey; this.secretKey = b.secretKey;
this.selected = b.selected; this.mSelected = b.mSelected;
this.bytes = b.bytes; this.mBytes = b.mBytes;
} }
public int describeContents() { public int describeContents() {
@@ -78,9 +78,9 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
dest.writeInt(bitStrength); dest.writeInt(bitStrength);
dest.writeString(algorithm); dest.writeString(algorithm);
dest.writeByte((byte) (secretKey ? 1 : 0)); dest.writeByte((byte) (secretKey ? 1 : 0));
dest.writeByte((byte) (selected ? 1 : 0)); dest.writeByte((byte) (mSelected ? 1 : 0));
dest.writeInt(bytes.length); dest.writeInt(mBytes.length);
dest.writeByteArray(bytes); dest.writeByteArray(mBytes);
} }
public static final Creator<ImportKeysListEntry> CREATOR = new Creator<ImportKeysListEntry>() { public static final Creator<ImportKeysListEntry> CREATOR = new Creator<ImportKeysListEntry>() {
@@ -96,9 +96,9 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
vr.bitStrength = source.readInt(); vr.bitStrength = source.readInt();
vr.algorithm = source.readString(); vr.algorithm = source.readString();
vr.secretKey = source.readByte() == 1; vr.secretKey = source.readByte() == 1;
vr.selected = source.readByte() == 1; vr.mSelected = source.readByte() == 1;
vr.bytes = new byte[source.readInt()]; vr.mBytes = new byte[source.readInt()];
source.readByteArray(vr.bytes); source.readByteArray(vr.mBytes);
return vr; return vr;
} }
@@ -113,11 +113,11 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
} }
public byte[] getBytes() { public byte[] getBytes() {
return bytes; return mBytes;
} }
public void setBytes(byte[] bytes) { public void setBytes(byte[] bytes) {
this.bytes = bytes; this.mBytes = bytes;
} }
/** /**
@@ -127,16 +127,16 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
// keys from keyserver are always public keys // keys from keyserver are always public keys
secretKey = false; secretKey = false;
// do not select by default // do not select by default
selected = false; mSelected = false;
userIds = new ArrayList<String>(); userIds = new ArrayList<String>();
} }
public boolean isSelected() { public boolean isSelected() {
return selected; return mSelected;
} }
public void setSelected(boolean selected) { public void setSelected(boolean selected) {
this.selected = selected; this.mSelected = selected;
} }
/** /**
@@ -146,13 +146,13 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
public ImportKeysListEntry(PGPKeyRing pgpKeyRing) { public ImportKeysListEntry(PGPKeyRing pgpKeyRing) {
// save actual key object into entry, used to import it later // save actual key object into entry, used to import it later
try { try {
this.bytes = pgpKeyRing.getEncoded(); this.mBytes = pgpKeyRing.getEncoded();
} catch (IOException e) { } catch (IOException e) {
Log.e(Constants.TAG, "IOException on pgpKeyRing.getEncoded()", e); Log.e(Constants.TAG, "IOException on pgpKeyRing.getEncoded()", e);
} }
// selected is default // selected is default
this.selected = true; this.mSelected = true;
if (pgpKeyRing instanceof PGPSecretKeyRing) { if (pgpKeyRing instanceof PGPSecretKeyRing) {
secretKey = true; secretKey = true;
@@ -187,4 +187,4 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
this.algorithm = "unknown"; this.algorithm = "unknown";
} }
} }
} }

View File

@@ -31,21 +31,22 @@ import java.io.BufferedInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> { public class ImportKeysListLoader
extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
public static class FileHasNoContent extends Exception { public static class FileHasNoContent extends Exception {
} }
public static class NonPgpPart extends Exception { public static class NonPgpPart extends Exception {
private int count; private int mCount;
public NonPgpPart(int count) { public NonPgpPart(int count) {
this.count = count; this.mCount = count;
} }
public int getCount() { public int getCount() {
return count; return mCount;
} }
} }
@@ -53,8 +54,8 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper
InputData mInputData; InputData mInputData;
ArrayList<ImportKeysListEntry> data = new ArrayList<ImportKeysListEntry>(); ArrayList<ImportKeysListEntry> mData = new ArrayList<ImportKeysListEntry>();
AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> entryListWrapper; AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper;
public ImportKeysListLoader(Context context, InputData inputData) { public ImportKeysListLoader(Context context, InputData inputData) {
super(context); super(context);
@@ -65,16 +66,16 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper
@Override @Override
public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() { public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(data, null); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, null);
if (mInputData == null) { if (mInputData == null) {
Log.e(Constants.TAG, "Input data is null!"); Log.e(Constants.TAG, "Input data is null!");
return entryListWrapper; return mEntryListWrapper;
} }
generateListOfKeyrings(mInputData); generateListOfKeyrings(mInputData);
return entryListWrapper; return mEntryListWrapper;
} }
@Override @Override
@@ -142,25 +143,25 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper
} }
} catch (Exception e) { } catch (Exception e) {
Log.e(Constants.TAG, "Exception on parsing key file!", e); Log.e(Constants.TAG, "Exception on parsing key file!", e);
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(data, e); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mData, e);
nonPgpCounter = 0; nonPgpCounter = 0;
} }
if (isEmpty) { if (isEmpty) {
Log.e(Constants.TAG, "File has no content!", new FileHasNoContent()); Log.e(Constants.TAG, "File has no content!", new FileHasNoContent());
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
(data, new FileHasNoContent()); (mData, new FileHasNoContent());
} }
if (nonPgpCounter > 0) { if (nonPgpCounter > 0) {
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
(data, new NonPgpPart(nonPgpCounter)); (mData, new NonPgpPart(nonPgpCounter));
} }
} }
private void addToData(PGPKeyRing keyring) { private void addToData(PGPKeyRing keyring) {
ImportKeysListEntry item = new ImportKeysListEntry(keyring); ImportKeysListEntry item = new ImportKeysListEntry(keyring);
data.add(item); mData.add(item);
} }
} }

View File

@@ -26,14 +26,15 @@ import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
public class ImportKeysListServerLoader extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> { public class ImportKeysListServerLoader
extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
Context mContext; Context mContext;
String mServerQuery; String mServerQuery;
String mKeyServer; String mKeyServer;
private ArrayList<ImportKeysListEntry> entryList = new ArrayList<ImportKeysListEntry>(); private ArrayList<ImportKeysListEntry> mEntryList = new ArrayList<ImportKeysListEntry>();
private AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> entryListWrapper; private AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> mEntryListWrapper;
public ImportKeysListServerLoader(Context context, String serverQuery, String keyServer) { public ImportKeysListServerLoader(Context context, String serverQuery, String keyServer) {
super(context); super(context);
@@ -45,16 +46,16 @@ public class ImportKeysListServerLoader extends AsyncTaskLoader<AsyncTaskResultW
@Override @Override
public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() { public AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>> loadInBackground() {
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, null); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, null);
if (mServerQuery == null) { if (mServerQuery == null) {
Log.e(Constants.TAG, "mServerQuery is null!"); Log.e(Constants.TAG, "mServerQuery is null!");
return entryListWrapper; return mEntryListWrapper;
} }
queryServer(mServerQuery, mKeyServer); queryServer(mServerQuery, mKeyServer);
return entryListWrapper; return mEntryListWrapper;
} }
@Override @Override
@@ -89,17 +90,17 @@ public class ImportKeysListServerLoader extends AsyncTaskLoader<AsyncTaskResultW
ArrayList<ImportKeysListEntry> searchResult = server.search(query); ArrayList<ImportKeysListEntry> searchResult = server.search(query);
// add result to data // add result to data
entryList.addAll(searchResult); mEntryList.addAll(searchResult);
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, null); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, null);
} catch (KeyServer.InsufficientQuery e) { } catch (KeyServer.InsufficientQuery e) {
Log.e(Constants.TAG, "InsufficientQuery", e); Log.e(Constants.TAG, "InsufficientQuery", e);
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, e); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, e);
} catch (KeyServer.QueryException e) { } catch (KeyServer.QueryException e) {
Log.e(Constants.TAG, "QueryException", e); Log.e(Constants.TAG, "QueryException", e);
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, e); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, e);
} catch (KeyServer.TooManyResponses e) { } catch (KeyServer.TooManyResponses e) {
Log.e(Constants.TAG, "TooManyResponses", e); Log.e(Constants.TAG, "TooManyResponses", e);
entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(entryList, e); mEntryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(mEntryList, e);
} }
} }

View File

@@ -94,4 +94,4 @@ public class KeyValueSpinnerAdapter extends ArrayAdapter<String> {
} }
return -1; return -1;
} }
} }

View File

@@ -44,8 +44,8 @@ public class SelectKeyCursorAdapter extends HighlightQueryCursorAdapter {
private int mIndexProjectionValid; private int mIndexProjectionValid;
private int mIndexProjectionAvailable; private int mIndexProjectionAvailable;
public final static String PROJECTION_ROW_AVAILABLE = "available"; public static final String PROJECTION_ROW_AVAILABLE = "available";
public final static String PROJECTION_ROW_VALID = "valid"; public static final String PROJECTION_ROW_VALID = "valid";
public SelectKeyCursorAdapter(Context context, Cursor c, int flags, ListView listView, public SelectKeyCursorAdapter(Context context, Cursor c, int flags, ListView listView,
int keyType) { int keyType) {

View File

@@ -1,3 +1,20 @@
/*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui.adapter; package org.sufficientlysecure.keychain.ui.adapter;
import android.content.Context; import android.content.Context;
@@ -19,12 +36,12 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo { static final class TabInfo {
private final Class<?> clss; private final Class<?> mClss;
private final Bundle args; private final Bundle mArgs;
TabInfo(Class<?> _class, Bundle _args) { TabInfo(Class<?> mClss, Bundle mArgs) {
clss = _class; this.mClss = mClss;
args = _args; this.mArgs = mArgs;
} }
} }
@@ -54,7 +71,7 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
TabInfo info = mTabs.get(position); TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args); return Fragment.instantiate(mContext, info.mClss.getName(), info.mArgs);
} }
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
@@ -81,4 +98,4 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
} }
} }

View File

@@ -148,4 +148,4 @@ public class CreateKeyDialogFragment extends DialogFragment {
return dialog.create(); return dialog.create();
} }
} }

View File

@@ -88,7 +88,8 @@ public class DeleteFileDialogFragment extends DialogFragment {
null); null);
// Message is received after deleting is done in ApgService // Message is received after deleting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(activity, deletingDialog) { KeychainIntentServiceHandler saveHandler =
new KeychainIntentServiceHandler(activity, deletingDialog) {
public void handleMessage(Message message) { public void handleMessage(Message message) {
// handle messages by standard ApgHandler first // handle messages by standard ApgHandler first
super.handleMessage(message); super.handleMessage(message);
@@ -120,4 +121,4 @@ public class DeleteFileDialogFragment extends DialogFragment {
return alert.create(); return alert.create();
} }
} }

View File

@@ -117,8 +117,9 @@ public class DeleteKeyDialogFragment extends DialogFragment {
String selectionIDs = ""; String selectionIDs = "";
for (int i = 0; i < keyRingRowIds.length; i++) { for (int i = 0; i < keyRingRowIds.length; i++) {
selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'"; selectionIDs += "'" + String.valueOf(keyRingRowIds[i]) + "'";
if (i + 1 < keyRingRowIds.length) if (i + 1 < keyRingRowIds.length) {
selectionIDs += ","; selectionIDs += ",";
}
} }
selection += selectionIDs + ")"; selection += selectionIDs + ")";
@@ -139,7 +140,9 @@ public class DeleteKeyDialogFragment extends DialogFragment {
// check if a corresponding secret key exists... // check if a corresponding secret key exists...
Cursor secretCursor = activity.getContentResolver().query( Cursor secretCursor = activity.getContentResolver().query(
KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri(String.valueOf(masterKeyId)), KeychainContract.KeyRings
.buildSecretKeyRingsByMasterKeyIdUri(
String.valueOf(masterKeyId)),
null, null, null, null null, null, null, null
); );
if (secretCursor != null && secretCursor.getCount() > 0) { if (secretCursor != null && secretCursor.getCount() > 0) {
@@ -204,4 +207,4 @@ public class DeleteKeyDialogFragment extends DialogFragment {
Log.w(Constants.TAG, "Messenger is null!", e); Log.w(Constants.TAG, "Messenger is null!", e);
} }
} }
} }

View File

@@ -61,7 +61,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
private Messenger mMessenger; private Messenger mMessenger;
private EditText mPassphraseEditText; private EditText mPassphraseEditText;
private boolean canKB; private boolean mCanKB;
/** /**
* Creates new instance of this dialog fragment * Creates new instance of this dialog fragment
@@ -128,7 +128,7 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
} }
}); });
alert.setCancelable(false); alert.setCancelable(false);
canKB = false; mCanKB = false;
return alert.create(); return alert.create();
} }
String userId = PgpKeyHelper.getMainUserIdSafe(activity, secretKey); String userId = PgpKeyHelper.getMainUserIdSafe(activity, secretKey);
@@ -221,14 +221,14 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
} }
}); });
canKB = true; mCanKB = true;
return alert.create(); return alert.create();
} }
@Override @Override
public void onActivityCreated(Bundle arg0) { public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0); super.onActivityCreated(arg0);
if (canKB) { if (mCanKB) {
// request focus and open soft keyboard // request focus and open soft keyboard
mPassphraseEditText.requestFocus(); mPassphraseEditText.requestFocus();
getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);

View File

@@ -100,8 +100,9 @@ public class ProgressDialogFragment extends DialogFragment {
public void onCancel(DialogInterface dialog) { public void onCancel(DialogInterface dialog) {
super.onCancel(dialog); super.onCancel(dialog);
if (this.mOnCancelListener != null) if (this.mOnCancelListener != null) {
this.mOnCancelListener.onCancel(dialog); this.mOnCancelListener.onCancel(dialog);
}
} }
/** /**
@@ -150,4 +151,4 @@ public class ProgressDialogFragment extends DialogFragment {
return dialog; return dialog;
} }
} }

View File

@@ -183,4 +183,4 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
Log.w(Constants.TAG, "Messenger is null!", e); Log.w(Constants.TAG, "Messenger is null!", e);
} }
} }
} }

View File

@@ -96,4 +96,4 @@ public class ShareNfcDialogFragment extends DialogFragment {
return alert.create(); return alert.create();
} }
} }

View File

@@ -52,4 +52,4 @@ public class FixedListView extends ListView {
super.onMeasure(widthMeasureSpec, expandSpec); super.onMeasure(widthMeasureSpec, expandSpec);
} }
} }

View File

@@ -54,7 +54,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
GregorianCalendar mExpiryDate; GregorianCalendar mExpiryDate;
private int mDatePickerResultCount = 0; private int mDatePickerResultCount = 0;
private DatePickerDialog.OnDateSetListener mExpiryDateSetListener = new DatePickerDialog.OnDateSetListener() { private DatePickerDialog.OnDateSetListener mExpiryDateSetListener =
new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
// Note: Ignore results after the first one - android sends multiples. // Note: Ignore results after the first one - android sends multiples.
if (mDatePickerResultCount++ == 0) { if (mDatePickerResultCount++ == 0) {
@@ -89,7 +90,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
new Choice(Id.choice.usage.encrypt_only, getResources().getString( new Choice(Id.choice.usage.encrypt_only, getResources().getString(
R.string.choice_encrypt_only)), R.string.choice_encrypt_only)),
new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString( new Choice(Id.choice.usage.sign_and_encrypt, getResources().getString(
R.string.choice_sign_and_encrypt)),}; R.string.choice_sign_and_encrypt)), };
ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(getContext(), ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(getContext(),
android.R.layout.simple_spinner_item, choices); android.R.layout.simple_spinner_item, choices);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -129,13 +130,15 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}); });
// setCalendarViewShown() is supported from API 11 onwards. // setCalendarViewShown() is supported from API 11 onwards.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
// Hide calendarView in tablets because of the unix warparound bug. // Hide calendarView in tablets because of the unix warparound bug.
dialog.getDatePicker().setCalendarViewShown(false); dialog.getDatePicker().setCalendarViewShown(false);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
if (dialog != null && mCreatedDate != null) { if (dialog != null && mCreatedDate != null) {
dialog.getDatePicker().setMinDate(mCreatedDate.getTime().getTime() + DateUtils.DAY_IN_MILLIS); dialog.getDatePicker()
.setMinDate(
mCreatedDate.getTime().getTime() + DateUtils.DAY_IN_MILLIS);
} else { } else {
//When created date isn't available //When created date isn't available
dialog.getDatePicker().setMinDate(date.getTime().getTime() + DateUtils.DAY_IN_MILLIS); dialog.getDatePicker().setMinDate(date.getTime().getTime() + DateUtils.DAY_IN_MILLIS);
@@ -277,7 +280,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
class ExpiryDatePickerDialog extends DatePickerDialog { class ExpiryDatePickerDialog extends DatePickerDialog {
public ExpiryDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) { public ExpiryDatePickerDialog(Context context, OnDateSetListener callBack,
int year, int monthOfYear, int dayOfMonth) {
super(context, callBack, year, monthOfYear, dayOfMonth); super(context, callBack, year, monthOfYear, dayOfMonth);
} }

View File

@@ -55,7 +55,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
private Choice mNewKeyAlgorithmChoice; private Choice mNewKeyAlgorithmChoice;
private int mNewKeySize; private int mNewKeySize;
private boolean canEdit = true; private boolean mCanEdit = true;
private ActionBarActivity mActivity; private ActionBarActivity mActivity;
@@ -95,8 +95,8 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
} }
public void setCanEdit(boolean bCanEdit) { public void setCanEdit(boolean bCanEdit) {
canEdit = bCanEdit; mCanEdit = bCanEdit;
if (!canEdit) { if (!mCanEdit) {
mPlusButton.setVisibility(View.INVISIBLE); mPlusButton.setVisibility(View.INVISIBLE);
} }
} }
@@ -137,7 +137,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
* {@inheritDoc} * {@inheritDoc}
*/ */
public void onClick(View v) { public void onClick(View v) {
if (canEdit) { if (mCanEdit) {
switch (mType) { switch (mType) {
case Id.type.user_id: { case Id.type.user_id: {
UserIdEditor view = (UserIdEditor) mInflater.inflate( UserIdEditor view = (UserIdEditor) mInflater.inflate(
@@ -151,15 +151,18 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
} }
case Id.type.key: { case Id.type.key: {
CreateKeyDialogFragment mCreateKeyDialogFragment = CreateKeyDialogFragment.newInstance(mEditors.getChildCount()); CreateKeyDialogFragment mCreateKeyDialogFragment =
mCreateKeyDialogFragment.setOnAlgorithmSelectedListener(new CreateKeyDialogFragment.OnAlgorithmSelectedListener() { CreateKeyDialogFragment.newInstance(mEditors.getChildCount());
@Override mCreateKeyDialogFragment
public void onAlgorithmSelected(Choice algorithmChoice, int keySize) { .setOnAlgorithmSelectedListener(
mNewKeyAlgorithmChoice = algorithmChoice; new CreateKeyDialogFragment.OnAlgorithmSelectedListener() {
mNewKeySize = keySize; @Override
createKey(); public void onAlgorithmSelected(Choice algorithmChoice, int keySize) {
} mNewKeyAlgorithmChoice = algorithmChoice;
}); mNewKeySize = keySize;
createKey();
}
});
mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog"); mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog");
break; break;
} }
@@ -186,7 +189,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
if (mEditors.getChildCount() == 0) { if (mEditors.getChildCount() == 0) {
view.setIsMainUserId(true); view.setIsMainUserId(true);
} }
view.setCanEdit(canEdit); view.setCanEdit(mCanEdit);
mEditors.addView(view); mEditors.addView(view);
} }
@@ -207,7 +210,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
view.setEditorListener(this); view.setEditorListener(this);
boolean isMasterKey = (mEditors.getChildCount() == 0); boolean isMasterKey = (mEditors.getChildCount() == 0);
view.setValue(list.get(i), isMasterKey, usages.get(i)); view.setValue(list.get(i), isMasterKey, usages.get(i));
view.setCanEdit(canEdit); view.setCanEdit(mCanEdit);
mEditors.addView(view); mEditors.addView(view);
} }

View File

@@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui.widget;
import android.content.Context; import android.content.Context;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Patterns;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -38,14 +39,6 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene
private AutoCompleteTextView mEmail; private AutoCompleteTextView mEmail;
private EditText mComment; private EditText mComment;
// see http://www.regular-expressions.info/email.html
// RFC 2822 if we omit the syntax using double quotes and square brackets
// android.util.Patterns.EMAIL_ADDRESS is only available as of Android 2.2+
private static final Pattern EMAIL_PATTERN = Pattern
.compile(
"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
Pattern.CASE_INSENSITIVE);
public static class NoNameException extends Exception { public static class NoNameException extends Exception {
static final long serialVersionUID = 0xf812773343L; static final long serialVersionUID = 0xf812773343L;
@@ -142,7 +135,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene
String comment = ("" + mComment.getText()).trim(); String comment = ("" + mComment.getText()).trim();
if (email.length() > 0) { if (email.length() > 0) {
Matcher emailMatcher = EMAIL_PATTERN.matcher(email); Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email);
if (!emailMatcher.matches()) { if (!emailMatcher.matches()) {
throw new InvalidEmailException(getContext().getString(R.string.error_invalid_email, throw new InvalidEmailException(getContext().getString(R.string.error_invalid_email,
email)); email));

View File

@@ -17,13 +17,14 @@
package org.sufficientlysecure.keychain.util; package org.sufficientlysecure.keychain.util;
import java.util.HashMap; import android.annotation.SuppressLint;
import android.app.Activity;
import org.spongycastle.bcpg.HashAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.openpgp.PGPEncryptedData; import org.spongycastle.openpgp.PGPEncryptedData;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import android.annotation.SuppressLint;
import android.app.Activity; import java.util.HashMap;
@SuppressLint("UseSparseArrays") @SuppressLint("UseSparseArrays")
public class AlgorithmNames { public class AlgorithmNames {

View File

@@ -39,7 +39,7 @@ public class Choice {
} }
@Override @Override
public String toString() { public String toString() {
return mName; return mName;
} }
} }

View File

@@ -78,39 +78,40 @@ public class HkpKeyServer extends KeyServer {
// pub 2048R/<a href="/pks/lookup?op=get&search=0x887DF4BE9F5C9090">9F5C9090</a> 2009-08-17 <a // pub 2048R/<a href="/pks/lookup?op=get&search=0x887DF4BE9F5C9090">9F5C9090</a> 2009-08-17 <a
// href="/pks/lookup?op=vindex&search=0x887DF4BE9F5C9090">Jörg Runge // href="/pks/lookup?op=vindex&search=0x887DF4BE9F5C9090">Jörg Runge
// &lt;joerg@joergrunge.de&gt;</a> // &lt;joerg@joergrunge.de&gt;</a>
public static Pattern PUB_KEY_LINE = Pattern public static final Pattern PUB_KEY_LINE = Pattern
.compile( .compile(
"pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)", "pub +([0-9]+)([a-z]+)/.*?0x([0-9a-z]+).*? +([0-9-]+) +(.+)[\n\r]+((?: +.+[\n\r]+)*)",
Pattern.CASE_INSENSITIVE); Pattern.CASE_INSENSITIVE);
public static Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE public static final Pattern USER_ID_LINE = Pattern.compile("^ +(.+)$", Pattern.MULTILINE
| Pattern.CASE_INSENSITIVE); | Pattern.CASE_INSENSITIVE);
private static final short PORT_DEFAULT = 11371; private static final short PORT_DEFAULT = 11371;
/** /**
* @param hostAndPort may be just "<code>hostname</code>" (eg. "<code>pool.sks-keyservers.net</code>"), then it will * @param hostAndPort may be just
* connect using {@link #PORT_DEFAULT}. However, port may be specified after colon * "<code>hostname</code>" (eg. "<code>pool.sks-keyservers.net</code>"), then it will
* ("<code>hostname:port</code>", eg. "<code>p80.pool.sks-keyservers.net:80</code>"). * connect using {@link #PORT_DEFAULT}. However, port may be specified after colon
*/ * ("<code>hostname:port</code>", eg. "<code>p80.pool.sks-keyservers.net:80</code>").
public HkpKeyServer(String hostAndPort) { */
String host = hostAndPort; public HkpKeyServer(String hostAndPort) {
short port = PORT_DEFAULT; String host = hostAndPort;
final int colonPosition = hostAndPort.lastIndexOf(':'); short port = PORT_DEFAULT;
if (colonPosition > 0) { final int colonPosition = hostAndPort.lastIndexOf(':');
host = hostAndPort.substring(0, colonPosition); if (colonPosition > 0) {
final String portStr = hostAndPort.substring(colonPosition + 1); host = hostAndPort.substring(0, colonPosition);
port = Short.decode(portStr); final String portStr = hostAndPort.substring(colonPosition + 1);
} port = Short.decode(portStr);
mHost = host; }
mPort = port; mHost = host;
} mPort = port;
}
public HkpKeyServer(String host, short port) { public HkpKeyServer(String host, short port) {
mHost = host; mHost = host;
mPort = port; mPort = port;
} }
static private String readAll(InputStream in, String encoding) throws IOException { private static String readAll(InputStream in, String encoding) throws IOException {
ByteArrayOutputStream raw = new ByteArrayOutputStream(); ByteArrayOutputStream raw = new ByteArrayOutputStream();
byte buffer[] = new byte[1 << 16]; byte buffer[] = new byte[1 << 16];

View File

@@ -18,30 +18,28 @@ package org.sufficientlysecure.keychain.util;
import android.content.Intent; import android.content.Intent;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentIntegrator;
/** /**
* IntentIntegrator for the V4 Android compatibility package. * IntentIntegrator for the V4 Android compatibility package.
* *
* @author Lachezar Dobrev * @author Lachezar Dobrev
*/ */
public final class IntentIntegratorSupportV4 extends IntentIntegrator { public final class IntentIntegratorSupportV4 extends IntentIntegrator {
private final Fragment fragment; private final Fragment mFragment;
/** /**
* @param fragment * @param fragment Fragment to handle activity response.
* Fragment to handle activity response.
*/ */
public IntentIntegratorSupportV4(Fragment fragment) { public IntentIntegratorSupportV4(Fragment fragment) {
super(fragment.getActivity()); super(fragment.getActivity());
this.fragment = fragment; this.mFragment = fragment;
} }
@Override @Override
protected void startActivityForResult(Intent intent, int code) { protected void startActivityForResult(Intent intent, int code) {
fragment.startActivityForResult(intent, code); mFragment.startActivityForResult(intent, code);
} }
} }

View File

@@ -18,12 +18,12 @@
package org.sufficientlysecure.keychain.util; package org.sufficientlysecure.keychain.util;
import java.util.List;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
import java.util.List;
public abstract class KeyServer { public abstract class KeyServer {
static public class QueryException extends Exception { public static class QueryException extends Exception {
private static final long serialVersionUID = 2703768928624654512L; private static final long serialVersionUID = 2703768928624654512L;
public QueryException(String message) { public QueryException(String message) {
@@ -31,15 +31,15 @@ public abstract class KeyServer {
} }
} }
static public class TooManyResponses extends Exception { public static class TooManyResponses extends Exception {
private static final long serialVersionUID = 2703768928624654513L; private static final long serialVersionUID = 2703768928624654513L;
} }
static public class InsufficientQuery extends Exception { public static class InsufficientQuery extends Exception {
private static final long serialVersionUID = 2703768928624654514L; private static final long serialVersionUID = 2703768928624654514L;
} }
static public class AddKeyException extends Exception { public static class AddKeyException extends Exception {
private static final long serialVersionUID = -507574859137295530L; private static final long serialVersionUID = -507574859137295530L;
} }

View File

@@ -1,3 +1,16 @@
/*
* 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.util; package org.sufficientlysecure.keychain.util;
public interface KeychainServiceListener { public interface KeychainServiceListener {

View File

@@ -21,7 +21,6 @@ import org.sufficientlysecure.keychain.Constants;
/** /**
* Wraps Android Logging to enable or disable debug output using Constants * Wraps Android Logging to enable or disable debug output using Constants
*
*/ */
public final class Log { public final class Log {

View File

@@ -14,48 +14,36 @@ import android.os.Build;
import android.os.Process; import android.os.Process;
import android.util.Log; import android.util.Log;
import java.io.ByteArrayOutputStream; import java.io.*;
import java.io.DataInputStream; import java.security.*;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
import java.security.Security;
/** /**
* Fixes for the output of the default PRNG having low entropy. * Fixes for the output of the default PRNG having low entropy.
* * <p/>
* The fixes need to be applied via {@link #apply()} before any use of Java Cryptography * The fixes need to be applied via {@link #apply()} before any use of Java Cryptography
* Architecture primitives. A good place to invoke them is in the application's {@code onCreate}. * Architecture primitives. A good place to invoke them is in the application's {@code onCreate}.
* * <p/>
* copied from http://android-developers.blogspot.de/2013/08/some-securerandom-thoughts.html * copied from http://android-developers.blogspot.de/2013/08/some-securerandom-thoughts.html
* * <p/>
* * <p/>
* More information on these Android bugs: * More information on these Android bugs:
* http://blog.k3170makan.com/2013/08/more-details-on-android-jca-prng-flaw.html * http://blog.k3170makan.com/2013/08/more-details-on-android-jca-prng-flaw.html
* Paper: "Randomly failed! Weaknesses in Java Pseudo Random Number Generators (PRNGs)" * Paper: "Randomly failed! Weaknesses in Java Pseudo Random Number Generators (PRNGs)"
* * <p/>
* * <p/>
* Sep 15, 2013: * Sep 15, 2013:
* On some devices /dev/urandom is non-writable! * On some devices /dev/urandom is non-writable!
* No need to seed /dev/urandom. urandom should have enough seeds from the OS and kernel. * No need to seed /dev/urandom. urandom should have enough seeds from the OS and kernel.
* Only OpenSSL seeds are broken. See http://emboss.github.io/blog/2013/08/21/openssl-prng-is-not-really-fork-safe * Only OpenSSL seeds are broken. See http://emboss.github.io/blog/2013/08/21/openssl-prng-is-not-really-fork-safe
* * <p/>
* see also: * see also:
* https://github.com/k9mail/k-9/commit/dda8f64276d4d29c43f86237cd77819c28f22f21 * https://github.com/k9mail/k-9/commit/dda8f64276d4d29c43f86237cd77819c28f22f21
* In addition to a couple of custom ROMs linking /dev/urandom to a non-writable * In addition to a couple of custom ROMs linking /dev/urandom to a non-writable
* random version, now Samsung's SELinux policy also prevents apps from opening * random version, now Samsung's SELinux policy also prevents apps from opening
* /dev/urandom for writing. Since we shouldn't need to write to /dev/urandom anyway * /dev/urandom for writing. Since we shouldn't need to write to /dev/urandom anyway
* we now simply don't. * we now simply don't.
* * <p/>
* * <p/>
* Sep 17, 2013: * Sep 17, 2013:
* Updated from official blogpost: * Updated from official blogpost:
* Update: the original code sample below crashed on a small fraction of Android * Update: the original code sample below crashed on a small fraction of Android
@@ -66,10 +54,13 @@ public final class PRNGFixes {
private static final int VERSION_CODE_JELLY_BEAN = 16; private static final int VERSION_CODE_JELLY_BEAN = 16;
private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18; private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18;
private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL = private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL =
getBuildFingerprintAndDeviceSerial(); getBuildFingerprintAndDeviceSerial();
/** Hidden constructor to prevent instantiation. */ /**
private PRNGFixes() {} * Hidden constructor to prevent instantiation.
*/
private PRNGFixes() {
}
/** /**
* Applies all fixes. * Applies all fixes.
@@ -136,7 +127,7 @@ public final class PRNGFixes {
if ((secureRandomProviders == null) if ((secureRandomProviders == null)
|| (secureRandomProviders.length < 1) || (secureRandomProviders.length < 1)
|| (!LinuxPRNGSecureRandomProvider.class.equals( || (!LinuxPRNGSecureRandomProvider.class.equals(
secureRandomProviders[0].getClass()))) { secureRandomProviders[0].getClass()))) {
Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1); Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1);
} }
@@ -161,7 +152,7 @@ public final class PRNGFixes {
rng2.getProvider().getClass())) { rng2.getProvider().getClass())) {
throw new SecurityException( throw new SecurityException(
"SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong"
+ " Provider: " + rng2.getProvider().getClass()); + " Provider: " + rng2.getProvider().getClass());
} }
} }
@@ -175,7 +166,7 @@ public final class PRNGFixes {
super("LinuxPRNG", super("LinuxPRNG",
1.0, 1.0,
"A Linux-specific random number provider that uses" "A Linux-specific random number provider that uses"
+ " /dev/urandom"); + " /dev/urandom");
// Although /dev/urandom is not a SHA-1 PRNG, some apps // Although /dev/urandom is not a SHA-1 PRNG, some apps
// explicitly request a SHA1PRNG SecureRandom and we thus need to // explicitly request a SHA1PRNG SecureRandom and we thus need to
// prevent them from getting the default implementation whose output // prevent them from getting the default implementation whose output
@@ -358,4 +349,4 @@ public final class PRNGFixes {
throw new RuntimeException("UTF-8 encoding not supported"); throw new RuntimeException("UTF-8 encoding not supported");
} }
} }
} }

View File

@@ -17,11 +17,7 @@
package org.sufficientlysecure.keychain.util; package org.sufficientlysecure.keychain.util;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.*;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@@ -32,59 +28,63 @@ import java.util.concurrent.locks.ReentrantLock;
public class PausableThreadPoolExecutor extends ThreadPoolExecutor { public class PausableThreadPoolExecutor extends ThreadPoolExecutor {
public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { TimeUnit unit, BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
} }
public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, TimeUnit unit, BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) { ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
} }
public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { TimeUnit unit, BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
} }
public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue) { TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
} }
private boolean isPaused; private boolean mIsPaused;
private ReentrantLock pauseLock = new ReentrantLock(); private ReentrantLock mPauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition(); private Condition mUnPaused = mPauseLock.newCondition();
protected void beforeExecute(Thread t, Runnable r) { protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r); super.beforeExecute(t, r);
pauseLock.lock(); mPauseLock.lock();
try { try {
while (isPaused) while (mIsPaused) {
unpaused.await(); mUnPaused.await();
}
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
t.interrupt(); t.interrupt();
} finally { } finally {
pauseLock.unlock(); mPauseLock.unlock();
} }
} }
public void pause() { public void pause() {
pauseLock.lock(); mPauseLock.lock();
try { try {
isPaused = true; mIsPaused = true;
} finally { } finally {
pauseLock.unlock(); mPauseLock.unlock();
} }
} }
public void resume() { public void resume() {
pauseLock.lock(); mPauseLock.lock();
try { try {
isPaused = false; mIsPaused = false;
unpaused.signalAll(); mUnPaused.signalAll();
} finally { } finally {
pauseLock.unlock(); mPauseLock.unlock();
} }
} }
} }

View File

@@ -25,147 +25,147 @@ public final class Primes {
// taken from http://www.ietf.org/rfc/rfc3526.txt // taken from http://www.ietf.org/rfc/rfc3526.txt
public static final String P1536 = public static final String P1536 =
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
"670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF"; "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF";
public static final String P2048 = public static final String P2048 =
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
"15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"; "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF";
public static final String P3072 = public static final String P3072 =
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
"43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"; "43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF";
public static final String P4096 = public static final String P4096 =
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
"43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" +
"88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" +
"2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" +
"287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" +
"1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" +
"93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" +
"FFFFFFFF FFFFFFFF"; "FFFFFFFF FFFFFFFF";
public static final String P6144 = public static final String P6144 =
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
"43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" +
"88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" +
"2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" +
"287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" +
"1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" +
"93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" +
"36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" + "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" +
"F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" + "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" +
"179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" + "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" +
"DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" + "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" +
"5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" + "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" +
"D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" + "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" +
"23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" + "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" +
"CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" + "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" +
"06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" + "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" +
"DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" + "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" +
"12BF2D5B 0B7474D6 E694F91E 6DCC4024 FFFFFFFF FFFFFFFF"; "12BF2D5B 0B7474D6 E694F91E 6DCC4024 FFFFFFFF FFFFFFFF";
public static final String P8192 = public static final String P8192 =
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" +
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" +
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" +
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" +
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" +
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" +
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" +
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" +
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" +
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" +
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" +
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" +
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" +
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" +
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" +
"43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" +
"88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" +
"2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" +
"287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" +
"1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" +
"93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" +
"36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" + "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" +
"F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" + "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" +
"179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" + "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" +
"DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" + "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" +
"5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" + "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" +
"D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" + "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" +
"23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" + "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" +
"CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" + "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" +
"06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" + "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" +
"DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" + "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" +
"12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" + "12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" +
"38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" + "38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" +
"741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" + "741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" +
"3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" + "3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" +
"22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" + "22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" +
"4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" + "4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" +
"062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" + "062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" +
"4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" + "4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" +
"B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" + "B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" +
"4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" + "4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" +
"9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" + "9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" +
"60C980DD 98EDD3DF FFFFFFFF FFFFFFFF"; "60C980DD 98EDD3DF FFFFFFFF FFFFFFFF";
public static BigInteger getBestPrime(int keySize) { public static BigInteger getBestPrime(int keySize) {
String primeString; String primeString;

View File

@@ -18,26 +18,24 @@
package org.sufficientlysecure.keychain.util; package org.sufficientlysecure.keychain.util;
import java.util.Hashtable;
import org.sufficientlysecure.keychain.Constants;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType; import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException; import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.sufficientlysecure.keychain.Constants;
import java.util.Hashtable;
public class QrCodeUtils { public class QrCodeUtils {
public final static QRCodeWriter QR_CODE_WRITER = new QRCodeWriter(); public static final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter();
/** /**
* Generate Bitmap with QR Code based on input. * Generate Bitmap with QR Code based on input.
* *
* @param input * @param input
* @param size * @param size
* @return QR Code as Bitmap * @return QR Code as Bitmap