aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2015-03-19 03:03:46 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2015-03-19 03:03:46 +0100
commit9c9f95c7acb92aad1f02e65271610fb3dca6c0dd (patch)
tree75660812ee2e08ad0f8761e87168228ca2cadea7
parentdbcb7a9e10ec4418337e0dce1b4227cbc3b7bd4a (diff)
downloadopen-keychain-9c9f95c7acb92aad1f02e65271610fb3dca6c0dd.tar.gz
open-keychain-9c9f95c7acb92aad1f02e65271610fb3dca6c0dd.tar.bz2
open-keychain-9c9f95c7acb92aad1f02e65271610fb3dca6c0dd.zip
New Passphrase class for safer passphrase handling in memory
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PassphraseCacheInterface.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java25
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java13
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java36
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java15
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java13
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java9
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java5
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java21
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java131
34 files changed, 307 insertions, 140 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java
index 40dcbd78d..a824e73d7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/BaseOperation.java
@@ -24,6 +24,7 @@ import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -101,7 +102,7 @@ public abstract class BaseOperation implements PassphraseCacheInterface {
}
@Override
- public String getCachedPassphrase(long subKeyId) throws NoSecretKeyException {
+ public Passphrase getCachedPassphrase(long subKeyId) throws NoSecretKeyException {
try {
long masterKeyId = mProviderHelper.getMasterKeyId(subKeyId);
return getCachedPassphrase(masterKeyId, subKeyId);
@@ -111,7 +112,7 @@ public abstract class BaseOperation implements PassphraseCacheInterface {
}
@Override
- public String getCachedPassphrase(long masterKeyId, long subKeyId) throws NoSecretKeyException {
+ public Passphrase getCachedPassphrase(long masterKeyId, long subKeyId) throws NoSecretKeyException {
try {
return PassphraseCacheService.getCachedPassphrase(
mContext, masterKeyId, subKeyId);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
index ebf0dc70b..4ceb34722 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/CertifyOperation.java
@@ -40,6 +40,7 @@ import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyActio
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -79,7 +80,7 @@ public class CertifyOperation extends BaseOperation {
}
// certification is always with the master key id, so use that one
- String passphrase = getCachedPassphrase(parcel.mMasterKeyId, parcel.mMasterKeyId);
+ Passphrase passphrase = getCachedPassphrase(parcel.mMasterKeyId, parcel.mMasterKeyId);
if (!certificationKey.unlock(passphrase)) {
log.add(LogType.MSG_CRT_ERROR_UNLOCK, 2);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
index bcd842dd0..a179b53ee 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/EditKeyOperation.java
@@ -35,6 +35,7 @@ import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -55,7 +56,7 @@ public class EditKeyOperation extends BaseOperation {
super(context, providerHelper, progressable, cancelled);
}
- public EditKeyResult execute(SaveKeyringParcel saveParcel, String passphrase) {
+ public EditKeyResult execute(SaveKeyringParcel saveParcel, Passphrase passphrase) {
OperationLog log = new OperationLog();
log.add(LogType.MSG_ED, 0);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
index 86b37fea6..7df37cd9b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DecryptVerifyResult.java
@@ -22,6 +22,7 @@ import android.os.Parcel;
import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult;
+import org.sufficientlysecure.keychain.util.Passphrase;
public class DecryptVerifyResult extends OperationResult {
@@ -37,7 +38,7 @@ public class DecryptVerifyResult extends OperationResult {
long mNfcSubKeyId;
byte[] mNfcSessionKey;
- String mNfcPassphrase;
+ Passphrase mNfcPassphrase;
OpenPgpSignatureResult mSignatureResult;
OpenPgpMetadata mDecryptMetadata;
@@ -53,7 +54,7 @@ public class DecryptVerifyResult extends OperationResult {
mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
}
- public void setNfcState(long subKeyId, byte[] sessionKey, String passphrase) {
+ public void setNfcState(long subKeyId, byte[] sessionKey, Passphrase passphrase) {
mNfcSubKeyId = subKeyId;
mNfcSessionKey = sessionKey;
mNfcPassphrase = passphrase;
@@ -67,7 +68,7 @@ public class DecryptVerifyResult extends OperationResult {
return mNfcSessionKey;
}
- public String getNfcPassphrase() {
+ public Passphrase getNfcPassphrase() {
return mNfcPassphrase;
}
@@ -109,7 +110,7 @@ public class DecryptVerifyResult extends OperationResult {
mSignatureResult = source.readParcelable(OpenPgpSignatureResult.class.getClassLoader());
mDecryptMetadata = source.readParcelable(OpenPgpMetadata.class.getClassLoader());
mNfcSessionKey = source.readInt() != 0 ? source.createByteArray() : null;
- mNfcPassphrase = source.readString();
+ mNfcPassphrase = source.readParcelable(Passphrase.class.getClassLoader());
}
public int describeContents() {
@@ -127,7 +128,7 @@ public class DecryptVerifyResult extends OperationResult {
} else {
dest.writeInt(0);
}
- dest.writeString(mNfcPassphrase);
+ dest.writeParcelable(mNfcPassphrase, flags);
}
public static final Creator<DecryptVerifyResult> CREATOR = new Creator<DecryptVerifyResult>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
index de2f64404..cf40001b3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/PgpSignEncryptResult.java
@@ -19,6 +19,8 @@ package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
+import org.sufficientlysecure.keychain.util.Passphrase;
+
import java.util.Date;
public class PgpSignEncryptResult extends OperationResult {
@@ -36,7 +38,7 @@ public class PgpSignEncryptResult extends OperationResult {
byte[] mNfcHash;
int mNfcAlgo;
Date mNfcTimestamp;
- String mNfcPassphrase;
+ Passphrase mNfcPassphrase;
byte[] mDetachedSignature;
public long getKeyIdPassphraseNeeded() {
@@ -47,7 +49,7 @@ public class PgpSignEncryptResult extends OperationResult {
mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
}
- public void setNfcData(long nfcKeyId, byte[] nfcHash, int nfcAlgo, Date nfcTimestamp, String passphrase) {
+ public void setNfcData(long nfcKeyId, byte[] nfcHash, int nfcAlgo, Date nfcTimestamp, Passphrase passphrase) {
mNfcKeyId = nfcKeyId;
mNfcHash = nfcHash;
mNfcAlgo = nfcAlgo;
@@ -75,7 +77,7 @@ public class PgpSignEncryptResult extends OperationResult {
return mNfcTimestamp;
}
- public String getNfcPassphrase() {
+ public Passphrase getNfcPassphrase() {
return mNfcPassphrase;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
index ab91d7747..6ce77394c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedSecretKey.java
@@ -41,6 +41,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.util.ArrayList;
import java.util.Date;
@@ -149,7 +150,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
/**
* Returns true on right passphrase
*/
- public boolean unlock(String passphrase) throws PgpGeneralException {
+ public boolean unlock(Passphrase passphrase) throws PgpGeneralException {
// handle keys on OpenPGP cards like they were unlocked
if (mSecretKey.getS2K() != null
&& mSecretKey.getS2K().getType() == S2K.GNU_DUMMY_S2K
@@ -161,7 +162,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
// try to extract keys using the passphrase
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray());
mPrivateKey = mSecretKey.extractPrivateKey(keyDecryptor);
mPrivateKeyState = PRIVATE_KEY_STATE_UNLOCKED;
} catch (PGPException e) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PassphraseCacheInterface.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PassphraseCacheInterface.java
index 0066bd23e..88ccccc6a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PassphraseCacheInterface.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PassphraseCacheInterface.java
@@ -18,14 +18,16 @@
package org.sufficientlysecure.keychain.pgp;
+import org.sufficientlysecure.keychain.util.Passphrase;
+
public interface PassphraseCacheInterface {
public static class NoSecretKeyException extends Exception {
public NoSecretKeyException() {
}
}
- public String getCachedPassphrase(long subKeyId) throws NoSecretKeyException;
+ public Passphrase getCachedPassphrase(long subKeyId) throws NoSecretKeyException;
- public String getCachedPassphrase(long masterKeyId, long subKeyId) throws NoSecretKeyException;
+ public Passphrase getCachedPassphrase(long masterKeyId, long subKeyId) throws NoSecretKeyException;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index 14bc56538..364a1067d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -60,6 +60,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import java.io.BufferedInputStream;
@@ -83,7 +84,7 @@ public class PgpDecryptVerify extends BaseOperation {
private OutputStream mOutStream;
private boolean mAllowSymmetricDecryption;
- private String mPassphrase;
+ private Passphrase mPassphrase;
private Set<Long> mAllowedKeyIds;
private boolean mDecryptMetadataOnly;
private byte[] mDecryptedSessionKey;
@@ -118,7 +119,7 @@ public class PgpDecryptVerify extends BaseOperation {
private OutputStream mOutStream = null;
private Progressable mProgressable = null;
private boolean mAllowSymmetricDecryption = true;
- private String mPassphrase = null;
+ private Passphrase mPassphrase = null;
private Set<Long> mAllowedKeyIds = null;
private boolean mDecryptMetadataOnly = false;
private byte[] mDecryptedSessionKey = null;
@@ -159,7 +160,7 @@ public class PgpDecryptVerify extends BaseOperation {
return this;
}
- public Builder setPassphrase(String passphrase) {
+ public Builder setPassphrase(Passphrase passphrase) {
mPassphrase = passphrase;
return this;
}
@@ -572,7 +573,7 @@ public class PgpDecryptVerify extends BaseOperation {
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build();
PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder(
digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- mPassphrase.toCharArray());
+ mPassphrase.getCharArray());
clear = encryptedDataSymmetric.getDataStream(decryptorFactory);
encryptedData = encryptedDataSymmetric;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index 8fb5392e3..b3bf92364 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -57,6 +57,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Primes;
import org.sufficientlysecure.keychain.util.ProgressScaler;
@@ -316,7 +317,7 @@ public class PgpKeyOperation {
masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator());
subProgressPush(50, 100);
- return internal(sKR, masterSecretKey, add.mFlags, add.mExpiry, saveParcel, "", log);
+ return internal(sKR, masterSecretKey, add.mFlags, add.mExpiry, saveParcel, new Passphrase(), log);
} catch (PGPException e) {
log.add(LogType.MSG_CR_ERROR_INTERNAL_PGP, indent);
@@ -348,7 +349,7 @@ public class PgpKeyOperation {
*
*/
public PgpEditKeyResult modifySecretKeyRing(CanonicalizedSecretKeyRing wsKR, SaveKeyringParcel saveParcel,
- String passphrase) {
+ Passphrase passphrase) {
OperationLog log = new OperationLog();
int indent = 0;
@@ -404,7 +405,7 @@ public class PgpKeyOperation {
private PgpEditKeyResult internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey,
int masterKeyFlags, long masterKeyExpiry,
- SaveKeyringParcel saveParcel, String passphrase,
+ SaveKeyringParcel saveParcel, Passphrase passphrase,
OperationLog log) {
int indent = 1;
@@ -420,7 +421,7 @@ public class PgpKeyOperation {
{
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray());
masterPrivateKey = masterSecretKey.extractPrivateKey(keyDecryptor);
} catch (PGPException e) {
log.add(LogType.MSG_MF_UNLOCK_ERROR, indent + 1);
@@ -839,7 +840,7 @@ public class PgpKeyOperation {
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray());
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
.build().get(PgpConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
@@ -967,7 +968,7 @@ public class PgpKeyOperation {
PGPSecretKeyRing sKR,
PGPPublicKey masterPublicKey,
PGPPrivateKey masterPrivateKey,
- String passphrase,
+ Passphrase passphrase,
ChangeUnlockParcel newUnlock,
OperationLog log, int indent) throws PGPException {
@@ -1051,20 +1052,20 @@ public class PgpKeyOperation {
private static PGPSecretKeyRing applyNewPassphrase(
PGPSecretKeyRing sKR,
PGPPublicKey masterPublicKey,
- String passphrase,
- String newPassphrase,
+ Passphrase passphrase,
+ Passphrase newPassphrase,
OperationLog log, int indent) throws PGPException {
PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder().build()
.get(PgpConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
- Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
+ Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray());
// Build key encryptor based on new passphrase
PBESecretKeyEncryptor keyEncryptorNew = new JcePBESecretKeyEncryptorBuilder(
PgpConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
PgpConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- newPassphrase.toCharArray());
+ newPassphrase.getCharArray());
// noinspection unchecked
for (PGPSecretKey sKey : new IterableIterator<PGPSecretKey>(sKR.getSecretKeys())) {
@@ -1295,11 +1296,11 @@ public class PgpKeyOperation {
private static PGPSignature generateSubkeyBindingSignature(
PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey,
- PGPSecretKey sKey, PGPPublicKey pKey, int flags, long expiry, String passphrase)
+ PGPSecretKey sKey, PGPPublicKey pKey, int flags, long expiry, Passphrase passphrase)
throws IOException, PGPException, SignatureException {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- passphrase.toCharArray());
+ passphrase.getCharArray());
PGPPrivateKey subPrivateKey = sKey.extractPrivateKey(keyDecryptor);
return generateSubkeyBindingSignature(masterPublicKey, masterPrivateKey, subPrivateKey,
pKey, flags, expiry);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
index 2dec4b9c2..4a920685a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptInput.java
@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.util.Date;
@@ -29,12 +30,12 @@ public class PgpSignEncryptInput {
protected boolean mEnableAsciiArmorOutput = false;
protected int mCompressionId = CompressionAlgorithmTags.UNCOMPRESSED;
protected long[] mEncryptionMasterKeyIds = null;
- protected String mSymmetricPassphrase = null;
+ protected Passphrase mSymmetricPassphrase = null;
protected int mSymmetricEncryptionAlgorithm = PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED;
protected long mSignatureMasterKeyId = Constants.key.none;
protected Long mSignatureSubKeyId = null;
protected int mSignatureHashAlgorithm = PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED;
- protected String mSignaturePassphrase = null;
+ protected Passphrase mSignaturePassphrase = null;
protected long mAdditionalEncryptId = Constants.key.none;
protected byte[] mNfcSignedHash = null;
protected Date mNfcCreationTimestamp = null;
@@ -73,11 +74,11 @@ public class PgpSignEncryptInput {
return this;
}
- public String getSignaturePassphrase() {
+ public Passphrase getSignaturePassphrase() {
return mSignaturePassphrase;
}
- public PgpSignEncryptInput setSignaturePassphrase(String signaturePassphrase) {
+ public PgpSignEncryptInput setSignaturePassphrase(Passphrase signaturePassphrase) {
mSignaturePassphrase = signaturePassphrase;
return this;
}
@@ -118,11 +119,11 @@ public class PgpSignEncryptInput {
return this;
}
- public String getSymmetricPassphrase() {
+ public Passphrase getSymmetricPassphrase() {
return mSymmetricPassphrase;
}
- public PgpSignEncryptInput setSymmetricPassphrase(String symmetricPassphrase) {
+ public PgpSignEncryptInput setSymmetricPassphrase(Passphrase symmetricPassphrase) {
mSymmetricPassphrase = symmetricPassphrase;
return this;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
index 94e04060d..bd3c31d3a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java
@@ -243,7 +243,7 @@ public class PgpSignEncryptOperation extends BaseOperation {
log.add(LogType.MSG_PSE_SYMMETRIC, indent);
JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
- new JcePBEKeyEncryptionMethodGenerator(input.getSymmetricPassphrase().toCharArray());
+ new JcePBEKeyEncryptionMethodGenerator(input.getSymmetricPassphrase().getCharArray());
cPk.addMethod(symmetricEncryptionGenerator);
} else {
log.add(LogType.MSG_PSE_ASYMMETRIC, indent);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java
index 8e71e8815..975548c95 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/SignEncryptParcel.java
@@ -22,6 +22,8 @@ import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import org.sufficientlysecure.keychain.util.Passphrase;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -57,12 +59,12 @@ public class SignEncryptParcel extends PgpSignEncryptInput implements Parcelable
mEnableAsciiArmorOutput = src.readInt() == 1;
mCompressionId = src.readInt();
mEncryptionMasterKeyIds = src.createLongArray();
- mSymmetricPassphrase = src.readString();
+ mSymmetricPassphrase = src.readParcelable(Passphrase.class.getClassLoader());
mSymmetricEncryptionAlgorithm = src.readInt();
mSignatureMasterKeyId = src.readLong();
mSignatureSubKeyId = src.readInt() == 1 ? src.readLong() : null;
mSignatureHashAlgorithm = src.readInt();
- mSignaturePassphrase = src.readString();
+ mSignaturePassphrase = src.readParcelable(Passphrase.class.getClassLoader());
mAdditionalEncryptId = src.readLong();
mNfcSignedHash = src.createByteArray();
mNfcCreationTimestamp = src.readInt() == 1 ? new Date(src.readLong()) : null;
@@ -112,7 +114,7 @@ public class SignEncryptParcel extends PgpSignEncryptInput implements Parcelable
dest.writeInt(mEnableAsciiArmorOutput ? 1 : 0);
dest.writeInt(mCompressionId);
dest.writeLongArray(mEncryptionMasterKeyIds);
- dest.writeString(mSymmetricPassphrase);
+ dest.writeParcelable(mSymmetricPassphrase, flags);
dest.writeInt(mSymmetricEncryptionAlgorithm);
dest.writeLong(mSignatureMasterKeyId);
if (mSignatureSubKeyId != null) {
@@ -122,7 +124,7 @@ public class SignEncryptParcel extends PgpSignEncryptInput implements Parcelable
dest.writeInt(0);
}
dest.writeInt(mSignatureHashAlgorithm);
- dest.writeString(mSignaturePassphrase);
+ dest.writeParcelable(mSignaturePassphrase, flags);
dest.writeLong(mAdditionalEncryptId);
dest.writeByteArray(mNfcSignedHash);
if (mNfcCreationTimestamp != null) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index a4bc95602..98a9ff44f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -54,6 +54,7 @@ import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.io.IOException;
import java.io.InputStream;
@@ -179,7 +180,7 @@ public class OpenPgpService extends RemoteService {
return result;
}
- private PendingIntent getNfcSignPendingIntent(Intent data, long keyId, String pin, byte[] hashToSign, int hashAlgo) {
+ private PendingIntent getNfcSignPendingIntent(Intent data, long keyId, Passphrase pin, byte[] hashToSign, int hashAlgo) {
// build PendingIntent for Yubikey NFC operations
Intent intent = new Intent(getBaseContext(), NfcActivity.class);
intent.setAction(NfcActivity.ACTION_SIGN_HASH);
@@ -195,7 +196,7 @@ public class OpenPgpService extends RemoteService {
PendingIntent.FLAG_CANCEL_CURRENT);
}
- private PendingIntent getNfcDecryptPendingIntent(Intent data, long subKeyId, String pin, byte[] encryptedSessionKey) {
+ private PendingIntent getNfcDecryptPendingIntent(Intent data, long subKeyId, Passphrase pin, byte[] encryptedSessionKey) {
// build PendingIntent for Yubikey NFC operations
Intent intent = new Intent(getBaseContext(), NfcActivity.class);
intent.setAction(NfcActivity.ACTION_DECRYPT_SESSION_KEY);
@@ -508,7 +509,7 @@ public class OpenPgpService extends RemoteService {
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
}
- String passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
+ Passphrase passphrase = data.getParcelableExtra(OpenPgpApi.EXTRA_PASSPHRASE);
long inputLength = is.available();
InputData inputData = new InputData(is, inputLength);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index bf6a62782..d5f13f7ce 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -65,6 +65,7 @@ import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -281,7 +282,7 @@ public class KeychainIntentService extends IntentService implements Progressable
try {
/* Input */
- String passphrase = data.getString(DECRYPT_PASSPHRASE);
+ Passphrase passphrase = data.getParcelable(DECRYPT_PASSPHRASE);
byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
InputData inputData = createDecryptInputData(data);
@@ -411,7 +412,7 @@ public class KeychainIntentService extends IntentService implements Progressable
try {
/* Input */
- String passphrase = data.getString(DECRYPT_PASSPHRASE);
+ Passphrase passphrase = data.getParcelable(DECRYPT_PASSPHRASE);
byte[] nfcDecryptedSessionKey = data.getByteArray(DECRYPT_NFC_DECRYPTED_SESSION_KEY);
InputData inputData = createDecryptInputData(data);
@@ -469,7 +470,7 @@ public class KeychainIntentService extends IntentService implements Progressable
// Input
SaveKeyringParcel saveParcel = data.getParcelable(EDIT_KEYRING_PARCEL);
- String passphrase = data.getString(EDIT_KEYRING_PASSPHRASE);
+ Passphrase passphrase = data.getParcelable(EDIT_KEYRING_PASSPHRASE);
// Operation
EditKeyOperation op = new EditKeyOperation(this, providerHelper, this, mActionCanceled);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
index 57881f8ee..ee481ad31 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
import java.util.Date;
@@ -121,7 +122,7 @@ public class PassphraseCacheService extends Service {
* new events to the alarm manager for new passphrases to let them timeout in the future.
*/
public static void addCachedPassphrase(Context context, long masterKeyId, long subKeyId,
- String passphrase,
+ Passphrase passphrase,
String primaryUserId) {
Log.d(Constants.TAG, "PassphraseCacheService.cacheNewPassphrase() for " + masterKeyId);
@@ -143,7 +144,7 @@ public class PassphraseCacheService extends Service {
* @return passphrase or null (if no passphrase is cached for this keyId)
*/
- public static String getCachedPassphrase(Context context, long masterKeyId, long subKeyId) throws KeyNotFoundException {
+ public static Passphrase getCachedPassphrase(Context context, long masterKeyId, long subKeyId) throws KeyNotFoundException {
Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphrase() for masterKeyId "
+ masterKeyId + ", subKeyId " + subKeyId);
@@ -190,7 +191,9 @@ public class PassphraseCacheService extends Service {
switch (returnMessage.what) {
case MSG_PASSPHRASE_CACHE_GET_OKAY:
- return returnMessage.getData().getString(EXTRA_PASSPHRASE);
+ Bundle returnData = returnMessage.getData();
+ returnData.setClassLoader(context.getClassLoader());
+ return returnData.getParcelable(EXTRA_PASSPHRASE);
case MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND:
throw new KeyNotFoundException();
default:
@@ -202,11 +205,11 @@ public class PassphraseCacheService extends Service {
/**
* Internal implementation to get cached passphrase.
*/
- private String getCachedPassphraseImpl(long masterKeyId, long subKeyId) throws ProviderHelper.NotFoundException {
+ private Passphrase getCachedPassphraseImpl(long masterKeyId, long subKeyId) throws ProviderHelper.NotFoundException {
// passphrase for symmetric encryption?
if (masterKeyId == Constants.key.symmetric) {
Log.d(Constants.TAG, "PassphraseCacheService.getCachedPassphraseImpl() for symmetric encryption");
- String cachedPassphrase = mPassphraseCache.get(Constants.key.symmetric).getPassphrase();
+ Passphrase cachedPassphrase = mPassphraseCache.get(Constants.key.symmetric).getPassphrase();
if (cachedPassphrase == null) {
return null;
}
@@ -232,13 +235,13 @@ public class PassphraseCacheService extends Service {
case DIVERT_TO_CARD:
if (Preferences.getPreferences(this).useDefaultYubikeyPin()) {
Log.d(Constants.TAG, "PassphraseCacheService: Using default Yubikey PIN: 123456");
- return "123456"; // default Yubikey PIN, see http://www.yubico.com/2012/12/yubikey-neo-openpgp/
+ return new Passphrase("123456"); // default Yubikey PIN, see http://www.yubico.com/2012/12/yubikey-neo-openpgp/
} else {
Log.d(Constants.TAG, "PassphraseCacheService: NOT using default Yubikey PIN");
break;
}
case PASSPHRASE_EMPTY:
- return "";
+ return new Passphrase("");
case UNAVAILABLE:
throw new ProviderHelper.NotFoundException("secret key for this subkey is not available");
case GNU_DUMMY:
@@ -331,7 +334,7 @@ public class PassphraseCacheService extends Service {
long masterKeyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
long subKeyId = intent.getLongExtra(EXTRA_SUBKEY_ID, -1);
- String passphrase = intent.getStringExtra(EXTRA_PASSPHRASE);
+ Passphrase passphrase = intent.getParcelableExtra(EXTRA_PASSPHRASE);
String primaryUserID = intent.getStringExtra(EXTRA_USER_ID);
Log.d(Constants.TAG,
@@ -373,10 +376,10 @@ public class PassphraseCacheService extends Service {
Log.e(Constants.TAG, "PassphraseCacheService: Bad request, missing masterKeyId or subKeyId!");
msg.what = MSG_PASSPHRASE_CACHE_GET_KEY_NOT_FOUND;
} else {
- String passphrase = getCachedPassphraseImpl(masterKeyId, subKeyId);
+ Passphrase passphrase = getCachedPassphraseImpl(masterKeyId, subKeyId);
msg.what = MSG_PASSPHRASE_CACHE_GET_OKAY;
Bundle bundle = new Bundle();
- bundle.putString(EXTRA_PASSPHRASE, passphrase);
+ bundle.putParcelable(EXTRA_PASSPHRASE, passphrase);
msg.setData(bundle);
}
} catch (ProviderHelper.NotFoundException e) {
@@ -412,7 +415,10 @@ public class PassphraseCacheService extends Service {
* Called when one specific passphrase for keyId timed out
*/
private void timeout(Context context, long keyId) {
- // remove passphrase corresponding to keyId from memory
+ CachedPassphrase cPass = mPassphraseCache.get(keyId);
+ // clean internal char[] from memory!
+ cPass.getPassphrase().removeFromMemory();
+ // remove passphrase object
mPassphraseCache.remove(keyId);
Log.d(Constants.TAG, "PassphraseCacheService Timeout of keyId " + keyId + ", removed from memory!");
@@ -517,9 +523,9 @@ public class PassphraseCacheService extends Service {
public class CachedPassphrase {
private String primaryUserID;
- private String passphrase;
+ private Passphrase passphrase;
- public CachedPassphrase(String passphrase, String primaryUserID) {
+ public CachedPassphrase(Passphrase passphrase, String primaryUserID) {
setPassphrase(passphrase);
setPrimaryUserID(primaryUserID);
}
@@ -528,7 +534,7 @@ public class PassphraseCacheService extends Service {
return primaryUserID;
}
- public String getPassphrase() {
+ public Passphrase getPassphrase() {
return passphrase;
}
@@ -536,7 +542,7 @@ public class PassphraseCacheService extends Service {
this.primaryUserID = primaryUserID;
}
- public void setPassphrase(String passphrase) {
+ public void setPassphrase(Passphrase passphrase) {
this.passphrase = passphrase;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
index e2d0c03c9..9fd278c13 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
@@ -22,6 +22,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.io.Serializable;
import java.util.ArrayList;
@@ -296,33 +297,30 @@ public class SaveKeyringParcel implements Parcelable {
public static class ChangeUnlockParcel implements Parcelable {
// The new passphrase to use
- public final String mNewPassphrase;
+ public final Passphrase mNewPassphrase;
// A new pin to use. Must only contain [0-9]+
- public final String mNewPin;
+ public final Passphrase mNewPin;
- public ChangeUnlockParcel(String newPassphrase) {
+ public ChangeUnlockParcel(Passphrase newPassphrase) {
this(newPassphrase, null);
}
- public ChangeUnlockParcel(String newPassphrase, String newPin) {
+ public ChangeUnlockParcel(Passphrase newPassphrase, Passphrase newPin) {
if (newPassphrase == null && newPin == null) {
throw new RuntimeException("Cannot set both passphrase and pin. THIS IS A BUG!");
}
- if (newPin != null && !newPin.matches("[0-9]+")) {
- throw new RuntimeException("Pin must be numeric digits only. THIS IS A BUG!");
- }
mNewPassphrase = newPassphrase;
mNewPin = newPin;
}
public ChangeUnlockParcel(Parcel source) {
- mNewPassphrase = source.readString();
- mNewPin = source.readString();
+ mNewPassphrase = source.readParcelable(Passphrase.class.getClassLoader());
+ mNewPin = source.readParcelable(Passphrase.class.getClassLoader());
}
@Override
public void writeToParcel(Parcel destination, int flags) {
- destination.writeString(mNewPassphrase);
- destination.writeString(mNewPin);
+ destination.writeParcelable(mNewPassphrase, flags);
+ destination.writeParcelable(mNewPin, flags);
}
@Override
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
index 9cb4e5f65..a0f89b06a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
@@ -62,6 +62,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner;
import org.sufficientlysecure.keychain.ui.widget.KeySpinner;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
import java.lang.reflect.Method;
@@ -318,7 +319,7 @@ public class CertifyKeyFragment extends LoaderFragment
*/
private void initiateCertifying() {
// get the user's passphrase for this key (if required)
- String passphrase;
+ Passphrase passphrase;
try {
passphrase = PassphraseCacheService.getCachedPassphrase(getActivity(), mSignMasterKeyId, mSignMasterKeyId);
} catch (PassphraseCacheService.KeyNotFoundException e) {
@@ -341,7 +342,6 @@ public class CertifyKeyFragment extends LoaderFragment
switch (requestCode) {
case REQUEST_CODE_PASSPHRASE: {
if (resultCode == Activity.RESULT_OK && data != null) {
- String passphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
startCertifying();
}
return;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
index 2da5511b8..0eb9e948a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
@@ -23,11 +23,20 @@ import android.support.v4.app.FragmentTransaction;
import org.sufficientlysecure.keychain.R;
+import java.util.ArrayList;
+
public class CreateKeyActivity extends BaseActivity {
public static final String EXTRA_NAME = "name";
public static final String EXTRA_EMAIL = "email";
+ public class State {
+ String name;
+ String email;
+ ArrayList<String> additionalEmails;
+ char[] passphrase;
+ }
+
public static enum FragAction {
START,
TO_RIGHT,
@@ -44,7 +53,7 @@ public class CreateKeyActivity extends BaseActivity {
getIntent().getStringExtra(EXTRA_NAME),
getIntent().getStringExtra(EXTRA_EMAIL)
);
- loadFragment(null, frag, FragAction.START);
+ loadFragment(savedInstanceState, frag, FragAction.START);
}
@Override
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java
index 66424e012..6a4dd7a41 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java
@@ -85,7 +85,7 @@ public class CreateKeyEmailFragment extends Fragment {
*/
private static boolean isEditTextNotEmpty(Context context, EditText editText) {
boolean output = true;
- if (editText.getText().toString().length() == 0) {
+ if (editText.getText().length() == 0) {
editText.setError(context.getString(R.string.create_key_empty));
editText.requestFocus();
output = false;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
index 4871b5ae2..5f6bfdb11 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
@@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
import java.util.ArrayList;
@@ -72,7 +73,7 @@ public class CreateKeyFinalFragment extends Fragment {
String mName;
String mEmail;
ArrayList<String> mAdditionalEmails;
- String mPassphrase;
+ Passphrase mPassphrase;
SaveKeyringParcel mSaveKeyringParcel;
@@ -81,14 +82,14 @@ public class CreateKeyFinalFragment extends Fragment {
*/
public static CreateKeyFinalFragment newInstance(String name, String email,
ArrayList<String> additionalEmails,
- String passphrase) {
+ Passphrase passphrase) {
CreateKeyFinalFragment frag = new CreateKeyFinalFragment();
Bundle args = new Bundle();
args.putString(ARG_NAME, name);
args.putString(ARG_EMAIL, email);
args.putStringArrayList(ARG_ADDITIONAL_EMAILS, additionalEmails);
- args.putString(ARG_PASSPHRASE, passphrase);
+ args.putParcelable(ARG_PASSPHRASE, passphrase);
frag.setArguments(args);
@@ -111,7 +112,7 @@ public class CreateKeyFinalFragment extends Fragment {
mName = getArguments().getString(ARG_NAME);
mEmail = getArguments().getString(ARG_EMAIL);
mAdditionalEmails = getArguments().getStringArrayList(ARG_ADDITIONAL_EMAILS);
- mPassphrase = getArguments().getString(ARG_PASSPHRASE);
+ mPassphrase = getArguments().getParcelable(ARG_PASSPHRASE);
// set values
mNameEdit.setText(mName);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java
index 50a3bd655..093d427b7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java
@@ -68,7 +68,7 @@ public class CreateKeyNameFragment extends Fragment {
*/
private static boolean isEditTextNotEmpty(Context context, EditText editText) {
boolean output = true;
- if (editText.getText().toString().length() == 0) {
+ if (editText.getText().length() == 0) {
editText.setError(context.getString(R.string.create_key_empty));
editText.requestFocus();
output = false;
@@ -79,19 +79,6 @@ public class CreateKeyNameFragment extends Fragment {
return output;
}
- private static boolean areEditTextsEqual(Context context, EditText editText1, EditText editText2) {
- boolean output = true;
- if (!editText1.getText().toString().equals(editText2.getText().toString())) {
- editText2.setError(context.getString(R.string.create_key_passphrases_not_equal));
- editText2.requestFocus();
- output = false;
- } else {
- editText2.setError(null);
- }
-
- return output;
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.create_key_name_fragment, container, false);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
index 055ea608b..a10c94093 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
@@ -34,6 +34,7 @@ import android.widget.EditText;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.util.ArrayList;
@@ -83,7 +84,7 @@ public class CreateKeyPassphraseFragment extends Fragment {
*/
private static boolean isEditTextNotEmpty(Context context, EditText editText) {
boolean output = true;
- if (editText.getText().toString().length() == 0) {
+ if (editText.getText().length() == 0) {
editText.setError(context.getString(R.string.create_key_empty));
editText.requestFocus();
output = false;
@@ -95,11 +96,13 @@ public class CreateKeyPassphraseFragment extends Fragment {
}
private static boolean areEditTextsEqual(Context context, EditText editText1, EditText editText2) {
- boolean output = true;
- if (!editText1.getText().toString().equals(editText2.getText().toString())) {
+ Passphrase p1 = new Passphrase(editText1);
+ Passphrase p2 = new Passphrase(editText2);
+ boolean output = (p1.equals(p2));
+
+ if (!output) {
editText2.setError(context.getString(R.string.create_key_passphrases_not_equal));
editText2.requestFocus();
- output = false;
} else {
editText2.setError(null);
}
@@ -171,7 +174,7 @@ public class CreateKeyPassphraseFragment extends Fragment {
mName,
mEmail,
mAdditionalEmails,
- mPassphraseEdit.getText().toString()
+ new Passphrase(mPassphraseEdit.getText())
);
hideKeyboard();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
index 7e33843ea..71832daa5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
@@ -191,7 +191,7 @@ public class DecryptFilesFragment extends DecryptFragment {
data.putInt(KeychainIntentService.TARGET, IOType.URI.ordinal());
data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_OUTPUT_URI, mOutputUri);
- data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase);
+ data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase);
data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@@ -265,7 +265,7 @@ public class DecryptFilesFragment extends DecryptFragment {
data.putInt(KeychainIntentService.TARGET, IOType.URI.ordinal());
data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_OUTPUT_URI, mOutputUri);
- data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase);
+ data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase);
data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@@ -341,7 +341,7 @@ public class DecryptFilesFragment extends DecryptFragment {
switch (requestCode) {
case REQUEST_CODE_PASSPHRASE: {
if (resultCode == Activity.RESULT_OK && data != null) {
- mPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
+ mPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
decryptOriginalFilename();
}
return;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
index 513300cc5..63508e530 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java
@@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
+import org.sufficientlysecure.keychain.util.Passphrase;
public abstract class DecryptFragment extends Fragment {
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
@@ -57,7 +58,7 @@ public abstract class DecryptFragment extends Fragment {
// State
- protected String mPassphrase;
+ protected Passphrase mPassphrase;
protected byte[] mNfcDecryptedSessionKey;
@Override
@@ -100,7 +101,7 @@ public abstract class DecryptFragment extends Fragment {
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
}
- protected void startNfcDecrypt(long subKeyId, String pin, byte[] encryptedSessionKey) {
+ protected void startNfcDecrypt(long subKeyId, Passphrase pin, byte[] encryptedSessionKey) {
// build PendingIntent for Yubikey NFC operations
Intent intent = new Intent(getActivity(), NfcActivity.class);
intent.setAction(NfcActivity.ACTION_DECRYPT_SESSION_KEY);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
index 1b34f6bf0..30cf739fc 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
@@ -161,7 +161,7 @@ public class DecryptTextFragment extends DecryptFragment {
// data
data.putInt(KeychainIntentService.TARGET, IOType.BYTES.ordinal());
data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes());
- data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase);
+ data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase);
data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@@ -247,7 +247,7 @@ public class DecryptTextFragment extends DecryptFragment {
case REQUEST_CODE_PASSPHRASE: {
if (resultCode == Activity.RESULT_OK && data != null) {
- mPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
+ mPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
decryptStart();
} else {
getActivity().finish();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
index 8d16fe47e..d2c1ab74c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
@@ -67,6 +67,7 @@ import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
public class EditKeyFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
@@ -100,7 +101,7 @@ public class EditKeyFragment extends LoaderFragment implements
private SaveKeyringParcel mSaveKeyringParcel;
private String mPrimaryUserId;
- private String mCurrentPassphrase;
+ private Passphrase mCurrentPassphrase;
/**
* Creates new instance of this fragment
@@ -267,7 +268,7 @@ public class EditKeyFragment extends LoaderFragment implements
switch (requestCode) {
case REQUEST_CODE_PASSPHRASE: {
if (resultCode == Activity.RESULT_OK && data != null) {
- mCurrentPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
+ mCurrentPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
// Prepare the loaders. Either re-connect with an existing ones,
// or start new ones.
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, EditKeyFragment.this);
@@ -386,7 +387,7 @@ public class EditKeyFragment extends LoaderFragment implements
// cache new returned passphrase!
mSaveKeyringParcel.mNewUnlock = new ChangeUnlockParcel(
- data.getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE),
+ (Passphrase) data.getParcelable(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE),
null
);
}
@@ -593,7 +594,7 @@ public class EditKeyFragment extends LoaderFragment implements
getActivity().finish();
}
- private void saveInDatabase(String passphrase) {
+ private void saveInDatabase(Passphrase passphrase) {
Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel.toString());
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
@@ -640,7 +641,7 @@ public class EditKeyFragment extends LoaderFragment implements
// fill values for this action
Bundle data = new Bundle();
- data.putString(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase);
+ data.putParcelable(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase);
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index 35dfcb87c..5438f667c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.util.Date;
@@ -41,7 +42,7 @@ public abstract class EncryptActivity extends BaseActivity {
public static final int REQUEST_CODE_NFC = 0x00008002;
// For NFC data
- protected String mSigningKeyPassphrase = null;
+ protected Passphrase mSigningKeyPassphrase = null;
protected Date mNfcTimestamp = null;
protected byte[] mNfcHash = null;
@@ -64,7 +65,7 @@ public abstract class EncryptActivity extends BaseActivity {
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
}
- protected void startNfcSign(long keyId, String pin, byte[] hashToSign, int hashAlgo) {
+ protected void startNfcSign(long keyId, Passphrase pin, byte[] hashToSign, int hashAlgo) {
// build PendingIntent for Yubikey NFC operations
Intent intent = new Intent(this, NfcActivity.class);
intent.setAction(NfcActivity.ACTION_SIGN_HASH);
@@ -84,7 +85,7 @@ public abstract class EncryptActivity extends BaseActivity {
switch (requestCode) {
case REQUEST_CODE_PASSPHRASE: {
if (resultCode == RESULT_OK && data != null) {
- mSigningKeyPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
+ mSigningKeyPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE);
startEncrypt();
return;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
index c89707c34..2a102c6c4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java
@@ -19,6 +19,8 @@ package org.sufficientlysecure.keychain.ui;
import android.net.Uri;
+import org.sufficientlysecure.keychain.util.Passphrase;
+
import java.util.ArrayList;
public interface EncryptActivityInterface {
@@ -39,7 +41,7 @@ public interface EncryptActivityInterface {
public void setEncryptionKeys(long[] encryptionKeys);
public void setEncryptionUsers(String[] encryptionUsers);
- public void setPassphrase(String passphrase);
+ public void setPassphrase(Passphrase passphrase);
// ArrayList on purpose as only those are parcelable
public ArrayList<Uri> getInputUris();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
index f1784fab3..0dd672c90 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
@@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.ShareHelper;
import java.util.ArrayList;
@@ -72,7 +73,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
private long mEncryptionKeyIds[] = null;
private String mEncryptionUserIds[] = null;
private long mSigningKeyId = Constants.key.none;
- private String mPassphrase = "";
+ private Passphrase mPassphrase = new Passphrase();
private ArrayList<Uri> mInputUris;
private ArrayList<Uri> mOutputUris;
@@ -136,7 +137,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
}
@Override
- public void setPassphrase(String passphrase) {
+ public void setPassphrase(Passphrase passphrase) {
mPassphrase = passphrase;
}
@@ -243,8 +244,8 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
if (isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
- String passphrase = mPassphrase;
- if (passphrase.length() == 0) {
+ Passphrase passphrase = mPassphrase;
+ if (passphrase.isEmpty()) {
passphrase = null;
}
data.setSymmetricPassphrase(passphrase);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java
index 86731b162..36b3c08f9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java
@@ -28,6 +28,7 @@ import android.view.ViewGroup;
import android.widget.EditText;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.util.Passphrase;
public class EncryptSymmetricFragment extends Fragment implements EncryptActivityInterface.UpdateListener {
@@ -67,8 +68,13 @@ public class EncryptSymmetricFragment extends Fragment implements EncryptActivit
@Override
public void afterTextChanged(Editable s) {
// update passphrase in EncryptActivity
- if (mPassphrase.getText().toString().equals(mPassphraseAgain.getText().toString())) {
- mEncryptInterface.setPassphrase(s.toString());
+ Passphrase p1 = new Passphrase(mPassphrase.getText());
+ Passphrase p2 = new Passphrase(mPassphraseAgain.getText());
+ boolean passesEquals = (p1.equals(p2));
+ p1.removeFromMemory();
+ p2.removeFromMemory();
+ if (passesEquals) {
+ mEncryptInterface.setPassphrase(new Passphrase(mPassphrase.getText()));
} else {
mEncryptInterface.setPassphrase(null);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
index 14f2c492d..847f745d7 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
@@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.PgpConstants;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.ShareHelper;
import java.util.ArrayList;
@@ -70,7 +71,7 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
private String mEncryptionUserIds[] = null;
// TODO Constants.key.none? What's wrong with a null value?
private long mSigningKeyId = Constants.key.none;
- private String mPassphrase = "";
+ private Passphrase mPassphrase = new Passphrase();
private ArrayList<Uri> mInputUris;
private ArrayList<Uri> mOutputUris;
@@ -134,7 +135,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
}
@Override
- public void setPassphrase(String passphrase) {
+ public void setPassphrase(Passphrase passphrase) {
+ mPassphrase.removeFromMemory();
mPassphrase = passphrase;
}
@@ -223,8 +225,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
if (isModeSymmetric()) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
- String passphrase = mPassphrase;
- if (passphrase.length() == 0) {
+ Passphrase passphrase = mPassphrase;
+ if (passphrase.isEmpty()) {
passphrase = null;
}
data.setSymmetricPassphrase(passphrase);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
index 48509710a..360d30c82 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
@@ -55,6 +55,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
/**
@@ -318,7 +319,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
positive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- final String passphrase = mPassphraseEditText.getText().toString();
+ final Passphrase passphrase = new Passphrase(mPassphraseEditText);
// Early breakout if we are dealing with a symmetric key
if (mSecretRing == null) {
@@ -395,7 +396,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
});
}
- private void finishCaching(String passphrase) {
+ private void finishCaching(Passphrase passphrase) {
// any indication this isn't needed anymore, don't do it.
if (mIsCancelled || getActivity() == null) {
return;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
index b34dc2edc..947c316e0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
@@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.Passphrase;
public class SetPassphraseDialogFragment extends DialogFragment implements OnEditorActionListener {
private static final String ARG_MESSENGER = "messenger";
@@ -67,12 +68,12 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
* @param messenger to communicate back after setting the passphrase
* @return
*/
- public static SetPassphraseDialogFragment newInstance(Messenger messenger, String oldPassphrase, int title) {
+ public static SetPassphraseDialogFragment newInstance(Messenger messenger, Passphrase oldPassphrase, int title) {
SetPassphraseDialogFragment frag = new SetPassphraseDialogFragment();
Bundle args = new Bundle();
args.putInt(ARG_TITLE, title);
args.putParcelable(ARG_MESSENGER, messenger);
- args.putString(ARG_OLD_PASSPHRASE, oldPassphrase);
+ args.putParcelable(ARG_OLD_PASSPHRASE, oldPassphrase);
frag.setArguments(args);
@@ -88,7 +89,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
int title = getArguments().getInt(ARG_TITLE);
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
- String oldPassphrase = getArguments().getString(ARG_OLD_PASSPHRASE);
+ Passphrase oldPassphrase = getArguments().getParcelable(ARG_OLD_PASSPHRASE);
CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity);
@@ -103,7 +104,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
mNoPassphraseCheckBox = (CheckBox) view.findViewById(R.id.passphrase_no_passphrase);
- if (TextUtils.isEmpty(oldPassphrase)) {
+ if (oldPassphrase.isEmpty()) {
mNoPassphraseCheckBox.setChecked(true);
mPassphraseEditText.setEnabled(false);
mPassphraseAgainEditText.setEnabled(false);
@@ -123,12 +124,12 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
public void onClick(DialogInterface dialog, int id) {
dismiss();
- String passphrase1;
+ Passphrase passphrase1 = new Passphrase();
if (mNoPassphraseCheckBox.isChecked()) {
- passphrase1 = "";
+ passphrase1.setEmpty();
} else {
- passphrase1 = mPassphraseEditText.getText().toString();
- String passphrase2 = mPassphraseAgainEditText.getText().toString();
+ passphrase1 = new Passphrase(mPassphraseEditText);
+ Passphrase passphrase2 = new Passphrase(mPassphraseAgainEditText);
if (!passphrase1.equals(passphrase2)) {
Toast.makeText(
activity,
@@ -139,7 +140,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
return;
}
- if (passphrase1.equals("")) {
+ if (passphrase1.isEmpty()) {
Toast.makeText(
activity,
getString(R.string.error_message,
@@ -152,7 +153,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
// return resulting data back to activity
Bundle data = new Bundle();
- data.putString(MESSAGE_NEW_PASSPHRASE, passphrase1);
+ data.putParcelable(MESSAGE_NEW_PASSPHRASE, passphrase1);
sendMessageToHandler(MESSAGE_OKAY, data);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java
new file mode 100644
index 000000000..34cb9af8e
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.util;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.Editable;
+import android.widget.EditText;
+
+import org.sufficientlysecure.keychain.Constants;
+
+import java.util.Arrays;
+
+public class Passphrase implements Parcelable {
+ private char[] mPassphrase;
+
+ /**
+ * According to http://stackoverflow.com/a/15844273 EditText is not using String internally
+ * but char[]. Thus, we can get the char[] directly from it.
+ */
+ public Passphrase(Editable editable) {
+ int pl = editable.length();
+ mPassphrase = new char[pl];
+ editable.getChars(0, pl, mPassphrase, 0);
+ // TODO: clean up internal char[] of EditText after getting the passphrase?
+// editText.getText().replace()
+ System.gc();
+ }
+
+ public Passphrase(EditText editText) {
+ this(editText.getText());
+ }
+
+ public Passphrase(String passphrase) {
+ mPassphrase = passphrase.toCharArray();
+ }
+
+ public Passphrase() {
+ setEmpty();
+ }
+
+ public char[] getCharArray() {
+ return mPassphrase;
+ }
+
+ public boolean isEmpty() {
+ return (mPassphrase.length == 0);
+ }
+
+ public void setEmpty() {
+ removeFromMemory();
+ mPassphrase = new char[0];
+ }
+
+ public void removeFromMemory() {
+ if (mPassphrase != null) {
+ Arrays.fill(mPassphrase, ' ');
+ System.gc();
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (Constants.DEBUG) {
+ return "Passphrase{" +
+ "mPassphrase=" + Arrays.toString(mPassphrase) +
+ '}';
+ } else {
+ return "Passphrase: hidden";
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Passphrase that = (Passphrase) o;
+ if (!Arrays.equals(mPassphrase, that.mPassphrase)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return mPassphrase != null ? Arrays.hashCode(mPassphrase) : 0;
+ }
+
+ private Passphrase(Parcel source) {
+ mPassphrase = source.createCharArray();
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeCharArray(mPassphrase);
+ }
+
+ public static final Creator<Passphrase> CREATOR = new Creator<Passphrase>() {
+ public Passphrase createFromParcel(final Parcel source) {
+ return new Passphrase(source);
+ }
+
+ public Passphrase[] newArray(final int size) {
+ return new Passphrase[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+}