move key stripping into ChangeSubkey, support divert-to-card

This commit is contained in:
Vincent Breitmoser
2015-01-24 23:05:50 +01:00
parent 53955a8014
commit 0e0970c347
7 changed files with 59 additions and 42 deletions

View File

@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.bcpg.S2K;
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.spongycastle.bcpg.sig.Features;
import org.spongycastle.bcpg.sig.KeyFlags;
@@ -715,6 +716,24 @@ public class PgpKeyOperation {
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (change.mDummyStrip || change.mDummyDivert) {
// IT'S DANGEROUS~
// no really, it is. this operation irrevocably removes the private key data from the key
if (change.mDummyStrip) {
sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey(),
S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY);
} else {
sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey(),
S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD);
}
sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
}
// This doesn't concern us any further
if (change.mExpiry == null && change.mFlags == null) {
continue;
}
// expiry must not be in the past
if (change.mExpiry != null && change.mExpiry != 0 &&
new Date(change.mExpiry*1000).before(new Date())) {
@@ -805,30 +824,6 @@ public class PgpKeyOperation {
}
subProgressPop();
// 4c. For each subkey to be stripped... do so
subProgressPush(65, 70);
for (int i = 0; i < saveParcel.mStripSubKeys.size(); i++) {
progress(R.string.progress_modify_subkeystrip, (i-1) * (100 / saveParcel.mStripSubKeys.size()));
long strip = saveParcel.mStripSubKeys.get(i);
log.add(LogType.MSG_MF_SUBKEY_STRIP,
indent, KeyFormattingUtils.convertKeyIdToHex(strip));
PGPSecretKey sKey = sKR.getSecretKey(strip);
if (sKey == null) {
log.add(LogType.MSG_MF_ERROR_SUBKEY_MISSING,
indent+1, KeyFormattingUtils.convertKeyIdToHex(strip));
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// IT'S DANGEROUS~
// no really, it is. this operation irrevocably removes the private key data from the key
sKey = PGPSecretKey.constructGnuDummyKey(sKey.getPublicKey());
sKR = PGPSecretKeyRing.insertSecretKey(sKR, sKey);
}
subProgressPop();
// 5. Generate and add new subkeys
subProgressPush(70, 90);
for (int i = 0; i < saveParcel.mAddSubKeys.size(); i++) {

View File

@@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp;
import org.spongycastle.bcpg.ArmoredOutputStream;
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
import org.spongycastle.bcpg.S2K;
import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.bcpg.UserAttributeSubpacketTags;
import org.spongycastle.bcpg.sig.KeyFlags;
@@ -1221,7 +1222,8 @@ public class UncachedKeyRing {
// if this is a secret key which does not yet occur in the secret ring
if (sKey == null) {
// generate a stripped secret (sub)key
sKey = PGPSecretKey.constructGnuDummyKey(key);
sKey = PGPSecretKey.constructGnuDummyKey(key,
S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY);
}
sKey = PGPSecretKey.replacePublicKey(sKey, key);
return PGPSecretKeyRing.insertSecretKey(secRing, sKey);