fixes, refactoring

This commit is contained in:
Dominik 2012-09-11 15:27:32 +02:00
parent 534cbec7c5
commit be49597882
20 changed files with 231 additions and 220 deletions

View file

@ -15,47 +15,25 @@
limitations under the License. limitations under the License.
--> -->
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="16dp" android:paddingRight="16dp" >
android:stretchColumns="1" >
<TableRow> <TextView
android:id="@+id/passphrase_label_passphrase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/label_passPhrase" />
<TextView <EditText
android:id="@+id/passphrase_label_passphrase" android:id="@+id/passphrase_passphrase"
android:layout_width="wrap_content" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:inputType="textPassword"
android:padding="4dp" android:padding="4dp" />
android:text="@string/label_passPhrase" />
<EditText </LinearLayout>
android:id="@+id/passphrase_passphrase"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:padding="4dp" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/passphrase_label_passphrase_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/label_passPhraseAgain" />
<EditText
android:id="@+id/passphrase_passphrase_again"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:padding="4dp" />
</TableRow>
</TableLayout>

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:stretchColumns="1" >
<TableRow>
<TextView
android:id="@+id/passphrase_label_passphrase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/label_passPhrase" />
<EditText
android:id="@+id/passphrase_passphrase"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:padding="4dp" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/passphrase_label_passphrase_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="4dp"
android:text="@string/label_passPhraseAgain" />
<EditText
android:id="@+id/passphrase_passphrase_again"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:padding="4dp" />
</TableRow>
</TableLayout>

View file

@ -193,7 +193,7 @@
<string name="passPhrasesDoNotMatch">The passphrases didn\'t match.</string> <string name="passPhrasesDoNotMatch">The passphrases didn\'t match.</string>
<string name="passPhraseMustNotBeEmpty">Empty passphrases are not allowed.</string> <string name="passPhraseMustNotBeEmpty">Empty passphrases are not allowed.</string>
<string name="passPhraseForSymmetricEncryption">Symmetric encryption.</string> <string name="passPhraseForSymmetricEncryption">Symmetric encryption.</string>
<string name="passPhraseFor">%s</string> <string name="passPhraseFor">Enter passphrase for \'%s\'</string>
<string name="fileDeleteConfirmation">Are you sure you want to delete\n%s?</string> <string name="fileDeleteConfirmation">Are you sure you want to delete\n%s?</string>
<string name="fileDeleteSuccessful">Successfully deleted.</string> <string name="fileDeleteSuccessful">Successfully deleted.</string>
<string name="noFileSelected">Select a file first.</string> <string name="noFileSelected">Select a file first.</string>

View file

@ -29,6 +29,7 @@ import android.os.Environment;
public class ApgApplication extends Application { public class ApgApplication extends Application {
static { static {
// Define Java Security Provider to be Bouncy Castle
Security.addProvider(new BouncyCastleProvider()); Security.addProvider(new BouncyCastleProvider());
} }
@ -42,7 +43,7 @@ public class ApgApplication extends Application {
// TODO: Do it better than this! // TODO: Do it better than this!
// this initializes the database to be used in PGPMain // this initializes the database to be used in PGPMain
PGPMain.initialize(this); PGPMain.initialize(this);
// 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);

View file

@ -45,7 +45,7 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
ProgressDialogUpdater, AskForPassphrase.PassPhraseCallbackInterface { ProgressDialogUpdater, AskForPassphrase.PassPhraseCallbackInterface {
private ProgressDialog mProgressDialog = null; private ProgressDialog mProgressDialog = null;
private PausableThread mRunningThread = null; // private PausableThread mRunningThread = null;
private Thread mDeletingThread = null; private Thread mDeletingThread = null;
private long mSecretKeyId = 0; private long mSecretKeyId = 0;
@ -373,14 +373,14 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
// mHandler.sendMessage(msg); // mHandler.sendMessage(msg);
// } // }
public PausableThread getRunningThread() { // public PausableThread getRunningThread() {
return mRunningThread; // return mRunningThread;
} // }
//
public void startThread() { // public void startThread() {
mRunningThread = new PausableThread(this); // mRunningThread = new PausableThread(this);
mRunningThread.start(); // mRunningThread.start();
} // }
public void run() { public void run() {

View file

@ -1,49 +0,0 @@
/*
* 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.thialfihar.android.apg.deprecated;
public class PausableThread extends Thread {
private boolean mPaused = false;
public PausableThread(Runnable runnable) {
super(runnable);
}
public void pause() {
synchronized (this) {
mPaused = true;
while (mPaused) {
try {
wait();
} catch (InterruptedException e) {
// ignore
}
}
}
}
public void unpause() {
synchronized (this) {
mPaused = false;
notify();
}
}
public boolean isPaused() {
synchronized (this) {
return mPaused;
}
}
}

View file

@ -27,6 +27,9 @@ import java.util.Set;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.util.Log; import org.thialfihar.android.apg.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
@ -108,4 +111,24 @@ public class OtherHelper {
} }
} }
} }
/**
* Set actionbar without home button if called from another app
*
* @param activity
*/
public static void setActionBarBackButton(SherlockFragmentActivity activity) {
// set actionbar without home button if called from another app
final ActionBar actionBar = activity.getSupportActionBar();
Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)="
+ activity.getCallingPackage());
if (activity.getCallingPackage() != null
&& activity.getCallingPackage().equals(Constants.PACKAGE_NAME)) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
} else {
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(false);
}
}
} }

View file

@ -43,9 +43,7 @@ public class PGPConversionHelper {
try { try {
key.encode(os); key.encode(os);
} catch (IOException e) { } catch (IOException e) {
Log.e(Constants.TAG, Log.e(Constants.TAG, "Error while converting PGPSecretKey to byte[]!", e);
"Error while converting PGPSecretKey to byte[]: " + e.getMessage());
e.printStackTrace();
} }
} }
@ -68,7 +66,7 @@ public class PGPConversionHelper {
Log.e(Constants.TAG, "No keys given!"); Log.e(Constants.TAG, "No keys given!");
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e(Constants.TAG, "Error while converting to PGPSecretKeyRing!", e);
} }
return keyRing; return keyRing;
@ -88,7 +86,7 @@ public class PGPConversionHelper {
Log.e(Constants.TAG, "No keys given!"); Log.e(Constants.TAG, "No keys given!");
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e(Constants.TAG, "Error while converting to PGPPublicKeyRing!", e);
} }
return keyRing; return keyRing;
@ -135,7 +133,7 @@ public class PGPConversionHelper {
try { try {
return key.getEncoded(); return key.getEncoded();
} catch (IOException e) { } catch (IOException e) {
Log.e(Constants.TAG, "Encoding failed: ", e); Log.e(Constants.TAG, "Encoding failed", e);
return null; return null;
} }
@ -151,7 +149,7 @@ public class PGPConversionHelper {
try { try {
return keyRing.getEncoded(); return keyRing.getEncoded();
} catch (IOException e) { } catch (IOException e) {
Log.e(Constants.TAG, "Encoding failed: ", e); Log.e(Constants.TAG, "Encoding failed", e);
return null; return null;
} }

View file

@ -233,16 +233,16 @@ public class PGPHelper {
public static String getMainUserIdSafe(Context context, PGPPublicKey key) { public static String getMainUserIdSafe(Context context, PGPPublicKey key) {
String userId = getMainUserId(key); String userId = getMainUserId(key);
if (userId == null) { if (userId == null || userId.equals("")) {
userId = context.getResources().getString(R.string.unknownUserId); userId = context.getString(R.string.unknownUserId);
} }
return userId; return userId;
} }
public static String getMainUserIdSafe(Context context, PGPSecretKey key) { public static String getMainUserIdSafe(Context context, PGPSecretKey key) {
String userId = getMainUserId(key); String userId = getMainUserId(key);
if (userId == null) { if (userId == null || userId.equals("")) {
userId = context.getResources().getString(R.string.unknownUserId); userId = context.getString(R.string.unknownUserId);
} }
return userId; return userId;
} }
@ -384,7 +384,7 @@ public class PGPHelper {
} }
public static String getPubkeyAsArmoredString(long keyId) { public static String getPubkeyAsArmoredString(Context context, long keyId) {
PGPPublicKey key = PGPMain.getPublicKey(keyId); PGPPublicKey key = PGPMain.getPublicKey(keyId);
// if it is no public key get it from your own keys... // if it is no public key get it from your own keys...
if (key == null) { if (key == null) {
@ -398,6 +398,8 @@ public class PGPHelper {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
ArmoredOutputStream aos = new ArmoredOutputStream(bos); ArmoredOutputStream aos = new ArmoredOutputStream(bos);
aos.setHeader("Version", PGPMain.getFullVersion(context));
String armouredKey = null; String armouredKey = null;
try { try {
aos.write(key.getEncoded()); aos.write(key.getEncoded());

View file

@ -51,6 +51,7 @@ import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator; import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureList; import org.spongycastle.openpgp.PGPSignatureList;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.PGPUtil;
import org.spongycastle.openpgp.PGPV3SignatureGenerator; import org.spongycastle.openpgp.PGPV3SignatureGenerator;
import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory;
@ -88,7 +89,6 @@ import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
@ -750,6 +750,7 @@ public class PGPMain {
throw new GeneralException(context.getString(R.string.error_externalStorageNotReady)); throw new GeneralException(context.getString(R.string.error_externalStorageNotReady));
} }
ArmoredOutputStream out = new ArmoredOutputStream(outStream); ArmoredOutputStream out = new ArmoredOutputStream(outStream);
out.setHeader("Version", getFullVersion(context));
int numKeys = 0; int numKeys = 0;
for (int i = 0; i < keyRingIds.size(); ++i) { for (int i = 0; i < keyRingIds.size(); ++i) {
@ -771,7 +772,7 @@ public class PGPMain {
++numKeys; ++numKeys;
} }
out.close(); out.close();
returnData.putInt("exported", numKeys); returnData.putInt(ApgService.RESULT_EXPORT, numKeys);
if (progress != null) if (progress != null)
progress.setProgress(R.string.progress_done, 100, 100); progress.setProgress(R.string.progress_done, 100, 100);
@ -1048,22 +1049,26 @@ public class PGPMain {
PGPPrivateKey signaturePrivateKey = null; PGPPrivateKey signaturePrivateKey = null;
if (signatureKeyId == 0) { if (signatureKeyId == 0) {
armorOut.close();
throw new GeneralException(context.getString(R.string.error_noSignatureKey)); throw new GeneralException(context.getString(R.string.error_noSignatureKey));
} }
signingKeyRing = getSecretKeyRing(signatureKeyId); signingKeyRing = getSecretKeyRing(signatureKeyId);
signingKey = PGPHelper.getSigningKey(signatureKeyId); signingKey = PGPHelper.getSigningKey(signatureKeyId);
if (signingKey == null) { if (signingKey == null) {
armorOut.close();
throw new GeneralException(context.getString(R.string.error_signatureFailed)); throw new GeneralException(context.getString(R.string.error_signatureFailed));
} }
if (signaturePassPhrase == null) { if (signaturePassPhrase == null) {
armorOut.close();
throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase)); throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
} }
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray()); BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) { if (signaturePrivateKey == null) {
armorOut.close();
throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey)); throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
} }
if (progress != null) if (progress != null)
@ -1147,8 +1152,10 @@ public class PGPMain {
throws GeneralException, PGPException, IOException, NoSuchAlgorithmException, throws GeneralException, PGPException, IOException, NoSuchAlgorithmException,
SignatureException { SignatureException {
ArmoredOutputStream armorOut = null;
OutputStream out = null; OutputStream out = null;
// Ascii Armor (Base64)
ArmoredOutputStream armorOut = null;
if (armored) { if (armored) {
armorOut = new ArmoredOutputStream(outStream); armorOut = new ArmoredOutputStream(outStream);
armorOut.setHeader("Version", getFullVersion(context)); armorOut.setHeader("Version", getFullVersion(context));
@ -1174,6 +1181,7 @@ public class PGPMain {
if (signaturePassPhrase == null) { if (signaturePassPhrase == null) {
throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase)); throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
} }
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray()); BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
@ -1202,7 +1210,6 @@ public class PGPMain {
if (forceV3Signature) { if (forceV3Signature) {
signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder);
signatureV3Generator.init(type, signaturePrivateKey); signatureV3Generator.init(type, signaturePrivateKey);
} else { } else {
signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
signatureGenerator.init(type, signaturePrivateKey); signatureGenerator.init(type, signaturePrivateKey);
@ -1261,6 +1268,51 @@ public class PGPMain {
progress.setProgress(R.string.progress_done, 100, 100); progress.setProgress(R.string.progress_done, 100, 100);
} }
public static PGPPublicKeyRing signKey(Context context, long masterKeyId, long pubKeyId)
throws GeneralException, NoSuchAlgorithmException, NoSuchProviderException,
PGPException, SignatureException {
String signaturePassPhrase = PGPMain.getCachedPassPhrase(masterKeyId);
if (signaturePassPhrase == null || signaturePassPhrase.length() <= 0) {
throw new GeneralException("Unable to obtain passphrase");
} else {
PGPPublicKeyRing pubring = PGPMain.getPublicKeyRing(pubKeyId);
PGPSecretKey signingKey = PGPHelper.getSigningKey(masterKeyId);
if (signingKey == null) {
throw new GeneralException(context.getString(R.string.error_signatureFailed));
}
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray());
PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
throw new GeneralException(
context.getString(R.string.error_couldNotExtractPrivateKey));
}
// TODO: SHA256 fixed?
JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(
signingKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256)
.setProvider(BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
contentSignerBuilder);
signatureGenerator.init(PGPSignature.DIRECT_KEY, signaturePrivateKey);
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
PGPSignatureSubpacketVector packetVector = spGen.generate();
signatureGenerator.setHashedSubpackets(packetVector);
PGPPublicKey signedKey = PGPPublicKey.addCertification(pubring.getPublicKey(pubKeyId),
signatureGenerator.generate());
pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey);
return pubring;
}
}
public static long getDecryptionKeyId(Context context, InputStream inputStream) public static long getDecryptionKeyId(Context context, InputStream inputStream)
throws GeneralException, NoAsymmetricEncryptionException, IOException { throws GeneralException, NoAsymmetricEncryptionException, IOException {
InputStream in = PGPUtil.getDecoderStream(inputStream); InputStream in = PGPUtil.getDecoderStream(inputStream);

View file

@ -28,18 +28,10 @@ import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Vector; import java.util.Vector;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
import org.spongycastle.openpgp.PGPSignatureGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
import org.spongycastle.openpgp.PGPUtil;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
@ -198,6 +190,9 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
public static final String RESULT_IMPORT_UPDATED = "updated"; public static final String RESULT_IMPORT_UPDATED = "updated";
public static final String RESULT_IMPORT_BAD = "bad"; public static final String RESULT_IMPORT_BAD = "bad";
// export
public static final String RESULT_EXPORT = "exported";
// query // query
public static final String RESULT_QUERY_KEY_KEY_DATA = "queryKeyKeyData"; public static final String RESULT_QUERY_KEY_KEY_DATA = "queryKeyKeyData";
public static final String RESULT_QUERY_KEY_SEARCH_RESULT = "queryKeySearchResult"; public static final String RESULT_QUERY_KEY_SEARCH_RESULT = "queryKeySearchResult";
@ -740,12 +735,10 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
try { try {
/* Input */ /* Input */
int keyRingId = data.getInt(UPLOAD_KEY_KEYRING_ID); int keyRingId = data.getInt(UPLOAD_KEY_KEYRING_ID);
String keyServer = data.getString(UPLOAD_KEY_SERVER); String keyServer = data.getString(UPLOAD_KEY_SERVER);
/* Operation */ /* Operation */
HkpKeyServer server = new HkpKeyServer(keyServer); HkpKeyServer server = new HkpKeyServer(keyServer);
PGPKeyRing keyring = PGPMain.getKeyRing(keyRingId); PGPKeyRing keyring = PGPMain.getKeyRing(keyRingId);
@ -770,7 +763,6 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
try { try {
/* Input */ /* Input */
int queryType = data.getInt(QUERY_KEY_TYPE); int queryType = data.getInt(QUERY_KEY_TYPE);
String keyServer = data.getString(QUERY_KEY_SERVER); String keyServer = data.getString(QUERY_KEY_SERVER);
@ -778,7 +770,6 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
long keyId = data.getLong(QUERY_KEY_ID); long keyId = data.getLong(QUERY_KEY_ID);
/* Operation */ /* Operation */
Bundle resultData = new Bundle(); Bundle resultData = new Bundle();
HkpKeyServer server = new HkpKeyServer(keyServer); HkpKeyServer server = new HkpKeyServer(keyServer);
@ -803,43 +794,16 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
try { try {
/* Input */ /* Input */
long masterKeyId = data.getLong(SIGN_KEY_MASTER_KEY_ID); long masterKeyId = data.getLong(SIGN_KEY_MASTER_KEY_ID);
long pubKeyId = data.getLong(SIGN_KEY_PUB_KEY_ID); long pubKeyId = data.getLong(SIGN_KEY_PUB_KEY_ID);
/* Operation */ /* Operation */
PGPPublicKeyRing signedPubKeyRing = PGPMain.signKey(this, masterKeyId, pubKeyId);
String passphrase = PGPMain.getCachedPassPhrase(masterKeyId); // store the signed key in our local cache
if (passphrase == null || passphrase.length() <= 0) { int retval = PGPMain.storeKeyRingInCache(signedPubKeyRing);
sendErrorToHandler(new GeneralException("Unable to obtain passphrase")); if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
} else { throw new GeneralException("Failed to store signed key in local cache");
PGPPublicKeyRing pubring = PGPMain.getPublicKeyRing(pubKeyId);
/*
* sign the incoming key
*/
PGPSecretKey secretKey = PGPMain.getSecretKey(masterKeyId);
PGPPrivateKey signingKey = secretKey.extractPrivateKey(
passphrase.toCharArray(), BouncyCastleProvider.PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(secretKey.getPublicKey()
.getAlgorithm(), PGPUtil.SHA256, BouncyCastleProvider.PROVIDER_NAME);
sGen.initSign(PGPSignature.DIRECT_KEY, signingKey);
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
PGPSignatureSubpacketVector packetVector = spGen.generate();
sGen.setHashedSubpackets(packetVector);
PGPPublicKey signedKey = PGPPublicKey.addCertification(
pubring.getPublicKey(pubKeyId), sGen.generate());
pubring = PGPPublicKeyRing.insertPublicKey(pubring, signedKey);
// store the signed key in our local cache
int retval = PGPMain.storeKeyRingInCache(pubring);
if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
sendErrorToHandler(new GeneralException(
"Failed to store signed key in local cache"));
}
} }
sendMessageToHandler(ApgServiceHandler.MESSAGE_OKAY); sendMessageToHandler(ApgServiceHandler.MESSAGE_OKAY);

View file

@ -20,6 +20,7 @@ import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.FileHelper; import org.thialfihar.android.apg.helper.FileHelper;
import org.thialfihar.android.apg.helper.OtherHelper;
import org.thialfihar.android.apg.helper.PGPHelper; import org.thialfihar.android.apg.helper.PGPHelper;
import org.thialfihar.android.apg.helper.PGPMain; import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.service.ApgServiceHandler; import org.thialfihar.android.apg.service.ApgServiceHandler;
@ -28,11 +29,9 @@ import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment;
import org.thialfihar.android.apg.ui.dialog.FileDialogFragment; import org.thialfihar.android.apg.ui.dialog.FileDialogFragment;
import org.thialfihar.android.apg.ui.dialog.LookupUnknownKeyDialogFragment; import org.thialfihar.android.apg.ui.dialog.LookupUnknownKeyDialogFragment;
import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment; import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment;
import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment;
import org.thialfihar.android.apg.util.Compatibility; import org.thialfihar.android.apg.util.Compatibility;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
@ -185,16 +184,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
setContentView(R.layout.decrypt); setContentView(R.layout.decrypt);
// set actionbar without home button if called from another app // set actionbar without home button if called from another app
final ActionBar actionBar = getSupportActionBar(); OtherHelper.setActionBarBackButton(this);
Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)="
+ getCallingPackage());
if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
} else {
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(false);
}
mSource = (ViewFlipper) findViewById(R.id.source); mSource = (ViewFlipper) findViewById(R.id.source);
mSourceLabel = (TextView) findViewById(R.id.sourceLabel); mSourceLabel = (TextView) findViewById(R.id.sourceLabel);

View file

@ -21,12 +21,12 @@ import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.OtherHelper;
import org.thialfihar.android.apg.helper.PGPHelper; import org.thialfihar.android.apg.helper.PGPHelper;
import org.thialfihar.android.apg.helper.PGPMain; import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.PGPConversionHelper; import org.thialfihar.android.apg.helper.PGPConversionHelper;
import org.thialfihar.android.apg.service.ApgServiceHandler; import org.thialfihar.android.apg.service.ApgServiceHandler;
import org.thialfihar.android.apg.service.ApgService; import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment;
import org.thialfihar.android.apg.ui.dialog.SetPassphraseDialogFragment; import org.thialfihar.android.apg.ui.dialog.SetPassphraseDialogFragment;
import org.thialfihar.android.apg.ui.widget.KeyEditor; import org.thialfihar.android.apg.ui.widget.KeyEditor;
import org.thialfihar.android.apg.ui.widget.SectionView; import org.thialfihar.android.apg.ui.widget.SectionView;
@ -138,14 +138,8 @@ public class EditKeyActivity extends SherlockFragmentActivity {
mActionBar = getSupportActionBar(); mActionBar = getSupportActionBar();
mActionBar.setDisplayShowTitleEnabled(true); mActionBar.setDisplayShowTitleEnabled(true);
// set actionbar without home button if called from another app // set actionbar without home button if called from another app
if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) { OtherHelper.setActionBarBackButton(this);
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setHomeButtonEnabled(true);
} else {
mActionBar.setDisplayHomeAsUpEnabled(false);
mActionBar.setHomeButtonEnabled(false);
}
// find views // find views
mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase); mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase);

View file

@ -24,6 +24,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.FileHelper; import org.thialfihar.android.apg.helper.FileHelper;
import org.thialfihar.android.apg.helper.OtherHelper;
import org.thialfihar.android.apg.helper.PGPHelper; import org.thialfihar.android.apg.helper.PGPHelper;
import org.thialfihar.android.apg.helper.PGPMain; import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.helper.Preferences; import org.thialfihar.android.apg.helper.Preferences;
@ -36,7 +37,6 @@ import org.thialfihar.android.apg.util.Choice;
import org.thialfihar.android.apg.util.Compatibility; import org.thialfihar.android.apg.util.Compatibility;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
@ -199,16 +199,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
setContentView(R.layout.encrypt); setContentView(R.layout.encrypt);
// set actionbar without home button if called from another app // set actionbar without home button if called from another app
final ActionBar actionBar = getSupportActionBar(); OtherHelper.setActionBarBackButton(this);
Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)="
+ getCallingPackage());
if (getCallingPackage() != null && getCallingPackage().equals(Constants.PACKAGE_NAME)) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
} else {
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(false);
}
mGenerateSignature = false; mGenerateSignature = false;
@ -703,7 +694,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
// Create a new Messenger for the communication back // Create a new Messenger for the communication back
Messenger messenger = new Messenger(returnHandler); Messenger messenger = new Messenger(returnHandler);
try { try {
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
messenger, mSecretKeyId); messenger, mSecretKeyId);

View file

@ -19,6 +19,7 @@ package org.thialfihar.android.apg.ui;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.OtherHelper;
import org.thialfihar.android.apg.helper.PGPHelper; import org.thialfihar.android.apg.helper.PGPHelper;
import org.thialfihar.android.apg.helper.PGPMain; import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.provider.KeyRings; import org.thialfihar.android.apg.provider.KeyRings;
@ -93,6 +94,9 @@ public class KeyListActivity extends SherlockFragmentActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.key_list); setContentView(R.layout.key_list);
// set actionbar without home button if called from another app
OtherHelper.setActionBarBackButton(this);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
mList = (ExpandableListView) findViewById(R.id.list); mList = (ExpandableListView) findViewById(R.id.list);
@ -152,18 +156,24 @@ public class KeyListActivity extends SherlockFragmentActivity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case Id.menu.option.import_keys: { case Id.menu.option.import_keys: {
// showDialog(Id.dialog.import_keys);
showImportKeysDialog(); showImportKeysDialog();
return true; return true;
} }
case Id.menu.option.export_keys: { case Id.menu.option.export_keys: {
// showDialog(Id.dialog.export_keys);
showExportKeysDialog(false); showExportKeysDialog(false);
return true; return true;
} }
case Id.menu.option.search: case Id.menu.option.search:
startSearch("", false, null, false); startSearch("", false, null, false);
return true; return true;
@ -401,7 +411,7 @@ public class KeyListActivity extends SherlockFragmentActivity {
// get returned data bundle // get returned data bundle
Bundle returnData = message.getData(); Bundle returnData = message.getData();
int exported = returnData.getInt("exported"); int exported = returnData.getInt(ApgService.RESULT_EXPORT);
String toastMessage; String toastMessage;
if (exported == 1) { if (exported == 1) {
toastMessage = getString(R.string.keyExported); toastMessage = getString(R.string.keyExported);
@ -724,7 +734,7 @@ public class KeyListActivity extends SherlockFragmentActivity {
mFileDialog.setFilename(path); mFileDialog.setFilename(path);
} catch (NullPointerException e) { } catch (NullPointerException e) {
Log.e(Constants.TAG, "Nullpointer while retrieving path!"); Log.e(Constants.TAG, "Nullpointer while retrieving path!", e);
} }
} }
return; return;

View file

@ -32,23 +32,27 @@ import android.view.View;
public class MainActivity extends SherlockActivity { public class MainActivity extends SherlockActivity {
public void manageKeysOnClick(View view) { public void manageKeysOnClick(View view) {
startActivity(new Intent(this, PublicKeyListActivity.class)); // used instead of startActivity set actionbar based on callingPackage
startActivityForResult(new Intent(this, PublicKeyListActivity.class), 0);
} }
public void myKeysOnClick(View view) { public void myKeysOnClick(View view) {
startActivity(new Intent(this, SecretKeyListActivity.class)); // used instead of startActivity set actionbar based on callingPackage
startActivityForResult(new Intent(this, SecretKeyListActivity.class), 0);
} }
public void encryptOnClick(View view) { public void encryptOnClick(View view) {
Intent intent = new Intent(MainActivity.this, EncryptActivity.class); Intent intent = new Intent(MainActivity.this, EncryptActivity.class);
intent.setAction(EncryptActivity.ACTION_ENCRYPT); intent.setAction(EncryptActivity.ACTION_ENCRYPT);
startActivityForResult(intent, 0); // used instead of startActivity to get callingPackage // used instead of startActivity set actionbar based on callingPackage
startActivityForResult(intent, 0);
} }
public void decryptOnClick(View view) { public void decryptOnClick(View view) {
Intent intent = new Intent(MainActivity.this, DecryptActivity.class); Intent intent = new Intent(MainActivity.this, DecryptActivity.class);
intent.setAction(DecryptActivity.ACTION_DECRYPT); intent.setAction(DecryptActivity.ACTION_DECRYPT);
startActivityForResult(intent, 0); // used instead of startActivity to get callingPackage // used instead of startActivity set actionbar based on callingPackage
startActivityForResult(intent, 0);
} }
public void scanQrcodeOnClick(View view) { public void scanQrcodeOnClick(View view) {

View file

@ -117,7 +117,7 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()) long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
.getGroupId(mSelectedItem); .getGroupId(mSelectedItem);
// String msg = keyId + "," + PGPHelper.getFingerPrint(keyId); // String msg = keyId + "," + PGPHelper.getFingerPrint(keyId);
String msg = PGPHelper.getPubkeyAsArmoredString(keyId); String msg = PGPHelper.getPubkeyAsArmoredString(this, keyId);
new IntentIntegrator(this).shareText(msg); new IntentIntegrator(this).shareText(msg);
} }

View file

@ -73,7 +73,7 @@ public class DeleteKeyDialogFragment extends DialogFragment {
final int keyType = getArguments().getInt(ARG_KEY_TYPE); final int keyType = getArguments().getInt(ARG_KEY_TYPE);
// TODO: better way to do this? // TODO: better way to do this?
String userId = "<unknown>"; String userId = activity.getString(R.string.unknownUserId);
Object keyRing = PGPMain.getKeyRing(deleteKeyRingId); Object keyRing = PGPMain.getKeyRing(deleteKeyRingId);
if (keyRing != null) { if (keyRing != null) {
if (keyRing instanceof PGPPublicKeyRing) { if (keyRing instanceof PGPPublicKeyRing) {

View file

@ -42,7 +42,6 @@ import org.thialfihar.android.apg.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
public class PassphraseDialogFragment extends DialogFragment { public class PassphraseDialogFragment extends DialogFragment {
@ -92,8 +91,7 @@ public class PassphraseDialogFragment extends DialogFragment {
private static boolean hasPassphrase(long secretKeyId) { private static boolean hasPassphrase(long secretKeyId) {
// check if the key has no passphrase // check if the key has no passphrase
try { try {
PGPSecretKey secretKey = PGPHelper.getMasterKey(PGPMain PGPSecretKey secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
.getSecretKeyRing(secretKeyId));
Log.d(Constants.TAG, "Check if key has no passphrase..."); Log.d(Constants.TAG, "Check if key has no passphrase...");
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
@ -132,7 +130,7 @@ public class PassphraseDialogFragment extends DialogFragment {
if (secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none) { if (secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none) {
secretKey = null; secretKey = null;
alert.setMessage(getString(R.string.passPhraseForSymmetricEncryption)); alert.setMessage(R.string.passPhraseForSymmetricEncryption);
} else { } else {
secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId)); secretKey = PGPHelper.getMasterKey(PGPMain.getSecretKeyRing(secretKeyId));
if (secretKey == null) { if (secretKey == null) {
@ -147,22 +145,17 @@ public class PassphraseDialogFragment extends DialogFragment {
return alert.create(); return alert.create();
} }
String userId = PGPHelper.getMainUserIdSafe(activity, secretKey); String userId = PGPHelper.getMainUserIdSafe(activity, secretKey);
Log.d(Constants.TAG, "User id: '" + userId + "'");
alert.setMessage(getString(R.string.passPhraseFor, userId)); alert.setMessage(getString(R.string.passPhraseFor, userId));
} }
LayoutInflater inflater = activity.getLayoutInflater(); LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.passphrase, null); View view = inflater.inflate(R.layout.passphrase, null);
final EditText input = (EditText) view.findViewById(R.id.passphrase_passphrase);
final TextView labelNotUsed = (TextView) view
.findViewById(R.id.passphrase_label_passphrase_again);
labelNotUsed.setVisibility(View.GONE);
final EditText inputNotUsed = (EditText) view
.findViewById(R.id.passphrase_passphrase_again);
inputNotUsed.setVisibility(View.GONE);
alert.setView(view); alert.setView(view);
final EditText input = (EditText) view.findViewById(R.id.passphrase_passphrase);
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
dismiss(); dismiss();
@ -172,7 +165,8 @@ public class PassphraseDialogFragment extends DialogFragment {
if (secretKey != null) { if (secretKey != null) {
try { try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(passPhrase.toCharArray()); .setProvider(PGPMain.BOUNCY_CASTLE_PROVIDER_NAME).build(
passPhrase.toCharArray());
PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor); PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
if (testKey == null) { if (testKey == null) {
Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey, Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey,

View file

@ -22,7 +22,6 @@ import org.thialfihar.android.apg.R;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.os.Message; import android.os.Message;
@ -80,9 +79,8 @@ public class SetPassphraseDialogFragment extends DialogFragment {
alert.setTitle(title); alert.setTitle(title);
alert.setMessage(R.string.enterPassPhraseTwice); alert.setMessage(R.string.enterPassPhraseTwice);
LayoutInflater inflater = (LayoutInflater) activity LayoutInflater inflater = activity.getLayoutInflater();
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.passphrase_repeat, null);
View view = inflater.inflate(R.layout.passphrase, null);
final EditText input1 = (EditText) view.findViewById(R.id.passphrase_passphrase); final EditText input1 = (EditText) view.findViewById(R.id.passphrase_passphrase);
final EditText input2 = (EditText) view.findViewById(R.id.passphrase_passphrase_again); final EditText input2 = (EditText) view.findViewById(R.id.passphrase_passphrase_again);