fixes for empty passphrase

This commit is contained in:
Dominik 2012-06-09 19:12:19 +03:00
parent 404ba01424
commit 5576a847a6
3 changed files with 85 additions and 54 deletions

View File

@ -507,8 +507,9 @@ public class Apg {
PGPPublicKey tmpKey = masterKey.getPublicKey();
PGPPublicKey masterPublicKey = new PGPPublicKey(tmpKey.getAlgorithm(),
tmpKey.getKey(new BouncyCastleProvider()), tmpKey.getCreationTime());
PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(oldPassPhrase.toCharArray(),
new BouncyCastleProvider());
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(oldPassPhrase.toCharArray());
PGPPrivateKey masterPrivateKey = masterKey.extractPrivateKey(keyDecryptor);
if (progress != null)
progress.setProgress(R.string.progress_certifyingMasterKey, 20, 100);
@ -572,8 +573,10 @@ public class Apg {
PGPSecretKey subKey = keys.get(i);
// keyEditor = (KeyEditor) keyEditors.getChildAt(i);
PGPPublicKey subPublicKey = subKey.getPublicKey();
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(oldPassPhrase.toCharArray(),
new BouncyCastleProvider());
PBESecretKeyDecryptor keyDecryptor2 = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(oldPassPhrase.toCharArray());
PGPPrivateKey subPrivateKey = subKey.extractPrivateKey(keyDecryptor2);
PGPKeyPair subKeyPair = new PGPKeyPair(subPublicKey.getAlgorithm(),
subPublicKey.getKey(new BouncyCastleProvider()), subPrivateKey.getKey(),
subPublicKey.getCreationTime());
@ -642,8 +645,10 @@ public class Apg {
PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
boolean save = true;
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(new char[] {});
PGPPrivateKey testKey = secretKeyRing.getSecretKey().extractPrivateKey(
new char[] {}, new BouncyCastleProvider());
keyDecryptor);
if (testKey == null) {
// this is bad, something is very wrong... likely a --export-secret-subkeys
// export
@ -1311,8 +1316,9 @@ public class Apg {
}
if (progress != null)
progress.setProgress(R.string.progress_extractingSignatureKey, 0, 100);
signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(),
new BouncyCastleProvider());
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
"SC").build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
throw new GeneralException(
context.getString(R.string.error_couldNotExtractPrivateKey));
@ -1450,8 +1456,9 @@ public class Apg {
if (signaturePassPhrase == null) {
throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
}
signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(),
new BouncyCastleProvider());
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
}
@ -1562,8 +1569,9 @@ public class Apg {
if (signaturePassPhrase == null) {
throw new GeneralException(context.getString(R.string.error_noSignaturePassPhrase));
}
signaturePrivateKey = signingKey.extractPrivateKey(signaturePassPhrase.toCharArray(),
new BouncyCastleProvider());
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(signaturePassPhrase.toCharArray());
signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor);
if (signaturePrivateKey == null) {
throw new GeneralException(context.getString(R.string.error_couldNotExtractPrivateKey));
}
@ -1804,8 +1812,9 @@ public class Apg {
progress.setProgress(R.string.progress_extractingKey, currentProgress, 100);
PGPPrivateKey privateKey = null;
try {
privateKey = secretKey.extractPrivateKey(passPhrase.toCharArray(),
new BouncyCastleProvider());
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(passPhrase.toCharArray());
privateKey = secretKey.extractPrivateKey(keyDecryptor);
} catch (PGPException e) {
throw new PGPException(context.getString(R.string.error_wrongPassPhrase));
}

View File

@ -649,7 +649,6 @@ public class EncryptActivity extends SherlockFragmentActivity {
}
if (getSecretKeyId() != 0 && Apg.getCachedPassPhrase(getSecretKeyId()) == null) {
// showDialog(Id.dialog.pass_phrase);
showPassphraseDialog();
return;
@ -672,7 +671,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.arg1 == PassphraseDialogFragment.MESSAGE_OKAY) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
if (mEncryptTarget == Id.target.file) {
askForOutputFilename();
} else {
@ -685,12 +684,15 @@ public class EncryptActivity extends SherlockFragmentActivity {
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(returnHandler);
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
mSecretKeyId, messenger);
try {
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
mSecretKeyId, messenger);
// no passphrase for this secret key -> passphraseDialog is null
if (passphraseDialog != null) {
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
} catch (Apg.GeneralException e) {
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
// send message to handler to start encryption directly
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
}
}

View File

@ -16,11 +16,13 @@
package org.thialfihar.android.apg.ui.dialog;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Apg.GeneralException;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R;
@ -59,17 +61,57 @@ public class PassphraseDialogFragment extends DialogFragment {
* @param messenger
* to communicate back after caching the passphrase
* @return
* @throws GeneralException
*/
public static PassphraseDialogFragment newInstance(long secretKeyId, Messenger messenger) {
public static PassphraseDialogFragment newInstance(long secretKeyId, Messenger messenger)
throws GeneralException {
// check if secret key has a passphrase
if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {
if (!hasPassphrase(secretKeyId)) {
throw new Apg.GeneralException("No passphrase! No passphrase dialog needed!");
}
}
PassphraseDialogFragment frag = new PassphraseDialogFragment();
Bundle args = new Bundle();
args.putLong(ARG_SECRET_KEY_ID, secretKeyId);
args.putParcelable(ARG_MESSENGER, messenger);
frag.setArguments(args);
return frag;
}
/**
* Checks if key has a passphrase
*
* @param secretKeyId
* @return true if it has a passphrase
*/
private static boolean hasPassphrase(long secretKeyId) {
// check if the key has no passphrase
try {
PGPSecretKey secretKey = Apg.getMasterKey(Apg.getSecretKeyRing(secretKeyId));
Log.d(Constants.TAG, "Check if key has no passphrase...");
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
"SC").build("".toCharArray());
PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
if (testKey != null) {
Log.d(Constants.TAG, "Key has no passphrase! Caches empty passphrase!");
// cache empty passphrase
Apg.setCachedPassPhrase(secretKey.getKeyID(), "");
return false;
}
} catch (PGPException e) {
// silently catch
}
return true;
}
/**
* Creates dialog
*/
@ -119,17 +161,17 @@ public class PassphraseDialogFragment extends DialogFragment {
alert.setView(view);
// final PassPhraseCallbackInterface cb = callback;
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// activity.removeDialog(Id.dialog.pass_phrase);
dismiss();
String passPhrase = input.getText().toString();
long keyId;
if (secretKey != null) {
try {
PGPPrivateKey testKey = secretKey.extractPrivateKey(
passPhrase.toCharArray(), new BouncyCastleProvider());
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider("SC").build(passPhrase.toCharArray());
PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
if (testKey == null) {
Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey,
Toast.LENGTH_SHORT).show();
@ -145,54 +187,32 @@ public class PassphraseDialogFragment extends DialogFragment {
keyId = Id.key.symmetric;
}
// cache again
// cache the new passphrase
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
Apg.setCachedPassPhrase(keyId, passPhrase);
// return by callback
// cb.passPhraseCallback(keyId, passPhrase);
sendMessageToHandler(MESSAGE_OKAY);
}
});
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// activity.removeDialog(Id.dialog.pass_phrase);
dismiss();
}
});
// check if the key has no passphrase
if (secretKey != null) {
try {
Log.d(Constants.TAG, "Check if key has no passphrase...");
PGPPrivateKey testKey = secretKey.extractPrivateKey("".toCharArray(),
new BouncyCastleProvider());
if (testKey != null) {
Log.d(Constants.TAG, "Key has no passphrase!");
// cache null
Apg.setCachedPassPhrase(secretKey.getKeyID(), null);
// return by callback
// cb.passPhraseCallback(secretKey.getKeyID(), null);
sendMessageToHandler(MESSAGE_OKAY);
return null;
}
} catch (PGPException e) {
}
}
return alert.create();
}
/**
* Send message back to handler which is initialized in a activity
*
* @param arg1
* Message you want to send
* @param what
* Message integer you want to send
*/
private void sendMessageToHandler(Integer arg1) {
private void sendMessageToHandler(Integer what) {
Message msg = Message.obtain();
msg.arg1 = arg1;
msg.what = what;
try {
mMessenger.send(msg);