diff options
| author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-05-17 00:35:10 +0200 | 
|---|---|---|
| committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-05-17 00:35:10 +0200 | 
| commit | c1e7fcf02455b7a03c86bb78efe39684396c15f8 (patch) | |
| tree | 40e89ce3bccf981f698862beccb7685a6b55cbdd /OpenKeychain/src/main/java | |
| parent | f554cc9c931f46f1017c2a34fbb776c456e9e344 (diff) | |
| download | open-keychain-c1e7fcf02455b7a03c86bb78efe39684396c15f8.tar.gz open-keychain-c1e7fcf02455b7a03c86bb78efe39684396c15f8.tar.bz2 open-keychain-c1e7fcf02455b7a03c86bb78efe39684396c15f8.zip | |
apply promote operation to specific subkeys present on yubikey only
Diffstat (limited to 'OpenKeychain/src/main/java')
6 files changed, 66 insertions, 9 deletions
| diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java index ef08b0b77..558756378 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/PromoteKeyOperation.java @@ -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; +    } +  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index 7f36aeb08..f7b1ca0b4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java index 4adacaf23..432ba23e9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedKeyRing.java @@ -19,6 +19,7 @@  package org.sufficientlysecure.keychain.pgp;  import org.spongycastle.openpgp.PGPKeyRing; +import org.spongycastle.openpgp.PGPPublicKey;  import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;  import org.sufficientlysecure.keychain.util.IterableIterator; @@ -127,7 +128,11 @@ public abstract class CanonicalizedKeyRing extends KeyRing {      }      public CanonicalizedPublicKey getPublicKey(long id) { -        return new CanonicalizedPublicKey(this, getRing().getPublicKey(id)); +        PGPPublicKey pubKey = getRing().getPublicKey(id); +        if (pubKey == null) { +            return null; +        } +        return new CanonicalizedPublicKey(this, pubKey);      }      public byte[] getEncoded() throws IOException { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java index 8432b8f9f..68fd4a428 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/CanonicalizedPublicKeyRing.java @@ -103,9 +103,22 @@ public class CanonicalizedPublicKeyRing extends CanonicalizedKeyRing {      }      /** Create a dummy secret ring from this key */ -    public UncachedKeyRing createDivertSecretRing (byte[] cardAid) { +    public UncachedKeyRing createDivertSecretRing (byte[] cardAid, long[] subKeyIds) {          PGPSecretKeyRing secRing = PGPSecretKeyRing.constructDummyFromPublic(getRing(), cardAid); -        return new UncachedKeyRing(secRing); + +        if (subKeyIds == null) { +            return new UncachedKeyRing(secRing); +        } + +        // if only specific subkeys should be promoted, construct a +        // stripped dummy, then move divert-to-card keys over +        PGPSecretKeyRing newRing = PGPSecretKeyRing.constructDummyFromPublic(getRing()); +        for (long subKeyId : subKeyIds) { +            newRing = PGPSecretKeyRing.insertSecretKey(newRing, secRing.getSecretKey(subKeyId)); +        } + +        return new UncachedKeyRing(newRing); +      }  }
\ No newline at end of file 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 e0509ac9b..71e149672 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -65,7 +65,6 @@ 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; @@ -185,6 +184,7 @@ public class KeychainIntentService extends IntentService implements Progressable      // promote key      public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id";      public static final String PROMOTE_CARD_AID = "promote_card_aid"; +    public static final String PROMOTE_SUBKEY_IDS = "promote_fingerprints";      // consolidate      public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery"; @@ -476,10 +476,12 @@ public class KeychainIntentService extends IntentService implements Progressable                  // Input                  long keyRingId = data.getLong(PROMOTE_MASTER_KEY_ID);                  byte[] cardAid = data.getByteArray(PROMOTE_CARD_AID); +                long[] subKeyIds = data.getLongArray(PROMOTE_SUBKEY_IDS);                  // Operation -                PromoteKeyOperation op = new PromoteKeyOperation(this, providerHelper, this, mActionCanceled); -                PromoteKeyResult result = op.execute(keyRingId, cardAid); +                PromoteKeyOperation op = new PromoteKeyOperation( +                        this, providerHelper, this, mActionCanceled); +                PromoteKeyResult result = op.execute(keyRingId, cardAid, subKeyIds);                  // Result                  sendMessageToHandler(MessageStatus.OKAY, result); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java index 99ac73800..ecd351965 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubiKeyFragment.java @@ -45,6 +45,8 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;  import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;  import org.sufficientlysecure.keychain.service.KeychainIntentService;  import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +  public class ViewKeyYubiKeyFragment extends Fragment          implements LoaderCallbacks<Cursor> { @@ -154,6 +156,11 @@ public class ViewKeyYubiKeyFragment extends Fragment          Bundle data = new Bundle();          data.putLong(KeychainIntentService.PROMOTE_MASTER_KEY_ID, mMasterKeyId);          data.putByteArray(KeychainIntentService.PROMOTE_CARD_AID, mCardAid); +        long[] subKeyIds = new long[mFingerprints.length]; +        for (int i = 0; i < subKeyIds.length; i++) { +            subKeyIds[i] = KeyFormattingUtils.getKeyIdFromFingerprint(mFingerprints[i]); +        } +        data.putLongArray(KeychainIntentService.PROMOTE_SUBKEY_IDS, subKeyIds);          intent.putExtra(KeychainIntentService.EXTRA_DATA, data);          // Create a new Messenger for the communication back @@ -219,7 +226,7 @@ public class ViewKeyYubiKeyFragment extends Fragment      } -    public Integer naiveIndexOf(byte[][] haystack, byte[] needle) { +    static private Integer naiveIndexOf(byte[][] haystack, byte[] needle) {          for (int i = 0; i < haystack.length; i++) {              if (Arrays.equals(needle, haystack[i])) {                  return i; | 
