modify*Key: improve handling of passphrase modification (add tests, too)
This commit is contained in:
@@ -698,7 +698,7 @@ public class PgpKeyOperation {
|
||||
// Build key encrypter and decrypter based on passphrase
|
||||
PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
|
||||
PGPEncryptedData.CAST5, sha1Calc)
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray());
|
||||
|
||||
sKey = new PGPSecretKey(keyPair.getPrivateKey(), pKey,
|
||||
sha1Calc, false, keyEncryptor);
|
||||
@@ -716,6 +716,8 @@ public class PgpKeyOperation {
|
||||
if (saveParcel.mNewPassphrase != null) {
|
||||
progress(R.string.progress_modify_passphrase, 90);
|
||||
log.add(LogLevel.INFO, LogType.MSG_MF_PASSPHRASE, indent);
|
||||
indent += 1;
|
||||
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build()
|
||||
.get(HashAlgorithmTags.SHA1);
|
||||
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||
@@ -726,7 +728,51 @@ public class PgpKeyOperation {
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
|
||||
saveParcel.mNewPassphrase.toCharArray());
|
||||
|
||||
sKR = PGPSecretKeyRing.copyWithNewPassword(sKR, keyDecryptor, keyEncryptorNew);
|
||||
// noinspection unchecked
|
||||
for (PGPSecretKey sKey : new IterableIterator<PGPSecretKey>(sKR.getSecretKeys())) {
|
||||
log.add(LogLevel.DEBUG, LogType.MSG_MF_PASSPHRASE_KEY, indent,
|
||||
PgpKeyHelper.convertKeyIdToHex(sKey.getKeyID()));
|
||||
|
||||
boolean ok = false;
|
||||
|
||||
try {
|
||||
// try to set new passphrase
|
||||
sKey = PGPSecretKey.copyWithNewPassword(sKey, keyDecryptor, keyEncryptorNew);
|
||||
ok = true;
|
||||
} catch (PGPException e) {
|
||||
|
||||
// if this is the master key, error!
|
||||
if (sKey.getKeyID() == masterPublicKey.getKeyID()) {
|
||||
log.add(LogLevel.ERROR, LogType.MSG_MF_ERROR_PASSPHRASE_MASTER, indent+1);
|
||||
return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null);
|
||||
}
|
||||
|
||||
// being in here means decrypt failed, likely due to a bad passphrase try
|
||||
// again with an empty passphrase, maybe we can salvage this
|
||||
try {
|
||||
log.add(LogLevel.DEBUG, LogType.MSG_MF_PASSPHRASE_EMPTY_RETRY, indent+1);
|
||||
PBESecretKeyDecryptor emptyDecryptor =
|
||||
new JcePBESecretKeyDecryptorBuilder().setProvider(
|
||||
Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());
|
||||
sKey = PGPSecretKey.copyWithNewPassword(sKey, emptyDecryptor, keyEncryptorNew);
|
||||
ok = true;
|
||||
} catch (PGPException e2) {
|
||||
// non-fatal but not ok, handled below
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
// for a subkey, it's merely a warning
|
||||
log.add(LogLevel.WARN, LogType.MSG_MF_PASSPHRASE_FAIL, indent+1,
|
||||
PgpKeyHelper.convertKeyIdToHex(sKey.getKeyID()));
|
||||
continue;
|
||||
}
|
||||
|
||||
sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
|
||||
|
||||
}
|
||||
|
||||
indent -= 1;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -364,6 +364,7 @@ public class OperationResultParcel implements Parcelable {
|
||||
MSG_MF_ERROR_NOEXIST_PRIMARY (R.string.msg_mf_error_noexist_primary),
|
||||
MSG_MF_ERROR_NOEXIST_REVOKE (R.string.msg_mf_error_noexist_revoke),
|
||||
MSG_MF_ERROR_NULL_EXPIRY (R.string.msg_mf_error_null_expiry),
|
||||
MSG_MF_ERROR_PASSPHRASE_MASTER(R.string.msg_mf_error_passphrase_master),
|
||||
MSG_MF_ERROR_PAST_EXPIRY(R.string.msg_mf_error_past_expiry),
|
||||
MSG_MF_ERROR_PGP (R.string.msg_mf_error_pgp),
|
||||
MSG_MF_ERROR_REVOKED_PRIMARY (R.string.msg_mf_error_revoked_primary),
|
||||
@@ -371,6 +372,9 @@ public class OperationResultParcel implements Parcelable {
|
||||
MSG_MF_ERROR_SUBKEY_MISSING(R.string.msg_mf_error_subkey_missing),
|
||||
MSG_MF_MASTER (R.string.msg_mf_master),
|
||||
MSG_MF_PASSPHRASE (R.string.msg_mf_passphrase),
|
||||
MSG_MF_PASSPHRASE_KEY (R.string.msg_mf_passphrase_key),
|
||||
MSG_MF_PASSPHRASE_EMPTY_RETRY (R.string.msg_mf_passphrase_empty_retry),
|
||||
MSG_MF_PASSPHRASE_FAIL (R.string.msg_mf_passphrase_fail),
|
||||
MSG_MF_PRIMARY_REPLACE_OLD (R.string.msg_mf_primary_replace_old),
|
||||
MSG_MF_PRIMARY_NEW (R.string.msg_mf_primary_new),
|
||||
MSG_MF_SUBKEY_CHANGE (R.string.msg_mf_subkey_change),
|
||||
|
||||
@@ -644,10 +644,14 @@
|
||||
<string name="msg_mf_error_noexist_revoke">Bad user id for revocation specified!</string>
|
||||
<string name="msg_mf_error_revoked_primary">Revoked user ids cannot be primary!</string>
|
||||
<string name="msg_mf_error_null_expiry">Expiry time cannot be "same as before" on subkey creation. This is a programming error, please file a bug report!</string>
|
||||
<string name="msg_mf_error_passphrase_master">Fatal error decrypting master key! This is likely a programming error, please file a bug report!</string>
|
||||
<string name="msg_mf_error_pgp">PGP internal exception!</string>
|
||||
<string name="msg_mf_error_sig">Signature exception!</string>
|
||||
<string name="msg_mf_master">Modifying master certifications</string>
|
||||
<string name="msg_mf_passphrase">Changing passphrase</string>
|
||||
<string name="msg_mf_passphrase">Changing passphrase for keyring…</string>
|
||||
<string name="msg_mf_passphrase_key">Changing passphrase for subkey %s</string>
|
||||
<string name="msg_mf_passphrase_empty_retry">Setting new passphrase failed, trying again with empty old passphrase</string>
|
||||
<string name="msg_mf_passphrase_fail">Passphrase for subkey could not be changed! (Does it have a different one from the other keys?)</string>
|
||||
<string name="msg_mf_primary_replace_old">Replacing certificate of previous primary user id</string>
|
||||
<string name="msg_mf_primary_new">Generating new certificate for new primary user id</string>
|
||||
<string name="msg_mf_subkey_change">Modifying subkey %s</string>
|
||||
|
||||
Reference in New Issue
Block a user