From f8a222983efe5741a0d79147c6724a49ad7e5b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 5 Aug 2014 20:52:29 +0200 Subject: [PATCH] Use PublicKeyAlgorithmTags instead of homebrew choices constants, fix expiry selection for adding new subkeys --- .../keychain/Constants.java | 7 --- .../keychain/pgp/PgpKeyHelper.java | 22 +++---- .../keychain/pgp/PgpKeyOperation.java | 9 +-- .../keychain/ui/CreateKeyFinalFragment.java | 8 ++- .../keychain/ui/EditKeyFragment.java | 9 +-- .../keychain/ui/adapter/SubkeysAdapter.java | 13 ++-- .../ui/adapter/SubkeysAddedAdapter.java | 36 +++++------ .../ui/dialog/AddSubkeyDialogFragment.java | 61 +++++++++++++++---- .../EditSubkeyExpiryDialogFragment.java | 13 ++-- OpenKeychain/src/main/res/values/strings.xml | 2 +- 10 files changed, 102 insertions(+), 78 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 6423697cf..df39efeb0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -92,13 +92,6 @@ public final class Constants { } public static final class choice { - public static final class algorithm { - // TODO: legacy reasons :/ better: PublicKeyAlgorithmTags - public static final int dsa = 0x21070001; - public static final int elgamal = 0x21070002; - public static final int rsa = 0x21070003; - } - public static final class compression { // TODO: legacy reasons :/ better: CompressionAlgorithmTags.UNCOMPRESSED public static final int none = 0x21070001; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 7e18aa906..0c640538f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -24,7 +24,7 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; -import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -37,9 +37,6 @@ import java.util.Locale; public class PgpKeyHelper { - /** - * TODO: Only used in HkpKeyServer. Get rid of this one! - */ public static String getAlgorithmInfo(int algorithm) { return getAlgorithmInfo(null, algorithm, 0); } @@ -55,25 +52,25 @@ public class PgpKeyHelper { String algorithmStr; switch (algorithm) { - case PGPPublicKey.RSA_ENCRYPT: - case PGPPublicKey.RSA_GENERAL: - case PGPPublicKey.RSA_SIGN: { + case PublicKeyAlgorithmTags.RSA_ENCRYPT: + case PublicKeyAlgorithmTags.RSA_GENERAL: + case PublicKeyAlgorithmTags.RSA_SIGN: { algorithmStr = "RSA"; break; } - case PGPPublicKey.DSA: { + case PublicKeyAlgorithmTags.DSA: { algorithmStr = "DSA"; break; } - case PGPPublicKey.ELGAMAL_ENCRYPT: - case PGPPublicKey.ELGAMAL_GENERAL: { + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: + case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: { algorithmStr = "ElGamal"; break; } - case PGPPublicKey.ECDSA: - case PGPPublicKey.ECDH: { + case PublicKeyAlgorithmTags.ECDSA: + case PublicKeyAlgorithmTags.ECDH: { algorithmStr = "ECC"; break; } @@ -82,7 +79,6 @@ public class PgpKeyHelper { if (context != null) { algorithmStr = context.getResources().getString(R.string.unknown_algorithm); } else { - // TODO algorithmStr = "unknown"; } break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 3f058d888..6cd020684 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.pgp; import org.spongycastle.bcpg.CompressionAlgorithmTags; import org.spongycastle.bcpg.HashAlgorithmTags; +import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.jce.spec.ElGamalParameterSpec; @@ -138,7 +139,7 @@ public class PgpKeyOperation { KeyPairGenerator keyGen; switch (algorithmChoice) { - case Constants.choice.algorithm.dsa: { + case PublicKeyAlgorithmTags.DSA: { progress(R.string.progress_generating_dsa, 30); keyGen = KeyPairGenerator.getInstance("DSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); keyGen.initialize(keySize, new SecureRandom()); @@ -146,7 +147,7 @@ public class PgpKeyOperation { break; } - case Constants.choice.algorithm.elgamal: { + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: { progress(R.string.progress_generating_elgamal, 30); keyGen = KeyPairGenerator.getInstance("ElGamal", Constants.BOUNCY_CASTLE_PROVIDER_NAME); BigInteger p = Primes.getBestPrime(keySize); @@ -159,7 +160,7 @@ public class PgpKeyOperation { break; } - case Constants.choice.algorithm.rsa: { + case PublicKeyAlgorithmTags.RSA_GENERAL: { progress(R.string.progress_generating_rsa, 30); keyGen = KeyPairGenerator.getInstance("RSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME); keyGen.initialize(keySize, new SecureRandom()); @@ -217,7 +218,7 @@ public class PgpKeyOperation { return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } - if (add.mAlgorithm == Constants.choice.algorithm.elgamal) { + if (add.mAlgorithm == PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT) { log.add(LogLevel.ERROR, LogType.MSG_CR_ERROR_MASTER_ELGAMAL, indent); return new EditKeyResult(EditKeyResult.RESULT_ERROR, log, null); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index abbc3f199..de9c7f77d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -31,7 +31,9 @@ import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.TextView; +import org.spongycastle.bcpg.PublicKeyAlgorithmTags; import org.spongycastle.bcpg.sig.KeyFlags; +import org.spongycastle.openpgp.PGPPublicKey; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.Preferences; @@ -169,9 +171,9 @@ public class CreateKeyFinalFragment extends Fragment { Bundle data = new Bundle(); SaveKeyringParcel parcel = new SaveKeyringParcel(); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.CERTIFY_OTHER, null)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.SIGN_DATA, null)); - parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, null)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.CERTIFY_OTHER, null)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.SIGN_DATA, null)); + parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(PublicKeyAlgorithmTags.RSA_GENERAL, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, null)); String userId = KeyRing.createUserId(mName, mEmail, null); parcel.mAddUserIds.add(userId); parcel.mChangePrimaryUserId = userId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 7697f736c..1a37567eb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -397,15 +397,16 @@ public class EditKeyFragment extends LoaderFragment implements private void editSubkeyExpiry(final int position) { final long keyId = mSubkeysAdapter.getKeyId(position); - final long creationDate = mSubkeysAdapter.getCreationDate(position); - final long expiryDate = mSubkeysAdapter.getExpiryDate(position); + final Long creationDate = mSubkeysAdapter.getCreationDate(position); + final Long expiryDate = mSubkeysAdapter.getExpiryDate(position); Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { switch (message.what) { case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY_DATE: - long expiry = message.getData().getLong(EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY_DATE); + Long expiry = (Long) message.getData(). + getSerializable(EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY_DATE); Log.d(Constants.TAG, "new expiry: " + expiry); mSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry = expiry; break; @@ -464,7 +465,7 @@ public class EditKeyFragment extends LoaderFragment implements new AddSubkeyDialogFragment.OnAlgorithmSelectedListener() { @Override public void onAlgorithmSelected(SaveKeyringParcel.SubkeyAdd newSubkey) { - mSubkeysAddedAdapter.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.SIGN_DATA, null)); + mSubkeysAddedAdapter.add(newSubkey); } } ); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java index dd972866c..e845c7e42 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java @@ -95,9 +95,13 @@ public class SubkeysAdapter extends CursorAdapter { return mCursor.getLong(INDEX_CREATION); } - public long getExpiryDate(int position) { + public Long getExpiryDate(int position) { mCursor.moveToPosition(position); - return mCursor.getLong(INDEX_EXPIRY); + if (mCursor.isNull(INDEX_EXPIRY)) { + return null; + } else { + return mCursor.getLong(INDEX_EXPIRY); + } } @Override @@ -178,8 +182,9 @@ public class SubkeysAdapter extends CursorAdapter { SaveKeyringParcel.SubkeyChange subkeyChange = mSaveKeyringParcel.getSubkeyChange(keyId); if (subkeyChange != null) { - // 0 is "no expiry" - if (subkeyChange.mExpiry != null && subkeyChange.mExpiry != 0) { + if (subkeyChange.mExpiry == null) { + expiryDate = null; + } else { expiryDate = new Date(subkeyChange.mExpiry * 1000); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java index 1ec9add68..b3f87a4c4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java @@ -102,35 +102,27 @@ public class SubkeysAddedAdapter extends ArrayAdapter= android.os.Build.VERSION_CODES.HONEYCOMB) { + mExpiryDatePicker.setMinDate(new Date().getTime() + DateUtils.DAY_IN_MILLIS); + } + ArrayList choices = new ArrayList(); - choices.add(new Choice(Constants.choice.algorithm.dsa, getResources().getString( + choices.add(new Choice(PublicKeyAlgorithmTags.DSA, getResources().getString( R.string.dsa))); if (!willBeMasterKey) { - choices.add(new Choice(Constants.choice.algorithm.elgamal, getResources().getString( + choices.add(new Choice(PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, getResources().getString( R.string.elgamal))); } - choices.add(new Choice(Constants.choice.algorithm.rsa, getResources().getString( + choices.add(new Choice(PublicKeyAlgorithmTags.RSA_GENERAL, getResources().getString( R.string.rsa))); ArrayAdapter adapter = new ArrayAdapter(context, android.R.layout.simple_spinner_item, choices); @@ -140,13 +150,12 @@ public class AddSubkeyDialogFragment extends DialogFragment { mAlgorithmSpinner.setAdapter(adapter); // make RSA the default for (int i = 0; i < choices.size(); ++i) { - if (choices.get(i).getId() == Constants.choice.algorithm.rsa) { + if (choices.get(i).getId() == PublicKeyAlgorithmTags.RSA_GENERAL) { mAlgorithmSpinner.setSelection(i); break; } } - // dynamic ArrayAdapter must be created (instead of ArrayAdapter.getFromResource), because it's content may change ArrayAdapter keySizeAdapter = new ArrayAdapter(context, android.R.layout.simple_spinner_item, new ArrayList(Arrays.asList(getResources().getStringArray(R.array.rsa_key_size_spinner_values)))); @@ -161,11 +170,37 @@ public class AddSubkeyDialogFragment extends DialogFragment { di.dismiss(); Choice newKeyAlgorithmChoice = (Choice) mAlgorithmSpinner.getSelectedItem(); int newKeySize = getProperKeyLength(newKeyAlgorithmChoice.getId(), getSelectedKeyLength()); + + int flags = 0; + if (mFlagCertify.isChecked()) { + flags += KeyFlags.CERTIFY_OTHER; + } + if (mFlagSign.isChecked()) { + flags += KeyFlags.SIGN_DATA; + } + if (mFlagEncrypt.isChecked()) { + flags += KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE; + } + if (mFlagAuthenticate.isChecked()) { + flags += KeyFlags.AUTHENTICATION; + } + + Long expiry; + if (mNoExpiryCheckBox.isChecked()) { + expiry = null; + } else { + Calendar selectedCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + //noinspection ResourceType + selectedCal.set(mExpiryDatePicker.getYear(), + mExpiryDatePicker.getMonth(), mExpiryDatePicker.getDayOfMonth()); + expiry = selectedCal.getTime().getTime() / 1000; + } + SaveKeyringParcel.SubkeyAdd newSubkey = new SaveKeyringParcel.SubkeyAdd( newKeyAlgorithmChoice.getId(), newKeySize, - KeyFlags.SIGN_DATA, //TODO - null + flags, + expiry ); mAlgorithmSelectedListener.onAlgorithmSelected(newSubkey); } @@ -261,12 +296,12 @@ public class AddSubkeyDialogFragment extends DialogFragment { final int[] elGamalSupportedLengths = {1536, 2048, 3072, 4096, 8192}; int properKeyLength = -1; switch (algorithmId) { - case Constants.choice.algorithm.rsa: + case PublicKeyAlgorithmTags.RSA_GENERAL: if (currentKeyLength > 1024 && currentKeyLength <= 8192) { properKeyLength = currentKeyLength + ((8 - (currentKeyLength % 8)) % 8); } break; - case Constants.choice.algorithm.elgamal: + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: int[] elGammalKeyDiff = new int[elGamalSupportedLengths.length]; for (int i = 0; i < elGamalSupportedLengths.length; i++) { elGammalKeyDiff[i] = Math.abs(elGamalSupportedLengths[i] - currentKeyLength); @@ -281,7 +316,7 @@ public class AddSubkeyDialogFragment extends DialogFragment { } properKeyLength = elGamalSupportedLengths[minimalIndex]; break; - case Constants.choice.algorithm.dsa: + case PublicKeyAlgorithmTags.DSA: if (currentKeyLength >= 512 && currentKeyLength <= 1024) { properKeyLength = currentKeyLength + ((64 - (currentKeyLength % 64)) % 64); } @@ -320,15 +355,15 @@ public class AddSubkeyDialogFragment extends DialogFragment { final Object selectedItem = mKeySizeSpinner.getSelectedItem(); keySizeAdapter.clear(); switch (algorithmId) { - case Constants.choice.algorithm.rsa: + case PublicKeyAlgorithmTags.RSA_GENERAL: replaceArrayAdapterContent(keySizeAdapter, R.array.rsa_key_size_spinner_values); mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_rsa)); break; - case Constants.choice.algorithm.elgamal: + case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: replaceArrayAdapterContent(keySizeAdapter, R.array.elgamal_key_size_spinner_values); mCustomKeyInfoTextView.setText(""); // ElGamal does not support custom key length break; - case Constants.choice.algorithm.dsa: + case PublicKeyAlgorithmTags.DSA: replaceArrayAdapterContent(keySizeAdapter, R.array.dsa_key_size_spinner_values); mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_dsa)); break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java index 303ab4363..aa63f9944 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java @@ -56,12 +56,12 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { * Creates new instance of this dialog fragment */ public static EditSubkeyExpiryDialogFragment newInstance(Messenger messenger, - long creationDate, long expiryDate) { + Long creationDate, Long expiryDate) { EditSubkeyExpiryDialogFragment frag = new EditSubkeyExpiryDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_MESSENGER, messenger); - args.putLong(ARG_CREATION_DATE, creationDate); - args.putLong(ARG_EXPIRY_DATE, expiryDate); + args.putSerializable(ARG_CREATION_DATE, creationDate); + args.putSerializable(ARG_EXPIRY_DATE, expiryDate); frag.setArguments(args); @@ -124,12 +124,12 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { - (mExpiryCal.getTimeInMillis() / 86400000); if (numDays > 0) { Bundle data = new Bundle(); - data.putLong(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); + data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); } } else { Bundle data = new Bundle(); - data.putLong(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); + data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); } } @@ -140,9 +140,8 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public void onClick(DialogInterface dialog, int id) { dismiss(); - // "no expiry" corresponds to a 0 Bundle data = new Bundle(); - data.putLong(MESSAGE_DATA_EXPIRY_DATE, 0); + data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, null); sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); } }); diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 831edc94c..58d3832f7 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -446,7 +446,7 @@ Change Expiry Revoke Subkey - + new Upload key to keyserver