aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubikeyFragment.java113
-rw-r--r--OpenKeychain/src/main/res/layout/view_key_yubikey.xml11
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml4
3 files changed, 114 insertions, 14 deletions
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 7df791fbf..f60b6f299 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubikeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyYubikeyFragment.java
@@ -1,35 +1,48 @@
package org.sufficientlysecure.keychain.ui;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
import android.content.Intent;
+import android.database.Cursor;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.Fragment;
+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.DecryptVerifyResult;
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.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-public class ViewKeyYubikeyFragment extends Fragment {
-
+public class ViewKeyYubikeyFragment extends Fragment
+ implements LoaderCallbacks<Cursor> {
public static final String ARG_FINGERPRINT = "fingerprint";
public static final String ARG_USER_ID = "user_id";
public static final String ARG_AID = "aid";
- private byte[] mFingerprints;
+ private byte[][] mFingerprints;
private String mUserId;
private byte[] mAid;
+ private long mMasterKeyId;
+ private Button vButton;
+ private TextView vStatus;
public static ViewKeyYubikeyFragment newInstance(byte[] fingerprints, String userId, byte[] aid) {
@@ -50,10 +63,19 @@ public class ViewKeyYubikeyFragment extends Fragment {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
- mFingerprints = args.getByteArray(ARG_FINGERPRINT);
+ ByteBuffer buf = ByteBuffer.wrap(args.getByteArray(ARG_FINGERPRINT));
+ mFingerprints = new byte[buf.remaining()/40][];
+ for (int i = 0; i < mFingerprints.length; i++) {
+ mFingerprints[i] = new byte[20];
+ buf.get(mFingerprints[i]);
+ }
mUserId = args.getString(ARG_USER_ID);
mAid = args.getByteArray(ARG_AID);
+ mMasterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mFingerprints[0]);
+
+ getLoaderManager().initLoader(0, null, this);
+
}
@Override
@@ -64,21 +86,23 @@ public class ViewKeyYubikeyFragment extends Fragment {
TextView vUserId = (TextView) view.findViewById(R.id.yubikey_userid);
String serno = Hex.toHexString(mAid, 10, 4);
- vSerNo.setText("Serial N° " + serno);
+ vSerNo.setText(getString(R.string.yubikey_serno, serno));
if (!mUserId.isEmpty()) {
- vUserId.setText("Key holder: " + mUserId);
+ vUserId.setText(getString(R.string.yubikey_key_holder, mUserId));
} else {
- vUserId.setText("Key holder: " + "<unset>");
+ vUserId.setText(getString(R.string.yubikey_key_holder_unset));
}
- view.findViewById(R.id.button_import).setOnClickListener(new OnClickListener() {
+ 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.yubikey_status);
return view;
}
@@ -111,10 +135,8 @@ public class ViewKeyYubikeyFragment extends Fragment {
intent.setAction(KeychainIntentService.ACTION_PROMOTE_KEYRING);
- long masterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(mFingerprints);
-
Bundle data = new Bundle();
- data.putLong(KeychainIntentService.PROMOTE_MASTER_KEY_ID, masterKeyId);
+ data.putLong(KeychainIntentService.PROMOTE_MASTER_KEY_ID, mMasterKeyId);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Create a new Messenger for the communication back
@@ -126,4 +148,73 @@ public class ViewKeyYubikeyFragment extends Fragment {
}
+ 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("Key matches, fully bound");
+ } else {
+ vButton.setVisibility(View.VISIBLE);
+ if (noneBound) {
+ vStatus.setText("Key matches, can be bound");
+ } else {
+ vStatus.setText("Key matches, partly bound");
+ }
+ }
+
+ }
+
+ public 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) {
+
+ }
}
diff --git a/OpenKeychain/src/main/res/layout/view_key_yubikey.xml b/OpenKeychain/src/main/res/layout/view_key_yubikey.xml
index 7da1fc5c4..83272ef4e 100644
--- a/OpenKeychain/src/main/res/layout/view_key_yubikey.xml
+++ b/OpenKeychain/src/main/res/layout/view_key_yubikey.xml
@@ -21,7 +21,8 @@
card_view:cardBackgroundColor="@android:color/white"
card_view:cardElevation="2dp"
card_view:cardUseCompatPadding="true"
- card_view:cardCornerRadius="4dp">
+ card_view:cardCornerRadius="4dp"
+ android:animateLayoutChanges="true">
<LinearLayout
android:layout_width="match_parent"
@@ -37,6 +38,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
android:orientation="horizontal">
<ImageView
@@ -69,6 +72,7 @@
/>
<TextView
+ android:id="@+id/yubikey_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
@@ -80,13 +84,14 @@
</LinearLayout>
<Button
- android:id="@+id/button_import"
+ android:id="@+id/button_bind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
- android:text="Import"
+ android:text="@string/button_bind_key"
android:textColor="@color/link_text_material_light"
style="?android:attr/borderlessButtonStyle"
+ android:visibility="gone"
/>
</LinearLayout>
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index bcee267fd..f7a9a671e 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -1269,5 +1269,9 @@
<string name="unlocked">Unlocked</string>
<string name="nfc_settings">Settings</string>
<string name="snack_yubikey_view">View</string>
+ <string name="button_bind_key">Bind Key</string>
+ <string name="yubikey_serno">"Serial No: %s"</string>
+ <string name="yubikey_key_holder">"Key holder: "</string>
+ <string name="yubikey_key_holder_unset">"Key holder: &lt;unset&gt;"</string>
</resources>