diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org')
10 files changed, 206 insertions, 54 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 0d2d3256d..ac66bd097 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -167,7 +167,7 @@ public class OpenPgpService extends RemoteService { Intent data, RequiredInputParcel requiredInput) { switch (requiredInput.mType) { - case NFC_KEYTOCARD: + case NFC_MOVE_KEY_TO_CARD: case NFC_DECRYPT: case NFC_SIGN: { // build PendingIntent for YubiKey NFC operations diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java index 930c2ee4f..efe844145 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java @@ -12,7 +12,7 @@ import android.os.Parcelable; public class RequiredInputParcel implements Parcelable { public enum RequiredInputType { - PASSPHRASE, PASSPHRASE_SYMMETRIC, NFC_SIGN, NFC_DECRYPT, NFC_KEYTOCARD + PASSPHRASE, PASSPHRASE_SYMMETRIC, NFC_SIGN, NFC_DECRYPT, NFC_MOVE_KEY_TO_CARD } public Date mSignatureTime; @@ -226,7 +226,7 @@ public class RequiredInputParcel implements Parcelable { ByteBuffer buf = ByteBuffer.wrap(mSubkeysToExport.get(0)); // We need to pass in a subkey here... - return new RequiredInputParcel(RequiredInputType.NFC_KEYTOCARD, + return new RequiredInputParcel(RequiredInputType.NFC_MOVE_KEY_TO_CARD, inputHashes, null, null, mMasterKeyId, buf.getLong()); } @@ -241,7 +241,7 @@ public class RequiredInputParcel implements Parcelable { if (!mMasterKeyId.equals(input.mMasterKeyId)) { throw new AssertionError("Master keys must match, this is a programming error!"); } - if (input.mType != RequiredInputType.NFC_KEYTOCARD) { + if (input.mType != RequiredInputType.NFC_MOVE_KEY_TO_CARD) { throw new AssertionError("Operation types must match, this is a programming error!"); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index 68a809b69..fbe7b4066 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -17,8 +17,6 @@ package org.sufficientlysecure.keychain.ui; -import android.app.AlertDialog; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; @@ -89,13 +87,19 @@ public class CreateKeyActivity extends BaseNfcActivity { String nfcUserId = intent.getStringExtra(EXTRA_NFC_USER_ID); byte[] nfcAid = intent.getByteArrayExtra(EXTRA_NFC_AID); - Fragment frag2 = CreateKeyYubiKeyImportFragment.createInstance( - nfcFingerprints, nfcAid, nfcUserId); - loadFragment(frag2, FragAction.START); + if (containsKeys(nfcFingerprints)) { + Fragment frag = CreateKeyYubiKeyImportFragment.newInstance( + nfcFingerprints, nfcAid, nfcUserId); + loadFragment(frag, FragAction.START); - setTitle(R.string.title_import_keys); + setTitle(R.string.title_import_keys); + } else { + Fragment frag = CreateKeyYubiKeyBlankFragment.newInstance(); + loadFragment(frag, FragAction.START); + } return; } else { + // normal key creation CreateKeyStartFragment frag = CreateKeyStartFragment.newInstance(); loadFragment(frag, FragAction.START); } @@ -122,16 +126,7 @@ public class CreateKeyActivity extends BaseNfcActivity { byte[] nfcAid = nfcGetAid(); String userId = nfcGetUserId(); - // If all fingerprint bytes are 0, the card contains no keys. - boolean cardContainsKeys = false; - for (byte b : scannedFingerprints) { - if (b != 0) { - cardContainsKeys = true; - break; - } - } - - if (cardContainsKeys) { + if (containsKeys(scannedFingerprints)) { try { long masterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(scannedFingerprints); CachedPublicKeyRing ring = new ProviderHelper(this).getCachedPublicKeyRing(masterKeyId); @@ -146,25 +141,29 @@ public class CreateKeyActivity extends BaseNfcActivity { finish(); } catch (PgpKeyNotFoundException e) { - Fragment frag = CreateKeyYubiKeyImportFragment.createInstance( + Fragment frag = CreateKeyYubiKeyImportFragment.newInstance( scannedFingerprints, nfcAid, userId); loadFragment(frag, FragAction.TO_RIGHT); } } else { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.first_time_blank_smartcard_title) - .setMessage(R.string.first_time_blank_smartcard_message) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int button) { - CreateKeyActivity.this.mUseSmartCardSettings = true; - } - }) - .setNegativeButton(android.R.string.no, null).show(); + Fragment frag = CreateKeyYubiKeyBlankFragment.newInstance(); + loadFragment(frag, FragAction.TO_RIGHT); } } + private boolean containsKeys(byte[] scannedFingerprints) { + // If all fingerprint bytes are 0, the card contains no keys. + boolean cardContainsKeys = false; + for (byte b : scannedFingerprints) { + if (b != 0) { + cardContainsKeys = true; + break; + } + } + return cardContainsKeys; + } + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -182,7 +181,7 @@ public class CreateKeyActivity extends BaseNfcActivity { setContentView(R.layout.create_key_activity); } - public static enum FragAction { + public enum FragAction { START, TO_RIGHT, TO_LEFT 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 ebbd01afe..09ab1e663 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -20,11 +20,11 @@ package org.sufficientlysecure.keychain.ui; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; +import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Message; import android.os.Messenger; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -37,19 +37,24 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; +import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainService; -import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler; +import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; import java.util.Iterator; -public class CreateKeyFinalFragment extends Fragment { +public class CreateKeyFinalFragment extends CryptoOperationFragment<SaveKeyringParcel, OperationResult> { public static final int REQUEST_EDIT_KEY = 0x00008007; @@ -129,6 +134,11 @@ public class CreateKeyFinalFragment extends Fragment { } }); + // If this is a debug build, don't upload by default + if (Constants.DEBUG) { + mUploadCheckbox.setChecked(false); + } + return view; } @@ -164,6 +174,7 @@ public class CreateKeyFinalFragment extends Fragment { mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, 2048, null, KeyFlags.AUTHENTICATION, 0L)); mEditText.setText(R.string.create_key_custom); + mEditButton.setEnabled(false); } else { mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, 4096, null, KeyFlags.CERTIFY_OTHER, 0L)); @@ -192,8 +203,9 @@ public class CreateKeyFinalFragment extends Fragment { } } - private void createKey() { + final CreateKeyActivity createKeyActivity = (CreateKeyActivity) getActivity(); + Intent intent = new Intent(getActivity(), KeychainService.class); intent.setAction(KeychainService.ACTION_EDIT_KEYRING); @@ -216,25 +228,29 @@ public class CreateKeyFinalFragment extends Fragment { return; } + if (createKeyActivity.mUseSmartCardSettings) { + // save key id in between + mSaveKeyringParcel.mMasterKeyId = result.mMasterKeyId; + cryptoOperation(new CryptoInputParcel()); + return; + } + if (result.mMasterKeyId != null && mUploadCheckbox.isChecked()) { // result will be displayed after upload uploadKey(result); - } else { - Intent data = new Intent(); - data.putExtra(OperationResult.EXTRA_RESULT, result); - getActivity().setResult(Activity.RESULT_OK, data); - getActivity().finish(); + return; } + + Intent data = new Intent(); + data.putExtra(OperationResult.EXTRA_RESULT, result); + getActivity().setResult(Activity.RESULT_OK, data); + getActivity().finish(); } } }; - // fill values for this action Bundle data = new Bundle(); - - // get selected key entries data.putParcelable(KeychainService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel); - intent.putExtra(KeychainService.EXTRA_DATA, data); // Create a new Messenger for the communication back @@ -247,6 +263,55 @@ public class CreateKeyFinalFragment extends Fragment { getActivity().startService(intent); } + // currently only used for moveToCard + @Override + protected SaveKeyringParcel createOperationInput() { + CachedPublicKeyRing key = (new ProviderHelper(getActivity())) + .getCachedPublicKeyRing(mSaveKeyringParcel.mMasterKeyId); + + // overwrite mSaveKeyringParcel! + try { + mSaveKeyringParcel = new SaveKeyringParcel(key.getMasterKeyId(), key.getFingerprint()); + } catch (PgpKeyNotFoundException e) { + Log.e(Constants.TAG, "Key that should be moved to YubiKey not found in database!"); + return null; + } + + Cursor cursor = getActivity().getContentResolver().query( + KeychainContract.Keys.buildKeysUri(mSaveKeyringParcel.mMasterKeyId), + new String[]{KeychainContract.Keys.KEY_ID,}, null, null, null + ); + try { + while (cursor != null && cursor.moveToNext()) { + long subkeyId = cursor.getLong(0); + mSaveKeyringParcel.getOrCreateSubkeyChange(subkeyId).mMoveKeyToCard = true; + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return mSaveKeyringParcel; + } + + // currently only used for moveToCard + @Override + protected void onCryptoOperationSuccess(OperationResult result) { + EditKeyResult editResult = (EditKeyResult) result; + + if (editResult.mMasterKeyId != null && mUploadCheckbox.isChecked()) { + // result will be displayed after upload + uploadKey(editResult); + return; + } + + Intent data = new Intent(); + data.putExtra(OperationResult.EXTRA_RESULT, result); + getActivity().setResult(Activity.RESULT_OK, data); + getActivity().finish(); + } + // TODO move into EditKeyOperation private void uploadKey(final EditKeyResult saveKeyResult) { // Send all information needed to service to upload key in other thread @@ -259,7 +324,6 @@ public class CreateKeyFinalFragment extends Fragment { saveKeyResult.mMasterKeyId); intent.setData(blobUri); - // fill values for this action Bundle data = new Bundle(); // upload to favorite keyserver @@ -300,7 +364,6 @@ public class CreateKeyFinalFragment extends Fragment { // start service with intent getActivity().startService(intent); - } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyBlankFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyBlankFragment.java new file mode 100644 index 000000000..6df340636 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyBlankFragment.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; + +public class CreateKeyYubiKeyBlankFragment extends Fragment { + + CreateKeyActivity mCreateKeyActivity; + View mBackButton; + View mNextButton; + + /** + * Creates new instance of this fragment + */ + public static CreateKeyYubiKeyBlankFragment newInstance() { + CreateKeyYubiKeyBlankFragment frag = new CreateKeyYubiKeyBlankFragment(); + + Bundle args = new Bundle(); + + frag.setArguments(args); + + return frag; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.create_yubi_key_blank_fragment, container, false); + + mBackButton = view.findViewById(R.id.create_key_back_button); + mNextButton = view.findViewById(R.id.create_key_next_button); + + mBackButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getFragmentManager().getBackStackEntryCount() == 0) { + getActivity().setResult(Activity.RESULT_CANCELED); + getActivity().finish(); + } else { + mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); + } + } + }); + mNextButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + nextClicked(); + } + }); + + return view; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mCreateKeyActivity = (CreateKeyActivity) getActivity(); + } + + private void nextClicked() { + mCreateKeyActivity.mUseSmartCardSettings = true; + + CreateKeyNameFragment frag = CreateKeyNameFragment.newInstance(); + mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java index 2ab8c5967..a575dc6b9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyImportFragment.java @@ -64,7 +64,7 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe private TextView vSerNo; private TextView vUserId; - public static Fragment createInstance(byte[] scannedFingerprints, byte[] nfcAid, String userId) { + public static Fragment newInstance(byte[] scannedFingerprints, byte[] nfcAid, String userId) { CreateKeyYubiKeyImportFragment frag = new CreateKeyYubiKeyImportFragment(); @@ -95,7 +95,7 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.create_yubikey_import_fragment, container, false); + View view = inflater.inflate(R.layout.create_yubi_key_import_fragment, container, false); vSerNo = (TextView) view.findViewById(R.id.yubikey_serno); vUserId = (TextView) view.findViewById(R.id.yubikey_userid); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java index 0b8586c0a..0e2dd2531 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyYubiKeyWaitFragment.java @@ -35,7 +35,7 @@ public class CreateKeyYubiKeyWaitFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.create_yubikey_wait_fragment, container, false); + View view = inflater.inflate(R.layout.create_yubi_key_wait_fragment, container, false); mBackButton = view.findViewById(R.id.create_key_back_button); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java index c5fc9abe0..addfb6a23 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java @@ -63,7 +63,7 @@ public class NfcOperationActivity extends BaseNfcActivity { mServiceIntent = data.getParcelable(EXTRA_SERVICE_INTENT); // obtain passphrase for this subkey - if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_KEYTOCARD) { + if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_MOVE_KEY_TO_CARD) { obtainYubiKeyPin(mRequiredInput); } } @@ -96,7 +96,7 @@ public class NfcOperationActivity extends BaseNfcActivity { } break; } - case NFC_KEYTOCARD: { + case NFC_MOVE_KEY_TO_CARD: { ProviderHelper providerHelper = new ProviderHelper(this); CanonicalizedSecretKeyRing secretKeyRing; try { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java index a28a5ea59..cb250d28c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java @@ -269,7 +269,7 @@ public abstract class BaseNfcActivity extends BaseActivity { * This method is called by onNewIntent above upon discovery of an NFC tag. * It handles initialization and login to the application, subsequently * calls either nfcCalculateSignature() or nfcDecryptSessionKey(), then - * finishes the activity with an appropiate result. + * finishes the activity with an appropriate result. * * On general communication, see also * http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a.aspx diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java index 764602735..245abc21f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/CryptoOperationFragment.java @@ -52,7 +52,7 @@ public abstract class CryptoOperationFragment <T extends Parcelable, S extends O private void initiateInputActivity(RequiredInputParcel requiredInput) { switch (requiredInput.mType) { - case NFC_KEYTOCARD: + case NFC_MOVE_KEY_TO_CARD: case NFC_DECRYPT: case NFC_SIGN: { Intent intent = new Intent(getActivity(), NfcOperationActivity.class); |