mirror of
https://github.com/moparisthebest/open-keychain
synced 2025-02-15 22:50:11 -05:00
wrapped-key-ring: more work on passphrase caching and certification
This commit is contained in:
parent
8cf0638f54
commit
cd8af25ba7
@ -81,23 +81,6 @@ public class PgpKeyHelper {
|
||||
return getExpiryDate(key.getPublicKey());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Deprecated
|
||||
public static PGPSecretKey getKeyNum(PGPSecretKeyRing keyRing, long num) {
|
||||
long cnt = 0;
|
||||
if (keyRing == null) {
|
||||
return null;
|
||||
}
|
||||
for (PGPSecretKey key : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
|
||||
if (cnt == num) {
|
||||
return key;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getKeyUsage(PGPSecretKey key) {
|
||||
return getKeyUsage(key.getPublicKey());
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||
import org.sufficientlysecure.keychain.pgp.CachedSecretKeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
@ -163,38 +164,46 @@ public class PassphraseCacheService extends Service {
|
||||
* @return
|
||||
*/
|
||||
private String getCachedPassphraseImpl(long keyId) {
|
||||
Log.d(TAG, "getCachedPassphraseImpl() get masterKeyId for " + keyId);
|
||||
// passphrase for symmetric encryption?
|
||||
if (keyId == Constants.key.symmetric) {
|
||||
Log.d(TAG, "getCachedPassphraseImpl() for symmetric encryption");
|
||||
String cachedPassphrase = mPassphraseCache.get(Constants.key.symmetric);
|
||||
if (cachedPassphrase == null) {
|
||||
return null;
|
||||
}
|
||||
addCachedPassphrase(this, Constants.key.symmetric, cachedPassphrase);
|
||||
return cachedPassphrase;
|
||||
}
|
||||
|
||||
// try to get master key id which is used as an identifier for cached passphrases
|
||||
long masterKeyId = keyId;
|
||||
if (masterKeyId != Constants.key.symmetric) {
|
||||
try {
|
||||
masterKeyId = new ProviderHelper(this).getMasterKeyId(
|
||||
KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId)));
|
||||
} catch (ProviderHelper.NotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + masterKeyId);
|
||||
|
||||
// get cached passphrase
|
||||
String cachedPassphrase = mPassphraseCache.get(masterKeyId);
|
||||
if (cachedPassphrase == null) {
|
||||
// if key has no passphrase -> cache and return empty passphrase
|
||||
if (!hasPassphrase(this, masterKeyId)) {
|
||||
try {
|
||||
Log.d(TAG, "getCachedPassphraseImpl() for masterKeyId " + keyId);
|
||||
CachedSecretKeyRing key = new ProviderHelper(this).getCachedSecretKeyRing(
|
||||
KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(keyId)));
|
||||
// no passphrase needed? just add empty string and return it, then
|
||||
if (!key.hasPassphrase()) {
|
||||
Log.d(Constants.TAG, "Key has no passphrase! Caches and returns empty passphrase!");
|
||||
|
||||
addCachedPassphrase(this, masterKeyId, "");
|
||||
addCachedPassphrase(this, keyId, "");
|
||||
return "";
|
||||
} else {
|
||||
}
|
||||
|
||||
// get cached passphrase
|
||||
String cachedPassphrase = mPassphraseCache.get(keyId);
|
||||
if (cachedPassphrase == null) {
|
||||
// this is an error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// set it again to reset the cache life cycle
|
||||
Log.d(TAG, "Cache passphrase again when getting it!");
|
||||
addCachedPassphrase(this, masterKeyId, cachedPassphrase);
|
||||
|
||||
return cachedPassphrase;
|
||||
// set it again to reset the cache life cycle
|
||||
Log.d(TAG, "Cache passphrase again when getting it!");
|
||||
addCachedPassphrase(this, keyId, cachedPassphrase);
|
||||
return cachedPassphrase;
|
||||
|
||||
} catch (ProviderHelper.NotFoundException e) {
|
||||
Log.e(TAG, "Passphrase for unknown key was requested!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ -230,16 +239,9 @@ public class PassphraseCacheService extends Service {
|
||||
* @return true if it has a passphrase
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasPassphrase(Context context, long secretKeyId) {
|
||||
// check if the key has no passphrase
|
||||
try {
|
||||
PGPSecretKeyRing secRing = new ProviderHelper(context).getPGPSecretKeyRing(secretKeyId);
|
||||
return hasPassphrase(secRing);
|
||||
} catch (ProviderHelper.NotFoundException e) {
|
||||
Log.e(Constants.TAG, "key not found!", e);
|
||||
}
|
||||
|
||||
return true;
|
||||
public static boolean hasPassphrase(Context context, long secretKeyId)
|
||||
throws ProviderHelper.NotFoundException {
|
||||
return new ProviderHelper(context).getCachedSecretKeyRing(secretKeyId).hasPassphrase();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,53 +226,22 @@ public class CertifyKeyActivity extends ActionBarActivity implements
|
||||
* handles the UI bits of the signing process on the UI thread
|
||||
*/
|
||||
private void initiateSigning() {
|
||||
try {
|
||||
PGPPublicKeyRing pubring = new ProviderHelper(this).getPGPPublicKeyRing(mPubKeyId);
|
||||
|
||||
// if we have already signed this key, dont bother doing it again
|
||||
boolean alreadySigned = false;
|
||||
|
||||
/* todo: reconsider this at a later point when certs are in the db
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<PGPSignature> itr = pubring.getPublicKey(mPubKeyId).getSignatures();
|
||||
while (itr.hasNext()) {
|
||||
PGPSignature sig = itr.next();
|
||||
if (sig.getKeyID() == mMasterKeyId) {
|
||||
alreadySigned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (!alreadySigned) {
|
||||
/*
|
||||
* get the user's passphrase for this key (if required)
|
||||
*/
|
||||
String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId);
|
||||
if (passphrase == null) {
|
||||
PassphraseDialogFragment.show(this, mMasterKeyId,
|
||||
new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||
startSigning();
|
||||
}
|
||||
}
|
||||
});
|
||||
// bail out; need to wait until the user has entered the passphrase before trying again
|
||||
return;
|
||||
} else {
|
||||
startSigning();
|
||||
}
|
||||
} else {
|
||||
AppMsg.makeText(this, R.string.key_has_already_been_certified, AppMsg.STYLE_ALERT)
|
||||
.show();
|
||||
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
} catch (ProviderHelper.NotFoundException e) {
|
||||
Log.e(Constants.TAG, "key not found!", e);
|
||||
// get the user's passphrase for this key (if required)
|
||||
String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId);
|
||||
if (passphrase == null) {
|
||||
PassphraseDialogFragment.show(this, mMasterKeyId,
|
||||
new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||
startSigning();
|
||||
}
|
||||
}
|
||||
});
|
||||
// bail out; need to wait until the user has entered the passphrase before trying again
|
||||
return;
|
||||
} else {
|
||||
startSigning();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,8 +101,12 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
|
||||
long secretKeyId) throws PgpGeneralException {
|
||||
// check if secret key has a passphrase
|
||||
if (!(secretKeyId == Constants.key.symmetric || secretKeyId == Constants.key.none)) {
|
||||
if (!PassphraseCacheService.hasPassphrase(context, secretKeyId)) {
|
||||
throw new PgpGeneralException("No passphrase! No passphrase dialog needed!");
|
||||
try {
|
||||
if (new ProviderHelper(context).getCachedSecretKeyRing(secretKeyId).hasPassphrase()) {
|
||||
throw new PgpGeneralException("No passphrase! No passphrase dialog needed!");
|
||||
}
|
||||
} catch(ProviderHelper.NotFoundException e) {
|
||||
throw new PgpGeneralException("Error: Key not found!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user