aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2016-01-10 17:17:57 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2016-01-10 17:17:57 +0100
commit0fd5b45df913d1524aa400a644c48dc91044d9bf (patch)
tree8a1c879bffd5143ef3c79a3a0702bddd085bf50e /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java
parent9163b93a907a29dab04e1ca99b175b097d1e9d91 (diff)
downloadopen-keychain-0fd5b45df913d1524aa400a644c48dc91044d9bf.tar.gz
open-keychain-0fd5b45df913d1524aa400a644c48dc91044d9bf.tar.bz2
open-keychain-0fd5b45df913d1524aa400a644c48dc91044d9bf.zip
Use more generic 'Security Token' where possible, add sutitle to create key what tokens are supported
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java222
1 files changed, 222 insertions, 0 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java
new file mode 100644
index 000000000..48e41c7bb
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeySecurityTokenFragment.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
+ *
+ * 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 java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager.LoaderCallbacks;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import org.spongycastle.util.encoders.Hex;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
+import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
+import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
+import org.sufficientlysecure.keychain.service.PromoteKeyringParcel;
+import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment;
+import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
+
+
+public class ViewKeySecurityTokenFragment
+ extends QueueingCryptoOperationFragment<PromoteKeyringParcel, PromoteKeyResult>
+ implements LoaderCallbacks<Cursor> {
+
+ public static final String ARG_MASTER_KEY_ID = "master_key_id";
+ public static final String ARG_FINGERPRINT = "fingerprint";
+ public static final String ARG_USER_ID = "user_id";
+ public static final String ARG_CARD_AID = "aid";
+
+ private byte[][] mFingerprints;
+ private String mUserId;
+ private byte[] mCardAid;
+ private long mMasterKeyId;
+ private long[] mSubKeyIds;
+
+ private Button vButton;
+ private TextView vStatus;
+
+ public static ViewKeySecurityTokenFragment newInstance(long masterKeyId,
+ byte[] fingerprints, String userId, byte[] aid) {
+ ViewKeySecurityTokenFragment frag = new ViewKeySecurityTokenFragment();
+
+ Bundle args = new Bundle();
+ args.putLong(ARG_MASTER_KEY_ID, masterKeyId);
+ args.putByteArray(ARG_FINGERPRINT, fingerprints);
+ args.putString(ARG_USER_ID, userId);
+ args.putByteArray(ARG_CARD_AID, aid);
+ frag.setArguments(args);
+
+ return frag;
+ }
+
+ public ViewKeySecurityTokenFragment() {
+ super(null);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Bundle args = getArguments();
+ ByteBuffer buf = ByteBuffer.wrap(args.getByteArray(ARG_FINGERPRINT));
+ mFingerprints = new byte[buf.remaining()/20][];
+ for (int i = 0; i < mFingerprints.length; i++) {
+ mFingerprints[i] = new byte[20];
+ buf.get(mFingerprints[i]);
+ }
+ mUserId = args.getString(ARG_USER_ID);
+ mCardAid = args.getByteArray(ARG_CARD_AID);
+
+ mMasterKeyId = args.getLong(ARG_MASTER_KEY_ID);
+
+ getLoaderManager().initLoader(0, null, this);
+
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.view_key_security_token, null);
+
+ TextView vSerNo = (TextView) view.findViewById(R.id.token_serno);
+ TextView vUserId = (TextView) view.findViewById(R.id.token_userid);
+
+ String serno = Hex.toHexString(mCardAid, 10, 4);
+ vSerNo.setText(getString(R.string.security_token_serial_no, serno));
+
+ if (!mUserId.isEmpty()) {
+ vUserId.setText(getString(R.string.security_token_key_holder, mUserId));
+ } else {
+ vUserId.setText(getString(R.string.security_token_key_holder_not_set));
+ }
+
+ vButton = (Button) view.findViewById(R.id.button_bind);
+ vButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ promoteToSecretKey();
+ }
+ });
+
+ vStatus = (TextView) view.findViewById(R.id.token_status);
+
+ return view;
+ }
+
+ public void promoteToSecretKey() {
+ long[] subKeyIds = new long[mFingerprints.length];
+ for (int i = 0; i < subKeyIds.length; i++) {
+ subKeyIds[i] = KeyFormattingUtils.getKeyIdFromFingerprint(mFingerprints[i]);
+ }
+
+ // mMasterKeyId and mCardAid are already set
+ mSubKeyIds = subKeyIds;
+
+ cryptoOperation();
+ }
+
+ public static final String[] PROJECTION = new String[]{
+ Keys._ID,
+ Keys.KEY_ID,
+ Keys.RANK,
+ Keys.HAS_SECRET,
+ Keys.FINGERPRINT
+ };
+ // private static final int INDEX_KEY_ID = 1;
+ // private static final int INDEX_RANK = 2;
+ private static final int INDEX_HAS_SECRET = 3;
+ private static final int INDEX_FINGERPRINT = 4;
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ return new CursorLoader(getActivity(), Keys.buildKeysUri(mMasterKeyId),
+ PROJECTION, null, null, null);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ if (!data.moveToFirst()) {
+ // wut?
+ return;
+ }
+
+ boolean allBound = true;
+ boolean noneBound = true;
+
+ do {
+ SecretKeyType keyType = SecretKeyType.fromNum(data.getInt(INDEX_HAS_SECRET));
+ byte[] fingerprint = data.getBlob(INDEX_FINGERPRINT);
+ Integer index = naiveIndexOf(mFingerprints, fingerprint);
+ if (index == null) {
+ continue;
+ }
+ if (keyType == SecretKeyType.DIVERT_TO_CARD) {
+ noneBound = false;
+ } else {
+ allBound = false;
+ }
+ } while (data.moveToNext());
+
+ if (allBound) {
+ vButton.setVisibility(View.GONE);
+ vStatus.setText(R.string.security_token_status_bound);
+ } else {
+ vButton.setVisibility(View.VISIBLE);
+ vStatus.setText(noneBound
+ ? R.string.security_token_status_unbound
+ : R.string.security_token_status_partly);
+ }
+
+ }
+
+ static private Integer naiveIndexOf(byte[][] haystack, byte[] needle) {
+ for (int i = 0; i < haystack.length; i++) {
+ if (Arrays.equals(needle, haystack[i])) {
+ return i;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+
+ }
+
+ @Override
+ public PromoteKeyringParcel createOperationInput() {
+ return new PromoteKeyringParcel(mMasterKeyId, mCardAid, mSubKeyIds);
+ }
+
+ @Override
+ public void onQueuedOperationSuccess(PromoteKeyResult result) {
+ result.createNotify(getActivity()).show();
+ }
+
+}