apply promote operation to specific subkeys present on yubikey only

This commit is contained in:
Vincent Breitmoser
2015-05-17 00:35:10 +02:00
parent f554cc9c93
commit c1e7fcf024
8 changed files with 108 additions and 11 deletions

View File

@@ -25,6 +25,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
@@ -34,6 +35,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.ProgressScaler;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
/** An operation which promotes a public key ring to a secret one.
@@ -50,7 +52,7 @@ public class PromoteKeyOperation extends BaseOperation {
super(context, providerHelper, progressable, cancelled);
}
public PromoteKeyResult execute(long masterKeyId, byte[] cardAid) {
public PromoteKeyResult execute(long masterKeyId, byte[] cardAid, long[] subKeyIds) {
OperationLog log = new OperationLog();
log.add(LogType.MSG_PR, 0);
@@ -65,8 +67,24 @@ public class PromoteKeyOperation extends BaseOperation {
CanonicalizedPublicKeyRing pubRing =
mProviderHelper.getCanonicalizedPublicKeyRing(masterKeyId);
if (subKeyIds == null) {
log.add(LogType.MSG_PR_ALL, 1);
} else {
// sort for binary search
for (CanonicalizedPublicKey key : pubRing.publicKeyIterator()) {
long subKeyId = key.getKeyId();
if (naiveIndexOf(subKeyIds, subKeyId) != null) {
log.add(LogType.MSG_PR_SUBKEY_MATCH, 1,
KeyFormattingUtils.convertKeyIdToHex(subKeyId));
} else {
log.add(LogType.MSG_PR_SUBKEY_NOMATCH, 1,
KeyFormattingUtils.convertKeyIdToHex(subKeyId));
}
}
}
// create divert-to-card secret key from public key
promotedRing = pubRing.createDivertSecretRing(cardAid);
promotedRing = pubRing.createDivertSecretRing(cardAid, subKeyIds);
} catch (NotFoundException e) {
log.add(LogType.MSG_PR_ERROR_KEY_NOT_FOUND, 2);
@@ -106,4 +124,13 @@ public class PromoteKeyOperation extends BaseOperation {
}
static private Integer naiveIndexOf(long[] haystack, long needle) {
for (int i = 0; i < haystack.length; i++) {
if (needle == haystack[i]) {
return i;
}
}
return null;
}
}

View File

@@ -566,8 +566,11 @@ public abstract class OperationResult implements Parcelable {
// promote key
MSG_PR (LogLevel.START, R.string.msg_pr),
MSG_PR_ALL (LogLevel.DEBUG, R.string.msg_pr_all),
MSG_PR_ERROR_KEY_NOT_FOUND (LogLevel.ERROR, R.string.msg_pr_error_key_not_found),
MSG_PR_FETCHING (LogLevel.DEBUG, R.string.msg_pr_fetching),
MSG_PR_SUBKEY_MATCH (LogLevel.DEBUG, R.string.msg_pr_subkey_match),
MSG_PR_SUBKEY_NOMATCH (LogLevel.WARN, R.string.msg_pr_subkey_nomatch),
MSG_PR_SUCCESS (LogLevel.OK, R.string.msg_pr_success),
// messages used in UI code